def griesmer_upper_bound(n,q,d,algorithm=None): r""" Returns the Griesmer upper bound for number of elements in the largest code of minimum distance d in `\GF{q}^n`. Wraps GAP's UpperBoundGriesmer. EXAMPLES:: sage: codes.bounds.griesmer_upper_bound(10,2,3) 128 sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 128 """ if algorithm=="gap": gap.load_package("guava") ans=gap.eval("UpperBoundGriesmer(%s,%s,%s)"%(n,d,q)) return QQ(ans) else: den = 1 s = 0 k = 0 add = 0 while s <= n: if not(add == 1): if d%den==0: add = int(d/den) else: add = int(d/den)+1 s = s + add den = den * q k = k + 1 return q**(k-1)
def griesmer_upper_bound(n, q, d, algorithm=None): r""" Returns the Griesmer upper bound for number of elements in the largest code of minimum distance d in `\GF{q}^n`. Wraps GAP's UpperBoundGriesmer. EXAMPLES:: sage: codes.bounds.griesmer_upper_bound(10,2,3) 128 sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 128 """ if algorithm == "gap": gap.load_package("guava") ans = gap.eval("UpperBoundGriesmer(%s,%s,%s)" % (n, d, q)) return QQ(ans) else: den = 1 s = 0 k = 0 add = 0 while s <= n: if not (add == 1): if d % den == 0: add = int(d / den) else: add = int(d / den) + 1 s = s + add den = den * q k = k + 1 return q**(k - 1)
def elias_upper_bound(n,q,d,algorithm=None): r""" Returns the Elias upper bound. Returns the Elias upper bound for number of elements in the largest code of minimum distance `d` in `\GF{q}^n`, cf. [HP2003]_. If the method is "gap", it wraps GAP's ``UpperBoundElias``. EXAMPLES:: sage: codes.bounds.elias_upper_bound(10,2,3) 232 sage: codes.bounds.elias_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 232 """ _check_n_q_d(n, q, d, field_based=False) r = 1-1/q if algorithm=="gap": gap.load_package("guava") ans=gap.eval("UpperBoundElias(%s,%s,%s)"%(n,d,q)) return QQ(ans) else: def ff(n,d,w,q): return r*n*d*q**n/((w**2-2*r*n*w+r*n*d)*volume_hamming(n,q,w)); def get_list(n,d,q): I = [] for i in range(1,int(r*n)+1): if i**2-2*r*n*i+r*n*d>0: I.append(i) return I I = get_list(n,d,q) bnd = min([ff(n,d,w,q) for w in I]) return int(bnd)
def plotkin_upper_bound(n,q,d, algorithm=None): r""" Returns Plotkin upper bound for number of elements in the largest code of minimum distance d in `\GF{q}^n`. The algorithm="gap" option wraps Guava's UpperBoundPlotkin. EXAMPLES:: sage: codes.bounds.plotkin_upper_bound(10,2,3) 192 sage: codes.bounds.plotkin_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 192 """ if algorithm=="gap": gap.load_package("guava") ans=gap.eval("UpperBoundPlotkin(%s,%s,%s)"%(n,d,q)) return QQ(ans) else: t = 1 - 1/q if (q==2) and (n == 2*d) and (d%2 == 0): return 4*d elif (q==2) and (n == 2*d + 1) and (d%2 == 1): return 4*d + 4 elif d > t*n: return int(d/( d - t*n)) elif d < t*n + 1: fact = (d-1) / t if RR(fact)==RR(int(fact)): fact = int(fact) + 1 return int(d/( d - t * fact)) * q**(n - fact)
def plotkin_upper_bound(n, q, d, algorithm=None): r""" Returns Plotkin upper bound for number of elements in the largest code of minimum distance d in `\GF{q}^n`. The algorithm="gap" option wraps Guava's UpperBoundPlotkin. EXAMPLES:: sage: codes.bounds.plotkin_upper_bound(10,2,3) 192 sage: codes.bounds.plotkin_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 192 """ if algorithm == "gap": gap.load_package("guava") ans = gap.eval("UpperBoundPlotkin(%s,%s,%s)" % (n, d, q)) return QQ(ans) else: t = 1 - 1 / q if (q == 2) and (n == 2 * d) and (d % 2 == 0): return 4 * d elif (q == 2) and (n == 2 * d + 1) and (d % 2 == 1): return 4 * d + 4 elif d > t * n: return int(d / (d - t * n)) elif d < t * n + 1: fact = (d - 1) / t if RR(fact) == RR(int(fact)): fact = int(fact) + 1 return int(d / (d - t * fact)) * q**(n - fact)
def elias_upper_bound(n, q, d, algorithm=None): r""" Returns the Elias upper bound for number of elements in the largest code of minimum distance d in `\GF{q}^n`. Wraps GAP's UpperBoundElias. EXAMPLES:: sage: codes.bounds.elias_upper_bound(10,2,3) 232 sage: codes.bounds.elias_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 232 """ r = 1 - 1 / q if algorithm == "gap": gap.load_package("guava") ans = gap.eval("UpperBoundElias(%s,%s,%s)" % (n, d, q)) return QQ(ans) else: def ff(n, d, w, q): return r * n * d * q**n / ( (w**2 - 2 * r * n * w + r * n * d) * volume_hamming(n, q, w)) def get_list(n, d, q): I = [] for i in range(1, int(r * n) + 1): if i**2 - 2 * r * n * i + r * n * d > 0: I.append(i) return I I = get_list(n, d, q) bnd = min([ff(n, d, w, q) for w in I]) return int(bnd)
def griesmer_upper_bound(n,q,d,algorithm=None): r""" Returns the Griesmer upper bound. Returns the Griesmer upper bound for the number of elements in a largest linear code of minimum distance `d` in `\GF{q}^n`, cf. [HP2003]_. If the method is "gap", it wraps GAP's ``UpperBoundGriesmer``. The bound states: .. MATH:: `n\geq \sum_{i=0}^{k-1} \lceil d/q^i \rceil.` EXAMPLES: The bound is reached for the ternary Golay codes:: sage: codes.bounds.griesmer_upper_bound(12,3,6) 729 sage: codes.bounds.griesmer_upper_bound(11,3,5) 729 :: sage: codes.bounds.griesmer_upper_bound(10,2,3) 128 sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 128 TESTS:: sage: codes.bounds.griesmer_upper_bound(11,3,6) 243 sage: codes.bounds.griesmer_upper_bound(11,3,6) 243 """ _check_n_q_d(n, q, d) if algorithm=="gap": gap.load_package("guava") ans=gap.eval("UpperBoundGriesmer(%s,%s,%s)"%(n,d,q)) return QQ(ans) else: #To compute the bound, we keep summing up the terms on the RHS #until we start violating the inequality. from sage.functions.other import ceil den = 1 s = 0 k = 0 while s <= n: s += ceil(d/den) den *= q k = k + 1 return q**(k-1)
def BinaryReedMullerCode(r, k): r""" The binary 'Reed-Muller code' with dimension k and order r is a code with length `2^k` and minimum distance `2^k-r` (see for example, section 1.10 in [HP]_). By definition, the `r^{th}` order binary Reed-Muller code of length `n=2^m`, for `0 \leq r \leq m`, is the set of all vectors `(f(p)\ |\ p \in GF(2)^m)`, where `f` is a multivariate polynomial of degree at most `r` in `m` variables. INPUT: - ``r, k`` -- positive integers with `2^k>r`. OUTPUT: Returns the binary 'Reed-Muller code' with dimension `k` and order `r`. EXAMPLE:: sage: C = codes.BinaryReedMullerCode(2,4); C # optional - gap_packages (Guava package) Linear code of length 16, dimension 11 over Finite Field of size 2 sage: C.minimum_distance() # optional - gap_packages (Guava package) 4 sage: C.generator_matrix() # optional - gap_packages (Guava package) [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] [0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1] [0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1] [0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1] [0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1] [0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1] [0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1] [0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1] [0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1] [0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1] [0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1] AUTHOR: David Joyner (11-2005) """ F = GF(2) gap.load_package("guava") gap.eval("C:=ReedMullerCode(" + str(r) + ", " + str(k) + ")") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[ gfq_gap_to_sage(gap.eval("G[" + str(i) + "][" + str(j) + "]"), F) for j in range(1, n + 1) ] for i in range(1, k + 1)] MS = MatrixSpace(F, k, n) return LinearCode(MS(G))
def codesize_upper_bound(n,d,q,algorithm=None): r""" This computes the minimum value of the upper bound using the methods of Singleton, Hamming, Plotkin, and Elias. If algorithm="gap" then this returns the best known upper bound `A(n,d)=A_q(n,d)` for the size of a code of length n, minimum distance d over a field of size q. The function first checks for trivial cases (like d=1 or n=d), and if the value is in the built-in table. Then it calculates the minimum value of the upper bound using the algorithms of Singleton, Hamming, Johnson, Plotkin and Elias. If the code is binary, `A(n, 2\ell-1) = A(n+1,2\ell)`, so the function takes the minimum of the values obtained from all algorithms for the parameters `(n, 2\ell-1)` and `(n+1, 2\ell)`. This wraps GUAVA's (i.e. GAP's package Guava) UpperBound( n, d, q ). If algorithm="LP" then this returns the Delsarte (a.k.a. Linear Programming) upper bound. EXAMPLES:: sage: codes.bounds.codesize_upper_bound(10,3,2) 93 sage: codes.bounds.codesize_upper_bound(24,8,2,algorithm="LP") 4096 sage: codes.bounds.codesize_upper_bound(10,3,2,algorithm="gap") # optional - gap_packages (Guava package) 85 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm=None) 123361 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="gap") # optional - gap_packages (Guava package) 123361 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="LP") 109226 """ if algorithm=="gap": gap.load_package('guava') return int(gap.eval("UpperBound(%s,%s,%s)"%( n, d, q ))) if algorithm=="LP": return int(delsarte_bound_hamming_space(n,d,q)) else: eub = elias_upper_bound(n,q,d) gub = griesmer_upper_bound(n,q,d) hub = hamming_upper_bound(n,q,d) pub = plotkin_upper_bound(n,q,d) sub = singleton_upper_bound(n,q,d) return min([eub,gub,hub,pub,sub])
def BinaryReedMullerCode(r,k): r""" The binary 'Reed-Muller code' with dimension k and order r is a code with length `2^k` and minimum distance `2^k-r` (see for example, section 1.10 in [HP]_). By definition, the `r^{th}` order binary Reed-Muller code of length `n=2^m`, for `0 \leq r \leq m`, is the set of all vectors `(f(p)\ |\ p \\in GF(2)^m)`, where `f` is a multivariate polynomial of degree at most `r` in `m` variables. INPUT: - ``r, k`` -- positive integers with `2^k>r`. OUTPUT: Returns the binary 'Reed-Muller code' with dimension `k` and order `r`. EXAMPLE:: sage: C = codes.BinaryReedMullerCode(2,4); C # optional - gap_packages (Guava package) Linear code of length 16, dimension 11 over Finite Field of size 2 sage: C.minimum_distance() # optional - gap_packages (Guava package) 4 sage: C.gen_mat() # optional - gap_packages (Guava package) [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] [0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1] [0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1] [0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1] [0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1] [0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1] [0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1] [0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1] [0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1] [0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1] [0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1] AUTHOR: David Joyner (11-2005) """ F = GF(2) gap.load_package("guava") gap.eval("C:=ReedMullerCode("+str(r)+", "+str(k)+")") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[gfq_gap_to_sage(gap.eval("G["+str(i)+"]["+str(j)+"]"),F) for j in range(1,n+1)] for i in range(1,k+1)] MS = MatrixSpace(F,k,n) return LinearCode(MS(G))
def codesize_upper_bound(n, d, q, algorithm=None): r""" This computes the minimum value of the upper bound using the methods of Singleton, Hamming, Plotkin, and Elias. If algorithm="gap" then this returns the best known upper bound `A(n,d)=A_q(n,d)` for the size of a code of length n, minimum distance d over a field of size q. The function first checks for trivial cases (like d=1 or n=d), and if the value is in the built-in table. Then it calculates the minimum value of the upper bound using the algorithms of Singleton, Hamming, Johnson, Plotkin and Elias. If the code is binary, `A(n, 2\ell-1) = A(n+1,2\ell)`, so the function takes the minimum of the values obtained from all algorithms for the parameters `(n, 2\ell-1)` and `(n+1, 2\ell)`. This wraps GUAVA's (i.e. GAP's package Guava) UpperBound( n, d, q ). If algorithm="LP" then this returns the Delsarte (a.k.a. Linear Programming) upper bound. EXAMPLES:: sage: codes.bounds.codesize_upper_bound(10,3,2) 93 sage: codes.bounds.codesize_upper_bound(24,8,2,algorithm="LP") 4096 sage: codes.bounds.codesize_upper_bound(10,3,2,algorithm="gap") # optional - gap_packages (Guava package) 85 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm=None) 123361 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="gap") # optional - gap_packages (Guava package) 123361 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="LP") 109226 """ if algorithm == "gap": gap.load_package('guava') return int(gap.eval("UpperBound(%s,%s,%s)" % (n, d, q))) if algorithm == "LP": return int(delsarte_bound_hamming_space(n, d, q)) else: eub = elias_upper_bound(n, q, d) gub = griesmer_upper_bound(n, q, d) hub = hamming_upper_bound(n, q, d) pub = plotkin_upper_bound(n, q, d) sub = singleton_upper_bound(n, q, d) return min([eub, gub, hub, pub, sub])
def QuasiQuadraticResidueCode(p): r""" A (binary) quasi-quadratic residue code (or QQR code), as defined by Proposition 2.2 in [BM]_, has a generator matrix in the block form `G=(Q,N)`. Here `Q` is a `p \times p` circulant matrix whose top row is `(0,x_1,...,x_{p-1})`, where `x_i=1` if and only if `i` is a quadratic residue `\mod p`, and `N` is a `p \times p` circulant matrix whose top row is `(0,y_1,...,y_{p-1})`, where `x_i+y_i=1` for all `i`. INPUT: - ``p`` -- a prime `>2`. OUTPUT: Returns a QQR code of length `2p`. EXAMPLES:: sage: C = codes.QuasiQuadraticResidueCode(11); C # optional - gap_packages (Guava package) Linear code of length 22, dimension 11 over Finite Field of size 2 REFERENCES: .. [BM] Bazzi and Mitter, {\it Some constructions of codes from group actions}, (preprint March 2003, available on Mitter's MIT website). .. [Jresidue] D. Joyner, {\it On quadratic residue codes and hyperelliptic curves}, (preprint 2006) These are self-orthogonal in general and self-dual when $p \\equiv 3 \\pmod 4$. AUTHOR: David Joyner (11-2005) """ F = GF(2) gap.load_package("guava") gap.eval("C:=QQRCode(" + str(p) + ")") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[ gfq_gap_to_sage(gap.eval("G[%s][%s]" % (i, j)), F) for j in range(1, n + 1) ] for i in range(1, k + 1)] MS = MatrixSpace(F, k, n) return LinearCode(MS(G))
def QuasiQuadraticResidueCode(p): r""" A (binary) quasi-quadratic residue code (or QQR code), as defined by Proposition 2.2 in [BM2003]_, has a generator matrix in the block form `G=(Q,N)`. Here `Q` is a `p \times p` circulant matrix whose top row is `(0,x_1,...,x_{p-1})`, where `x_i=1` if and only if `i` is a quadratic residue `\mod p`, and `N` is a `p \times p` circulant matrix whose top row is `(0,y_1,...,y_{p-1})`, where `x_i+y_i=1` for all `i`. INPUT: - ``p`` -- a prime `>2`. OUTPUT: Returns a QQR code of length `2p`. EXAMPLES:: sage: C = codes.QuasiQuadraticResidueCode(11); C # optional - gap_packages (Guava package) [22, 11] linear code over GF(2) REFERENCES: - [BM2003]_ - [Joy2006]_ These are self-orthogonal in general and self-dual when $p \\equiv 3 \\pmod 4$. AUTHOR: David Joyner (11-2005) """ F = GF(2) gap.load_package("guava") gap.eval("C:=QQRCode(" + str(p) + ")") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[ gfq_gap_to_sage(gap.eval("G[%s][%s]" % (i, j)), F) for j in range(1, n + 1) ] for i in range(1, k + 1)] MS = MatrixSpace(F, k, n) return LinearCode(MS(G))
def QuasiQuadraticResidueCode(p): r""" A (binary) quasi-quadratic residue code (or QQR code), as defined by Proposition 2.2 in [BM]_, has a generator matrix in the block form `G=(Q,N)`. Here `Q` is a `p \times p` circulant matrix whose top row is `(0,x_1,...,x_{p-1})`, where `x_i=1` if and only if `i` is a quadratic residue `\mod p`, and `N` is a `p \times p` circulant matrix whose top row is `(0,y_1,...,y_{p-1})`, where `x_i+y_i=1` for all `i`. INPUT: - ``p`` -- a prime `>2`. OUTPUT: Returns a QQR code of length `2p`. EXAMPLES:: sage: C = codes.QuasiQuadraticResidueCode(11); C # optional - gap_packages (Guava package) Linear code of length 22, dimension 11 over Finite Field of size 2 REFERENCES: .. [BM] Bazzi and Mitter, {\it Some constructions of codes from group actions}, (preprint March 2003, available on Mitter's MIT website). .. [Jresidue] \D. Joyner, {\it On quadratic residue codes and hyperelliptic curves}, (preprint 2006) These are self-orthogonal in general and self-dual when $p \\equiv 3 \\pmod 4$. AUTHOR: David Joyner (11-2005) """ F = GF(2) gap.load_package("guava") gap.eval("C:=QQRCode(" + str(p) + ")") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[gfq_gap_to_sage(gap.eval("G[%s][%s]" % (i, j)), F) for j in range(1, n + 1)] for i in range(1, k + 1)] MS = MatrixSpace(F, k, n) return LinearCode(MS(G))
def RandomLinearCodeGuava(n, k, F): r""" The method used is to first construct a `k \times n` matrix of the block form `(I,A)`, where `I` is a `k \times k` identity matrix and `A` is a `k \times (n-k)` matrix constructed using random elements of `F`. Then the columns are permuted using a randomly selected element of the symmetric group `S_n`. INPUT: - ``n,k`` -- integers with `n>k>1`. OUTPUT: Returns a "random" linear code with length `n`, dimension `k` over field `F`. EXAMPLES:: sage: C = codes.RandomLinearCodeGuava(30,15,GF(2)); C # optional - gap_packages (Guava package) [30, 15] linear code over GF(2) sage: C = codes.RandomLinearCodeGuava(10,5,GF(4,'a')); C # optional - gap_packages (Guava package) [10, 5] linear code over GF(4) AUTHOR: David Joyner (11-2005) """ current_randstate().set_seed_gap() q = F.order() if not is_package_installed('gap_packages'): raise PackageNotFoundError('gap_packages') gap.load_package("guava") gap.eval("C:=RandomLinearCode(" + str(n) + "," + str(k) + ", GF(" + str(q) + "))") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[ gfq_gap_to_sage(gap.eval("G[%s][%s]" % (i, j)), F) for j in range(1, n + 1) ] for i in range(1, k + 1)] MS = MatrixSpace(F, k, n) return LinearCode(MS(G))
def best_linear_code_in_guava(n, k, F): r""" Returns the linear code of length ``n``, dimension ``k`` over field ``F`` with the maximal minimum distance which is known to the GAP package GUAVA. The function uses the tables described in ``bounds_on_minimum_distance_in_guava`` to construct this code. This requires the optional GAP package GUAVA. INPUT: - ``n`` -- the length of the code to look up - ``k`` -- the dimension of the code to look up - ``F`` -- the base field of the code to look up OUTPUT: - A :class:`LinearCode` which is a best linear code of the given parameters known to GUAVA. EXAMPLES:: sage: codes.databases.best_linear_code_in_guava(10,5,GF(2)) # long time; optional - gap_packages (Guava package) [10, 5] linear code over GF(2) sage: gap.eval("C:=BestKnownLinearCode(10,5,GF(2))") # long time; optional - gap_packages (Guava package) 'a linear [10,5,4]2..4 shortened code' This means that the best possible binary linear code of length 10 and dimension 5 is a code with minimum distance 4 and covering radius s somewhere between 2 and 4. Use ``bounds_on_minimum_distance_in_guava(10,5,GF(2))`` for further details. """ if not is_package_installed('gap_packages'): raise PackageNotFoundError('gap_packages') gap.load_package("guava") q = F.order() C = gap("BestKnownLinearCode(%s,%s,GF(%s))"%(n,k,q)) from .linear_code import LinearCode return LinearCode(C.GeneratorMat()._matrix_(F))
def best_linear_code_in_guava(n, k, F): r""" Returns the linear code of length ``n``, dimension ``k`` over field ``F`` with the maximal minimum distance which is known to the GAP package GUAVA. The function uses the tables described in ``bounds_on_minimum_distance_in_guava`` to construct this code. This requires the optional GAP package GUAVA. INPUT: - ``n`` -- the length of the code to look up - ``k`` -- the dimension of the code to look up - ``F`` -- the base field of the code to look up OUTPUT: - A :class:`LinearCode` which is a best linear code of the given parameters known to GUAVA. EXAMPLES:: sage: codes.databases.best_linear_code_in_guava(10,5,GF(2)) # long time; optional - gap_packages (Guava package) [10, 5] linear code over GF(2) sage: gap.eval("C:=BestKnownLinearCode(10,5,GF(2))") # long time; optional - gap_packages (Guava package) 'a linear [10,5,4]2..4 shortened code' This means that the best possible binary linear code of length 10 and dimension 5 is a code with minimum distance 4 and covering radius s somewhere between 2 and 4. Use ``bounds_on_minimum_distance_in_guava(10,5,GF(2))`` for further details. """ if not is_package_installed('gap_packages'): raise PackageNotFoundError('gap_packages') gap.load_package("guava") q = F.order() C = gap("BestKnownLinearCode(%s,%s,GF(%s))" % (n, k, q)) from .linear_code import LinearCode return LinearCode(C.GeneratorMat()._matrix_(F))
def QuasiQuadraticResidueCode(p): r""" A (binary) quasi-quadratic residue code (or QQR code). Follows the definition of Proposition 2.2 in [BM]. The code has a generator matrix in the block form `G=(Q,N)`. Here `Q` is a `p \times p` circulant matrix whose top row is `(0,x_1,...,x_{p-1})`, where `x_i=1` if and only if `i` is a quadratic residue `\mod p`, and `N` is a `p \times p` circulant matrix whose top row is `(0,y_1,...,y_{p-1})`, where `x_i+y_i=1` for all `i`. INPUT: - ``p`` -- a prime `>2`. OUTPUT: Returns a QQR code of length `2p`. EXAMPLES:: sage: C = codes.QuasiQuadraticResidueCode(11); C # optional - gap_packages (Guava package) [22, 11] linear code over GF(2) These are self-orthogonal in general and self-dual when $p \\equiv 3 \\pmod 4$. AUTHOR: David Joyner (11-2005) """ if not is_package_installed('gap_packages'): raise PackageNotFoundError('gap_packages') F = GF(2) gap.load_package("guava") gap.eval("C:=QQRCode(" + str(p) + ")") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[gfq_gap_to_sage(gap.eval("G[%s][%s]" % (i, j)), F) for j in range(1, n + 1)] for i in range(1, k + 1)] MS = MatrixSpace(F, k, n) return LinearCode(MS(G))
def RandomLinearCodeGuava(n, k, F): r""" The method used is to first construct a `k \times n` matrix of the block form `(I,A)`, where `I` is a `k \times k` identity matrix and `A` is a `k \times (n-k)` matrix constructed using random elements of `F`. Then the columns are permuted using a randomly selected element of the symmetric group `S_n`. INPUT: - ``n,k`` -- integers with `n>k>1`. OUTPUT: Returns a "random" linear code with length `n`, dimension `k` over field `F`. EXAMPLES:: sage: C = codes.RandomLinearCodeGuava(30,15,GF(2)); C # optional - gap_packages (Guava package) [30, 15] linear code over GF(2) sage: C = codes.RandomLinearCodeGuava(10,5,GF(4,'a')); C # optional - gap_packages (Guava package) [10, 5] linear code over GF(4) AUTHOR: David Joyner (11-2005) """ current_randstate().set_seed_gap() q = F.order() if not is_package_installed('gap_packages'): raise PackageNotFoundError('gap_packages') gap.load_package("guava") gap.eval("C:=RandomLinearCode("+str(n)+","+str(k)+", GF("+str(q)+"))") gap.eval("G:=GeneratorMat(C)") k = int(gap.eval("Length(G)")) n = int(gap.eval("Length(G[1])")) G = [[gfq_gap_to_sage(gap.eval("G[%s][%s]" % (i, j)), F) for j in range(1, n + 1)] for i in range(1, k + 1)] MS = MatrixSpace(F, k, n) return LinearCode(MS(G))
def plotkin_upper_bound(n,q,d, algorithm=None): r""" Returns the Plotkin upper bound. Returns the Plotkin upper bound for the number of elements in a largest code of minimum distance `d` in `\GF{q}^n`. More precisely this is a generalization of Plotkin's result for `q=2` to bigger `q` due to Berlekamp. The ``algorithm="gap"`` option wraps Guava's ``UpperBoundPlotkin``. EXAMPLES:: sage: codes.bounds.plotkin_upper_bound(10,2,3) 192 sage: codes.bounds.plotkin_upper_bound(10,2,3,algorithm="gap") # optional - gap_packages (Guava package) 192 """ _check_n_q_d(n, q, d, field_based=False) if algorithm=="gap": gap.load_package("guava") ans=gap.eval("UpperBoundPlotkin(%s,%s,%s)"%(n,d,q)) return QQ(ans) else: t = 1 - 1/q if (q==2) and (n == 2*d) and (d%2 == 0): return 4*d elif (q==2) and (n == 2*d + 1) and (d%2 == 1): return 4*d + 4 elif d > t*n: return int(d/( d - t*n)) elif d < t*n + 1: fact = (d-1) / t if RR(fact)==RR(int(fact)): fact = int(fact) + 1 return int(d/( d - t * fact)) * q**(n - fact)
def codesize_upper_bound(n,d,q,algorithm=None): r""" Returns an upper bound on the number of codewords in a (possibly non-linear) code. This function computes the minimum value of the upper bounds of Singleton, Hamming, Plotkin, and Elias. If algorithm="gap" then this returns the best known upper bound `A(n,d)=A_q(n,d)` for the size of a code of length n, minimum distance d over a field of size q. The function first checks for trivial cases (like d=1 or n=d), and if the value is in the built-in table. Then it calculates the minimum value of the upper bound using the algorithms of Singleton, Hamming, Johnson, Plotkin and Elias. If the code is binary, `A(n, 2\ell-1) = A(n+1,2\ell)`, so the function takes the minimum of the values obtained from all algorithms for the parameters `(n, 2\ell-1)` and `(n+1, 2\ell)`. This wraps GUAVA's (i.e. GAP's package Guava) UpperBound( n, d, q ). If algorithm="LP" then this returns the Delsarte (a.k.a. Linear Programming) upper bound. EXAMPLES:: sage: codes.bounds.codesize_upper_bound(10,3,2) 93 sage: codes.bounds.codesize_upper_bound(24,8,2,algorithm="LP") 4096 sage: codes.bounds.codesize_upper_bound(10,3,2,algorithm="gap") # optional - gap_packages (Guava package) 85 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm=None) 123361 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="gap") # optional - gap_packages (Guava package) 123361 sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="LP") 109226 TESTS: Make sure :trac:`22961` is fixed:: sage: codes.bounds.codesize_upper_bound(19,10,2) 20 sage: codes.bounds.codesize_upper_bound(19,10,2,algorithm="gap") # optional - gap_packages (Guava package) 20 Meaningless parameters are rejected:: sage: codes.bounds.codesize_upper_bound(10, -20, 6) Traceback (most recent call last): ... ValueError: The length or minimum distance does not make sense """ _check_n_q_d(n, q, d, field_based=False) if algorithm=="gap": gap.load_package('guava') return int(gap.eval("UpperBound(%s,%s,%s)"%( n, d, q ))) if algorithm=="LP": return int(delsarte_bound_hamming_space(n,d,q)) else: eub = elias_upper_bound(n,q,d) hub = hamming_upper_bound(n,q,d) pub = plotkin_upper_bound(n,q,d) sub = singleton_upper_bound(n,q,d) return min([eub,hub,pub,sub])
def bounds_on_minimum_distance_in_guava(n, k, F): r""" Computes a lower and upper bound on the greatest minimum distance of a `[n,k]` linear code over the field ``F``. This function requires the optional GAP package GUAVA. The function returns a GAP record with the two bounds and an explanation for each bound. The function Display can be used to show the explanations. The values for the lower and upper bound are obtained from a table constructed by Cen Tjhai for GUAVA, derived from the table of Brouwer. See http://www.codetables.de/ for the most recent data. These tables contain lower and upper bounds for `q=2` (when ``n <= 257``), `q=3` (when ``n <= 243``), `q=4` (``n <= 256``). (Current as of 11 May 2006.) For codes over other fields and for larger word lengths, trivial bounds are used. INPUT: - ``n`` -- the length of the code to look up - ``k`` -- the dimension of the code to look up - ``F`` -- the base field of the code to look up OUTPUT: - A GAP record object. See below for an example. EXAMPLES:: sage: gap_rec = codes.databases.bounds_on_minimum_distance_in_guava(10,5,GF(2)) # optional - gap_packages (Guava package) sage: print(gap_rec) # optional - gap_packages (Guava package) rec( construction := [ <Operation "ShortenedCode">, [ [ <Operation "UUVCode">, [ [ <Operation "DualCode">, [ [ <Operation "RepetitionCode">, [ 8, 2 ] ] ] ], [ <Operation "UUVCode">, [ [ <Operation "DualCode">, [ [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ] , [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ] ] ], [ 1, 2, 3, 4, 5, 6 ] ] ], k := 5, lowerBound := 4, lowerBoundExplanation := ... n := 10, q := 2, references := rec( ), upperBound := 4, upperBoundExplanation := ... ) """ from sage.interfaces.all import gap gap.load_package("guava") q = F.order() gap.eval("data := BoundsMinimumDistance(%s,%s,GF(%s))"%(n,k,q)) Ldata = gap.eval("Display(data)") return Ldata
def bounds_on_minimum_distance_in_guava(n, k, F): r""" Computes a lower and upper bound on the greatest minimum distance of a `[n,k]` linear code over the field ``F``. This function requires the optional GAP package GUAVA. The function returns a GAP record with the two bounds and an explanation for each bound. The function Display can be used to show the explanations. The values for the lower and upper bound are obtained from a table constructed by Cen Tjhai for GUAVA, derived from the table of Brouwer. See http://www.codetables.de/ for the most recent data. These tables contain lower and upper bounds for `q=2` (when ``n <= 257``), `q=3` (when ``n <= 243``), `q=4` (``n <= 256``). (Current as of 11 May 2006.) For codes over other fields and for larger word lengths, trivial bounds are used. INPUT: - ``n`` -- the length of the code to look up - ``k`` -- the dimension of the code to look up - ``F`` -- the base field of the code to look up OUTPUT: - A GAP record object. See below for an example. EXAMPLES:: sage: gap_rec = codes.databases.bounds_on_minimum_distance_in_guava(10,5,GF(2)) # optional - gap_packages (Guava package) sage: print(gap_rec) # optional - gap_packages (Guava package) rec( construction := [ <Operation "ShortenedCode">, [ [ <Operation "UUVCode">, [ [ <Operation "DualCode">, [ [ <Operation "RepetitionCode">, [ 8, 2 ] ] ] ], [ <Operation "UUVCode">, [ [ <Operation "DualCode">, [ [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ] , [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ] ] ], [ 1, 2, 3, 4, 5, 6 ] ] ], k := 5, lowerBound := 4, lowerBoundExplanation := ... n := 10, q := 2, references := rec( ), upperBound := 4, upperBoundExplanation := ... ) """ GapPackage("guava", spkg="gap_packages").require() gap.load_package("guava") q = F.order() gap.eval("data := BoundsMinimumDistance(%s,%s,GF(%s))" % (n, k, q)) Ldata = gap.eval("Display(data)") return Ldata