From fbe8361e023c99dd58e11947ad54a5907d1f1d23 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 May 2024 21:52:01 -0700 Subject: [PATCH 1/7] sage.coding: Update # needs --- src/sage/coding/abstract_code.py | 2 +- src/sage/coding/ag_code.py | 2 +- src/sage/coding/ag_code_decoders.pyx | 2 +- src/sage/coding/bch_code.py | 2 +- src/sage/coding/binary_code.pyx | 4 +- src/sage/coding/channel.py | 2 +- src/sage/coding/code_bounds.py | 64 ++++--- src/sage/coding/code_constructions.py | 48 ++--- src/sage/coding/codecan/codecan.pyx | 1 + src/sage/coding/cyclic_code.py | 4 +- src/sage/coding/databases.py | 17 +- src/sage/coding/decoder.py | 2 +- src/sage/coding/delsarte_bounds.py | 5 +- src/sage/coding/encoder.py | 2 +- src/sage/coding/extended_code.py | 3 +- src/sage/coding/gabidulin_code.py | 2 +- src/sage/coding/golay_code.py | 5 +- src/sage/coding/goppa_code.py | 2 +- src/sage/coding/grs_code.py | 8 +- src/sage/coding/guava.py | 2 +- src/sage/coding/guruswami_sudan/gs_decoder.py | 3 +- .../coding/guruswami_sudan/interpolation.py | 2 +- src/sage/coding/guruswami_sudan/utils.py | 9 +- src/sage/coding/hamming_code.py | 2 +- src/sage/coding/information_set_decoder.py | 4 +- src/sage/coding/kasami_codes.pyx | 6 +- src/sage/coding/linear_code.py | 173 +++++++++--------- src/sage/coding/linear_code_no_metric.py | 4 +- src/sage/coding/linear_rank_metric.py | 2 +- src/sage/coding/parity_check_code.py | 2 +- src/sage/coding/punctured_code.py | 2 +- src/sage/coding/reed_muller_code.py | 2 +- src/sage/coding/self_dual_codes.py | 2 +- src/sage/coding/source_coding/huffman.py | 10 +- src/sage/coding/subfield_subcode.py | 2 +- src/sage/coding/two_weight_db.py | 2 +- 36 files changed, 216 insertions(+), 190 deletions(-) diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index 0b2031a74f2..ca46d40327b 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Codes diff --git a/src/sage/coding/ag_code.py b/src/sage/coding/ag_code.py index 0f189bb69a0..787be4ee8b0 100644 --- a/src/sage/coding/ag_code.py +++ b/src/sage/coding/ag_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.rings.finite_rings sage.schemes +# sage.doctest: needs sage.rings.finite_rings sage.schemes """ AG codes diff --git a/src/sage/coding/ag_code_decoders.pyx b/src/sage/coding/ag_code_decoders.pyx index 9ce2aa2f8ce..3303c4602c6 100644 --- a/src/sage/coding/ag_code_decoders.pyx +++ b/src/sage/coding/ag_code_decoders.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.rings.finite_rings sage.schemes +# sage.doctest: needs sage.rings.finite_rings sage.schemes r""" Decoders for AG codes diff --git a/src/sage/coding/bch_code.py b/src/sage/coding/bch_code.py index 40fa088354a..1344ba42f65 100644 --- a/src/sage/coding/bch_code.py +++ b/src/sage/coding/bch_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" BCH code diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 81065a7dbd3..a86c0ebd1e8 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Optimized low-level binary code representation @@ -899,6 +899,7 @@ cdef class BinaryCode: EXAMPLES:: + sage: # needs sage.graphs sage: import sage.coding.binary_code sage: from sage.coding.binary_code import * sage: M = Matrix(GF(2), [[1,1,1,1]]) @@ -3977,6 +3978,7 @@ cdef class BinaryCodeClassifier: MORE EXAMPLES:: + sage: # needs sage.groups sage: soc_iter = codes.databases.self_orthogonal_binary_codes(12, 6, 4) sage: L = list(soc_iter) sage: for n in range(13): diff --git a/src/sage/coding/channel.py b/src/sage/coding/channel.py index 353c540575c..f197bc607d2 100644 --- a/src/sage/coding/channel.py +++ b/src/sage/coding/channel.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Channels diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 7b80eec172a..63f08719b21 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -199,6 +199,7 @@ def _check_n_q_d(n, q, d, field_based=True): TESTS:: + sage: # needs sage.libs.pari sage: from sage.coding.code_bounds import _check_n_q_d sage: _check_n_q_d(20, 16, 5) True @@ -251,26 +252,26 @@ def codesize_upper_bound(n, d, q, algorithm=None): EXAMPLES:: - sage: codes.bounds.codesize_upper_bound(10,3,2) + sage: codes.bounds.codesize_upper_bound(10, 3, 2) 93 - sage: codes.bounds.codesize_upper_bound(24,8,2,algorithm="LP") + sage: codes.bounds.codesize_upper_bound(24, 8, 2, algorithm="LP") # needs sage.numerical.mip 4096 - sage: codes.bounds.codesize_upper_bound(10,3,2,algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.codesize_upper_bound(10, 3, 2, algorithm="gap") # optional - gap_package_guava 85 - sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm=None) + sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm=None) # needs sage.symbolic 123361 - sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm="gap") # optional - gap_package_guava 123361 - sage: codes.bounds.codesize_upper_bound(11,3,4,algorithm="LP") + sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm="LP") # needs sage.numerical.mip 109226 TESTS: Make sure :issue:`22961` is fixed:: - sage: codes.bounds.codesize_upper_bound(19,10,2) + sage: codes.bounds.codesize_upper_bound(19, 10, 2) 20 - sage: codes.bounds.codesize_upper_bound(19,10,2,algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.codesize_upper_bound(19, 10, 2, algorithm="gap") # optional - gap_package_guava 20 Meaningless parameters are rejected:: @@ -308,18 +309,18 @@ def dimension_upper_bound(n, d, q, algorithm=None): EXAMPLES:: - sage: codes.bounds.dimension_upper_bound(10,3,2) + sage: codes.bounds.dimension_upper_bound(10,3,2) # needs sage.libs.pari sage.symbolic 6 - sage: codes.bounds.dimension_upper_bound(30,15,4) + sage: codes.bounds.dimension_upper_bound(30,15,4) # needs sage.libs.pari sage.symbolic 13 - sage: codes.bounds.dimension_upper_bound(30,15,4,algorithm="LP") + sage: codes.bounds.dimension_upper_bound(30,15,4,algorithm="LP") # needs sage.libs.pari sage.numerical.mip 12 TESTS: Meaningless code parameters are rejected:: - sage: codes.bounds.dimension_upper_bound(13,3,6) + sage: codes.bounds.dimension_upper_bound(13,3,6) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: The alphabet size does not make sense for a code over a field @@ -421,23 +422,23 @@ def griesmer_upper_bound(n,q,d,algorithm=None): The bound is reached for the ternary Golay codes:: - sage: codes.bounds.griesmer_upper_bound(12,3,6) + sage: codes.bounds.griesmer_upper_bound(12,3,6) # needs sage.libs.pari 729 - sage: codes.bounds.griesmer_upper_bound(11,3,5) + sage: codes.bounds.griesmer_upper_bound(11,3,5) # needs sage.libs.pari 729 :: - sage: codes.bounds.griesmer_upper_bound(10,2,3) + sage: codes.bounds.griesmer_upper_bound(10,2,3) # needs sage.libs.pari 128 - sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap") # optional - gap_package_guava + sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap") # optional - gap_package_guava, needs sage.libs.pari 128 TESTS:: - sage: codes.bounds.griesmer_upper_bound(11,3,6) + sage: codes.bounds.griesmer_upper_bound(11,3,6) # needs sage.libs.pari 243 - sage: codes.bounds.griesmer_upper_bound(11,3,6) + sage: codes.bounds.griesmer_upper_bound(11,3,6) # needs sage.libs.pari 243 """ _check_n_q_d(n, q, d) @@ -448,7 +449,7 @@ def griesmer_upper_bound(n,q,d,algorithm=None): 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 + from sage.arith.misc import integer_ceil as ceil den = 1 s = 0 k = 0 @@ -570,7 +571,7 @@ def gv_info_rate(n, delta, q): EXAMPLES:: - sage: RDF(codes.bounds.gv_info_rate(100,1/4,3)) # abs tol 1e-15 + sage: RDF(codes.bounds.gv_info_rate(100,1/4,3)) # abs tol 1e-15 # needs sage.libs.pari sage.symbolic 0.36704992608261894 """ q = ZZ(q) @@ -592,9 +593,9 @@ def entropy(x, q=2): sage: codes.bounds.entropy(0, 2) 0 - sage: codes.bounds.entropy(1/5,4).factor() # optional - sage.symbolic + sage: codes.bounds.entropy(1/5,4).factor() # needs sage.symbolic 1/10*(log(3) - 4*log(4/5) - log(1/5))/log(2) - sage: codes.bounds.entropy(1, 3) # optional - sage.symbolic + sage: codes.bounds.entropy(1, 3) # needs sage.symbolic log(2)/log(3) Check that values not within the limits are properly handled:: @@ -641,8 +642,9 @@ def entropy_inverse(x, q=2): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.coding.code_bounds import entropy_inverse - sage: entropy_inverse(0.1) + sage: entropy_inverse(0.1) # needs scipy 0.012986862055... sage: entropy_inverse(1) 1/2 @@ -678,10 +680,11 @@ def gv_bound_asymp(delta, q): EXAMPLES:: - sage: RDF(codes.bounds.gv_bound_asymp(1/4,2)) + sage: # needs sage.symbolic + sage: RDF(codes.bounds.gv_bound_asymp(1/4,2)) # needs sage.libs.pari 0.18872187554086... sage: f = lambda x: codes.bounds.gv_bound_asymp(x,2) - sage: plot(f,0,1) + sage: plot(f,0,1) # needs sage.libs.pari sage.plot Graphics object consisting of 1 graphics primitive """ return 1 - entropy(delta, q) @@ -693,10 +696,11 @@ def hamming_bound_asymp(delta, q): EXAMPLES:: - sage: RDF(codes.bounds.hamming_bound_asymp(1/4,2)) + sage: # needs sage.symbolic + sage: RDF(codes.bounds.hamming_bound_asymp(1/4,2)) # needs sage.libs.pari 0.456435556800... sage: f = lambda x: codes.bounds.hamming_bound_asymp(x,2) - sage: plot(f,0,1) + sage: plot(f,0,1) # needs sage.libs.pari sage.plot Graphics object consisting of 1 graphics primitive """ return 1 - entropy(delta / 2, q) @@ -711,7 +715,7 @@ def singleton_bound_asymp(delta, q): sage: codes.bounds.singleton_bound_asymp(1/4,2) 3/4 sage: f = lambda x: codes.bounds.singleton_bound_asymp(x,2) - sage: plot(f,0,1) + sage: plot(f,0,1) # needs sage.plot Graphics object consisting of 1 graphics primitive """ return 1 - delta @@ -740,7 +744,7 @@ def elias_bound_asymp(delta, q): EXAMPLES:: - sage: codes.bounds.elias_bound_asymp(1/4,2) + sage: codes.bounds.elias_bound_asymp(1/4,2) # needs sage.symbolic 0.39912396330... """ r = 1 - 1 / q @@ -755,7 +759,7 @@ def mrrw1_bound_asymp(delta, q): EXAMPLES:: - sage: codes.bounds.mrrw1_bound_asymp(1/4,2) # abs tol 4e-16 + sage: codes.bounds.mrrw1_bound_asymp(1/4,2) # abs tol 4e-16 # needs sage.symbolic 0.3545789026652697 """ return RDF(entropy((q-1-delta*(q-2)-2*sqrt((q-1)*delta*(1-delta)))/q,q)) diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index 6870c28ec87..94a8eddde95 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Linear code constructors that do not preserve the structural information @@ -229,28 +229,28 @@ def permutation_action(g, v): sage: V = VectorSpace(GF(3),5) sage: v = V([0,1,2,0,1]) - sage: G = SymmetricGroup(5) # optional - sage.groups - sage: g = G([(1,2,3)]) # optional - sage.groups - sage: permutation_action(g,v) # optional - sage.groups + sage: G = SymmetricGroup(5) # needs sage.groups + sage: g = G([(1,2,3)]) # needs sage.groups + sage: permutation_action(g,v) # needs sage.groups (1, 2, 0, 0, 1) - sage: g = G([()]) # optional - sage.groups - sage: permutation_action(g,v) # optional - sage.groups + sage: g = G([()]) # needs sage.groups + sage: permutation_action(g,v) # needs sage.groups (0, 1, 2, 0, 1) - sage: g = G([(1,2,3,4,5)]) # optional - sage.groups - sage: permutation_action(g,v) # optional - sage.groups + sage: g = G([(1,2,3,4,5)]) # needs sage.groups + sage: permutation_action(g,v) # needs sage.groups (1, 2, 0, 1, 0) sage: L = Sequence([1,2,3,4,5]) - sage: permutation_action(g,L) # optional - sage.groups + sage: permutation_action(g,L) # needs sage.groups [2, 3, 4, 5, 1] sage: MS = MatrixSpace(GF(3),3,7) sage: A = MS([[1,0,0,0,1,1,0],[0,1,0,1,0,1,0],[0,0,0,0,0,0,1]]) - sage: S5 = SymmetricGroup(5) # optional - sage.groups - sage: g = S5([(1,2,3)]) # optional - sage.groups + sage: S5 = SymmetricGroup(5) # needs sage.groups + sage: g = S5([(1,2,3)]) # needs sage.groups sage: A [1 0 0 0 1 1 0] [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] - sage: permutation_action(g,A) # optional - sage.groups + sage: permutation_action(g,A) # needs sage.groups [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] [1 0 0 0 1 1 0] @@ -258,16 +258,16 @@ def permutation_action(g, v): It also works on lists and is a "left action":: sage: v = [0,1,2,0,1] - sage: G = SymmetricGroup(5) # optional - sage.groups - sage: g = G([(1,2,3)]) # optional - sage.groups - sage: gv = permutation_action(g,v); gv # optional - sage.groups + sage: G = SymmetricGroup(5) # needs sage.groups + sage: g = G([(1,2,3)]) # needs sage.groups + sage: gv = permutation_action(g,v); gv # needs sage.groups [1, 2, 0, 0, 1] - sage: permutation_action(g,v) == g(v) # optional - sage.groups + sage: permutation_action(g,v) == g(v) # needs sage.groups True - sage: h = G([(3,4)]) # optional - sage.groups - sage: gv = permutation_action(g,v) # optional - sage.groups - sage: hgv = permutation_action(h,gv) # optional - sage.groups - sage: hgv == permutation_action(h*g,v) # optional - sage.groups + sage: h = G([(3,4)]) # needs sage.groups + sage: gv = permutation_action(g,v) # needs sage.groups + sage: hgv = permutation_action(h,gv) # needs sage.groups + sage: hgv == permutation_action(h*g,v) # needs sage.groups True AUTHORS: @@ -729,7 +729,7 @@ def ToricCode(P,F): sage: C = codes.ToricCode([[0,0],[1,0],[2,0],[0,1],[1,1]], GF(7)) sage: C [36, 5] linear code over GF(7) - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.groups 24 sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava ...24 @@ -737,7 +737,7 @@ def ToricCode(P,F): ....: [0,-1],[0,0],[0,1],[1,-1],[1,0]], GF(5)) sage: C [16, 9] linear code over GF(5) - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.groups 6 sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava 6 @@ -786,9 +786,9 @@ def WalshCode(m): [8, 3] linear code over GF(2) sage: C.spectrum() [1, 0, 0, 0, 7, 0, 0, 0, 0] - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 4 - sage: C.minimum_distance(algorithm='gap') # check d=2^(m-1) + sage: C.minimum_distance(algorithm='gap') # check d=2^(m-1) # needs sage.libs.gap 4 REFERENCES: diff --git a/src/sage/coding/codecan/codecan.pyx b/src/sage/coding/codecan/codecan.pyx index 89a04d61433..4ea2d566472 100644 --- a/src/sage/coding/codecan/codecan.pyx +++ b/src/sage/coding/codecan/codecan.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.pari r""" Canonical forms and automorphism group computation for linear codes over finite fields diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index 8cab59c2504..66de4b4840b 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Cyclic code @@ -977,7 +977,7 @@ def message_space(self): sage: g = x ** 3 + x + 1 sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) - sage: E.message_space() + sage: E.message_space() # needs sage.libs.ntl Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) """ return self._polynomial_ring diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index 989d67e89d8..fc814b1901b 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Access functions to online databases for coding theory """ @@ -7,6 +7,11 @@ lazy_import('sage.libs.gap.libgap', 'libgap') +# Import the following function so that it is available as +# sage.codes.databases.self_dual_binary_codes sage.codes.databases functions +# somewhat like a catalog in this respect. +lazy_import('sage.coding.self_dual_codes', 'self_dual_binary_codes') + del lazy_import # Do not put any global imports here since this module is accessible as @@ -210,6 +215,7 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, Generate all self-orthogonal codes of length up to 7 and dimension up to 3:: + sage: # needs sage.groups sage: for B in codes.databases.self_orthogonal_binary_codes(7,3): ....: print(B) [2, 1] linear code over GF(2) @@ -224,6 +230,7 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, Generate all doubly-even codes of length up to 7 and dimension up to 3:: + sage: # needs sage.groups sage: for B in codes.databases.self_orthogonal_binary_codes(7,3,4): ....: print(B); print(B.generator_matrix()) [4, 1] linear code over GF(2) @@ -239,6 +246,7 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, Generate all doubly-even codes of length up to 7 and dimension up to 2:: + sage: # needs sage.groups sage: for B in codes.databases.self_orthogonal_binary_codes(7,2,4): ....: print(B); print(B.generator_matrix()) [4, 1] linear code over GF(2) @@ -250,6 +258,7 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, Generate all self-orthogonal codes of length equal to 8 and dimension equal to 4:: + sage: # needs sage.groups sage: for B in codes.databases.self_orthogonal_binary_codes(8, 4, equal=True): ....: print(B); print(B.generator_matrix()) [8, 4] linear code over GF(2) @@ -308,9 +317,3 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, for N in self_orthogonal_binary_codes(n, k, d, child, BC, in_test=in_test): if out_test(N): yield N - - -# Import the following function so that it is available as -# sage.codes.databases.self_dual_binary_codes sage.codes.databases functions -# somewhat like a catalog in this respect. -from sage.coding.self_dual_codes import self_dual_binary_codes diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index 503c31a3b39..76bbe8c0c7a 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Decoders diff --git a/src/sage/coding/delsarte_bounds.py b/src/sage/coding/delsarte_bounds.py index 0f8fa305a08..44d93d8adb1 100644 --- a/src/sage/coding/delsarte_bounds.py +++ b/src/sage/coding/delsarte_bounds.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.numerical.mip r""" Delsarte (or linear programming) bounds @@ -87,9 +88,9 @@ def krawtchouk(n, q, l, x, check=True): Other unusual inputs:: - sage: codes.bounds.krawtchouk(sqrt(5),1-I*sqrt(3),3,55.3).n() + sage: codes.bounds.krawtchouk(sqrt(5),1-I*sqrt(3),3,55.3).n() # needs sage.symbolic 211295.892797... + 1186.42763...*I - sage: codes.bounds.krawtchouk(-5/2,7*I,3,-1/10) + sage: codes.bounds.krawtchouk(-5/2,7*I,3,-1/10) # needs sage.symbolic 480053/250*I - 357231/400 sage: codes.bounds.krawtchouk(1,1,-1,1) Traceback (most recent call last): diff --git a/src/sage/coding/encoder.py b/src/sage/coding/encoder.py index f603f337008..73c64825104 100644 --- a/src/sage/coding/encoder.py +++ b/src/sage/coding/encoder.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Encoders diff --git a/src/sage/coding/extended_code.py b/src/sage/coding/extended_code.py index c27acc58066..a9d582b2a67 100644 --- a/src/sage/coding/extended_code.py +++ b/src/sage/coding/extended_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Extended code @@ -397,6 +397,7 @@ def decode_to_code(self, y, **kwargs): Another example, with a list decoder:: + sage: # needs sage.symbolic sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) sage: Ce = codes.ExtendedCode(C) sage: Dgrs = C.decoder('GuruswamiSudan', tau=4) diff --git a/src/sage/coding/gabidulin_code.py b/src/sage/coding/gabidulin_code.py index 0ba1d13ec41..341b9b89f5d 100644 --- a/src/sage/coding/gabidulin_code.py +++ b/src/sage/coding/gabidulin_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Gabidulin Code diff --git a/src/sage/coding/golay_code.py b/src/sage/coding/golay_code.py index e698605825e..7690962b4b7 100644 --- a/src/sage/coding/golay_code.py +++ b/src/sage/coding/golay_code.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Golay code @@ -261,11 +262,11 @@ def weight_distribution(self): True sage: C = codes.GolayCode(GF(3)) - sage: C.weight_distribution() == super(codes.GolayCode, C).weight_distribution() + sage: C.weight_distribution() == super(codes.GolayCode, C).weight_distribution() # needs sage.libs.gap True sage: C = codes.GolayCode(GF(3), extended=False) - sage: C.weight_distribution() == super(codes.GolayCode, C).weight_distribution() + sage: C.weight_distribution() == super(codes.GolayCode, C).weight_distribution() # needs sage.libs.gap True """ n = self.length() diff --git a/src/sage/coding/goppa_code.py b/src/sage/coding/goppa_code.py index a642fb86049..e173904e59e 100644 --- a/src/sage/coding/goppa_code.py +++ b/src/sage/coding/goppa_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Goppa code diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index 7a39d548c44..682036ef00b 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Reed-Solomon codes and Generalized Reed-Solomon codes @@ -514,7 +514,7 @@ def weight_distribution(self): sage: F = GF(11) sage: n, k = 10, 5 sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) - sage: C.weight_distribution() # optional - sage.symbolic + sage: C.weight_distribution() # needs sage.symbolic [1, 0, 0, 0, 0, 0, 2100, 6000, 29250, 61500, 62200] TESTS: @@ -523,11 +523,11 @@ def weight_distribution(self): sage: F = GF(7) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time, needs sage.symbolic True sage: F = GF(8) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time, needs sage.symbolic True """ from sage.symbolic.ring import SR diff --git a/src/sage/coding/guava.py b/src/sage/coding/guava.py index 92e2dc80451..70d808a96fa 100644 --- a/src/sage/coding/guava.py +++ b/src/sage/coding/guava.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.gap sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.libs.gap sage.modules sage.rings.finite_rings r""" Constructions of generator matrices using the GUAVA package for GAP diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index d992a881c04..25ac03ab6b2 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings sage.symbolic r""" Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes @@ -25,6 +25,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from sage.arith.misc import integer_floor as floor from sage.coding.grs_code import GeneralizedReedSolomonCode from sage.rings.integer_ring import ZZ from sage.coding.decoder import Decoder diff --git a/src/sage/coding/guruswami_sudan/interpolation.py b/src/sage/coding/guruswami_sudan/interpolation.py index 62ed9f3a8f1..ec4307a500b 100644 --- a/src/sage/coding/guruswami_sudan/interpolation.py +++ b/src/sage/coding/guruswami_sudan/interpolation.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings """ Interpolation algorithms for the Guruswami-Sudan decoder diff --git a/src/sage/coding/guruswami_sudan/utils.py b/src/sage/coding/guruswami_sudan/utils.py index d899bd0e12e..f29d4eac46f 100644 --- a/src/sage/coding/guruswami_sudan/utils.py +++ b/src/sage/coding/guruswami_sudan/utils.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Guruswami-Sudan utility methods @@ -20,7 +20,8 @@ #***************************************************************************** -from sage.functions.other import floor +from sage.arith.misc import integer_floor as floor +from sage.misc.lazy_import import lazy_import from sage.misc.functional import sqrt from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer @@ -61,7 +62,7 @@ def johnson_radius(n, d): EXAMPLES:: - sage: sage.coding.guruswami_sudan.utils.johnson_radius(250, 181) + sage: sage.coding.guruswami_sudan.utils.johnson_radius(250, 181) # needs sage.symbolic -5*sqrt(690) + 250 """ return n - sqrt(n*(n-d)) @@ -122,7 +123,7 @@ def solve_degree2_to_integer_range(a, b, c): EXAMPLES:: sage: from sage.coding.guruswami_sudan.utils import solve_degree2_to_integer_range - sage: solve_degree2_to_integer_range(1, -5, 1) + sage: solve_degree2_to_integer_range(1, -5, 1) # needs sage.symbolic (1, 4) If there is no real solution:: diff --git a/src/sage/coding/hamming_code.py b/src/sage/coding/hamming_code.py index 5209a0c3754..184023e3c29 100644 --- a/src/sage/coding/hamming_code.py +++ b/src/sage/coding/hamming_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Hamming codes diff --git a/src/sage/coding/information_set_decoder.py b/src/sage/coding/information_set_decoder.py index dad1f2b06f3..ede9a7f1c3e 100644 --- a/src/sage/coding/information_set_decoder.py +++ b/src/sage/coding/information_set_decoder.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Information-set decoding for linear codes @@ -40,11 +40,11 @@ # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.arith.misc import binomial from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from sage.modules.free_module_element import free_module_element as vector from sage.structure.sage_object import SageObject -from sage.functions.other import binomial from .decoder import Decoder diff --git a/src/sage/coding/kasami_codes.pyx b/src/sage/coding/kasami_codes.pyx index 4c35ed34e33..5f5b9a02543 100644 --- a/src/sage/coding/kasami_codes.pyx +++ b/src/sage/coding/kasami_codes.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Kasami code @@ -98,7 +98,7 @@ class KasamiCode(AbstractLinearCode): sage: codes.KasamiCode(16,4) [16, 9] Extended (16, 4)-Kasami code - sage: _.minimum_distance() + sage: _.minimum_distance() # needs sage.libs.gap 4 sage: codes.KasamiCode(8, 2, extended=False) @@ -134,7 +134,7 @@ class KasamiCode(AbstractLinearCode): True sage: C1 == C2 False - sage: C1.minimum_distance() == C2.minimum_distance()+1 + sage: C1.minimum_distance() == C2.minimum_distance() + 1 # needs sage.libs.gap True sage: C = codes.KasamiCode(4,2) sage: C.dimension() diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 1a0f037ddad..ec326b03281 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Generic structures for linear codes over the Hamming metric @@ -406,7 +406,7 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam And any method that works on linear codes works for our new dummy code:: - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 1 sage: C.is_self_orthogonal() False @@ -466,7 +466,8 @@ def automorphism_group_gens(self, equivalence="semilinear"): depends on which packages are loaded, so we must re-seed GAP to ensure a consistent result for this example:: - sage: libgap.set_seed(0) # optional - sage.libs.gap + sage: # needs sage.libs.gap + sage: libgap.set_seed(0) 0 sage: C = codes.HammingCode(GF(4, 'z'), 3) sage: C.automorphism_group_gens() @@ -589,14 +590,15 @@ def assmus_mattson_designs(self, t, mode=None): sage: C = codes.GolayCode(GF(2)) # example 1 sage: C.assmus_mattson_designs(5) ['weights from C: ', [8, 12, 16, 24], - 'designs from C: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)], - [5, (24, 24, 1)]], - 'weights from C*: ', [8, 12, 16], - 'designs from C*: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)]]] + 'designs from C: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], + [5, (24, 16, 78)], [5, (24, 24, 1)]], + 'weights from C*: ', [8, 12, 16], + 'designs from C*: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)]]] sage: C.assmus_mattson_designs(6) 0 sage: X = range(24) # example 2 - sage: blocks = [c.support() for c in C if c.hamming_weight()==8]; len(blocks) # long time computation + sage: blocks = [c.support() # long time + ....: for c in C if c.hamming_weight()==8]; len(blocks) 759 """ C = self @@ -651,9 +653,9 @@ def binomial_moment(self, i): EXAMPLES:: sage: C = codes.HammingCode(GF(2), 3) - sage: C.binomial_moment(2) + sage: C.binomial_moment(2) # needs sage.libs.gap 0 - sage: C.binomial_moment(4) # long time + sage: C.binomial_moment(4) # long time # needs sage.libs.gap 35 .. warning:: @@ -710,6 +712,7 @@ def _canonize(self, equivalence): depends on which packages are loaded, so we must re-seed GAP to ensure a consistent result for this example:: + sage: # needs sage.libs.gap sage: libgap.set_seed(0) 0 sage: C = codes.HammingCode(GF(4, 'z'), 3) @@ -718,12 +721,15 @@ def _canonize(self, equivalence): sage: C_iso == aut_group_can_label.get_canonical_form() True sage: aut_group_can_label.get_autom_gens() - [((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z); (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z + 1), - ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, z, z + 1, z, z, z); (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z + 1), - ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); (), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z)] + [((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z); (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z + 1), + ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, z, z + 1, z, z, z); (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z + 1), + ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); (), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z)] """ from sage.coding.codecan.autgroup_can_label import LinearCodeAutGroupCanLabel return LinearCodeAutGroupCanLabel(self, algorithm_type=equivalence) @@ -758,27 +764,27 @@ def canonical_representative(self, equivalence="semilinear"): sage: F. = GF(4) sage: C = codes.HammingCode(F, 3) - sage: CanRep, transp = C.canonical_representative() + sage: CanRep, transp = C.canonical_representative() # needs sage.libs.gap Check that the transporter element is correct:: - sage: LinearCode(transp*C.generator_matrix()) == CanRep + sage: LinearCode(transp*C.generator_matrix()) == CanRep # needs sage.libs.gap True Check if an equivalent code has the same canonical representative:: sage: f = F.hom([z**2]) sage: C_iso = LinearCode(C.generator_matrix().apply_map(f)) - sage: CanRep_iso, _ = C_iso.canonical_representative() - sage: CanRep_iso == CanRep + sage: CanRep_iso, _ = C_iso.canonical_representative() # needs sage.libs.gap + sage: CanRep_iso == CanRep # needs sage.libs.gap True Since applying the Frobenius automorphism could be extended to an automorphism of `C`, the following must also yield ``True``:: - sage: CanRep1, _ = C.canonical_representative("linear") - sage: CanRep2, _ = C_iso.canonical_representative("linear") - sage: CanRep2 == CanRep1 + sage: CanRep1, _ = C.canonical_representative("linear") # needs sage.libs.gap + sage: CanRep2, _ = C_iso.canonical_representative("linear") # needs sage.libs.gap + sage: CanRep2 == CanRep1 # needs sage.libs.gap True TESTS: @@ -787,7 +793,7 @@ def canonical_representative(self, equivalence="semilinear"): (see :issue:`21651`):: sage: C = LinearCode(random_matrix(GF(47), 25, 35)) - sage: alarm(0.5); C.canonical_representative() + sage: alarm(0.5); C.canonical_representative() # needs sage.libs.gap Traceback (most recent call last): ... AlarmInterrupt @@ -899,7 +905,7 @@ def covering_radius(self): This method requires the optional GAP package Guava. - If the covering radius a code equals its minimum distance, then the code is called perfect. + If the covering radius of a code equals its minimum distance, then the code is called perfect. .. NOTE:: @@ -973,7 +979,7 @@ def is_projective(self): sage: C = codes.GolayCode(GF(2), False) sage: C.is_projective() True - sage: C.dual_code().minimum_distance() + sage: C.dual_code().minimum_distance() # needs sage.libs.gap 8 A non-projective code:: @@ -1106,7 +1112,7 @@ def product_code(self, other): True sage: A.dimension() == C.dimension()*D.dimension() True - sage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance() + sage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance() # needs sage.libs.gap True """ @@ -1138,18 +1144,18 @@ def construction_x(self, other, aux): [15, 7] BCH Code over GF(2) with designed distance 5 sage: C.is_subcode(D) True - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 7 - sage: D.minimum_distance() + sage: D.minimum_distance() # needs sage.libs.gap 5 sage: aux = codes.HammingCode(GF(2),2) sage: aux = aux.dual_code() - sage: aux.minimum_distance() + sage: aux.minimum_distance() # needs sage.libs.gap 2 sage: Cx = D.construction_x(C,aux) sage: Cx [18, 7] linear code over GF(2) - sage: Cx.minimum_distance() + sage: Cx.minimum_distance() # needs sage.libs.gap 7 """ if not other.is_subcode(self): @@ -1278,7 +1284,7 @@ def is_permutation_equivalent(self,other,algorithm=None): [7, 4] Hamming Code over GF(2) sage: C1.is_permutation_equivalent(C2) True - sage: C1.is_permutation_equivalent(C2, algorithm="verbose") + sage: C1.is_permutation_equivalent(C2, algorithm="verbose") # needs sage.groups (True, (3,4)(5,7,6)) sage: C1 = codes.random_linear_code(GF(2), 10, 5) sage: C2 = codes.random_linear_code(GF(3), 10, 5) @@ -1364,15 +1370,15 @@ def minimum_distance(self, algorithm=None): sage: MS = MatrixSpace(GF(3),4,7) sage: G = MS([[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 3 If ``algorithm`` is provided, then the minimum distance will be recomputed even if there is a stored value from a previous run.:: - sage: C.minimum_distance(algorithm="gap") # optional - sage.libs.gap + sage: C.minimum_distance(algorithm="gap") # needs sage.libs.gap 3 - sage: libgap.SetAllInfoLevels(0) # to suppress extra info messages # optional - sage.libs.gap + sage: libgap.SetAllInfoLevels(0) # to suppress extra info messages # needs sage.libs.gap sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava ...3 @@ -1443,14 +1449,14 @@ def _minimum_weight_codeword(self, algorithm=None): sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) - sage: C._minimum_weight_codeword() + sage: C._minimum_weight_codeword() # needs sage.libs.gap (0, 1, 0, 1, 0, 1, 0) TESTS: We check that :issue:`18480` is fixed:: - sage: codes.HammingCode(GF(2), 2).minimum_distance() + sage: codes.HammingCode(GF(2), 2).minimum_distance() # needs sage.libs.gap 3 AUTHORS: @@ -1504,8 +1510,8 @@ def module_composition_factors(self, gp): sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) sage: C = LinearCode(G) - sage: gp = C.permutation_automorphism_group() - sage: C.module_composition_factors(gp) # optional - sage.libs.gap + sage: gp = C.permutation_automorphism_group() # needs sage.libs.gap + sage: C.module_composition_factors(gp) # needs sage.libs.gap [ rec( IsIrreducible := true, IsOverFiniteField := true, @@ -1565,14 +1571,15 @@ def permutation_automorphism_group(self, algorithm="partition"): sage: MS = MatrixSpace(GF(2),4,8) sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) - sage: C = LinearCode(G) - sage: C + sage: C = LinearCode(G); C [8, 4] linear code over GF(2) - sage: G = C.permutation_automorphism_group() # optional - sage.groups - sage: G.order() # optional - sage.groups + + sage: # needs sage.groups + sage: G = C.permutation_automorphism_group() + sage: G.order() 144 - sage: GG = C.permutation_automorphism_group("codecan") # optional - sage.groups - sage: GG == G # optional - sage.groups + sage: GG = C.permutation_automorphism_group("codecan") + sage: GG == G True A less easy example involves showing that the permutation @@ -1581,42 +1588,44 @@ def permutation_automorphism_group(self, algorithm="partition"): :: + sage: # needs sage.groups sage: C = codes.GolayCode(GF(3)) - sage: M11 = MathieuGroup(11) # optional - sage.groups - sage: M11.order() # optional - sage.groups + sage: M11 = MathieuGroup(11) + sage: M11.order() 7920 - sage: G = C.permutation_automorphism_group() # long time (6s on sage.math, 2011) # optional - sage.groups - sage: G.is_isomorphic(M11) # long time # optional - sage.groups + sage: G = C.permutation_automorphism_group() # long time (6s on sage.math, 2011) + sage: G.is_isomorphic(M11) # long time True - sage: GG = C.permutation_automorphism_group("codecan") # long time # optional - sage.groups - sage: GG == G # long time # optional - sage.groups + sage: GG = C.permutation_automorphism_group("codecan") # long time + sage: GG == G # long time True Other examples:: + sage: # needs sage.groups sage: C = codes.GolayCode(GF(2)) - sage: G = C.permutation_automorphism_group() # optional - sage.groups - sage: G.order() # optional - sage.groups + sage: G = C.permutation_automorphism_group() + sage: G.order() 244823040 sage: C = codes.HammingCode(GF(2), 5) - sage: G = C.permutation_automorphism_group() # optional - sage.groups - sage: G.order() # optional - sage.groups + sage: G = C.permutation_automorphism_group() + sage: G.order() 9999360 sage: C = codes.HammingCode(GF(3), 2); C [4, 2] Hamming Code over GF(3) - sage: C.permutation_automorphism_group(algorithm="partition") # optional - sage.groups + sage: C.permutation_automorphism_group(algorithm="partition") Permutation Group with generators [(1,3,4)] sage: C = codes.HammingCode(GF(4,"z"), 2); C [5, 3] Hamming Code over GF(4) - sage: G = C.permutation_automorphism_group(algorithm="partition"); G # optional - sage.groups + sage: G = C.permutation_automorphism_group(algorithm="partition"); G Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] - sage: GG = C.permutation_automorphism_group(algorithm="codecan") # long time, optional - sage.groups - sage: GG == G # long time, optional - sage.groups + sage: GG = C.permutation_automorphism_group(algorithm="codecan") # long time + sage: GG == G # long time True - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_package_guava sage.groups + sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_package_guava Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] sage: C = codes.GolayCode(GF(3), True) - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_package_guava sage.groups + sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_package_guava Permutation Group with generators [(5,7)(6,11)(8,9)(10,12), (4,6,11)(5,8,12)(7,10,9), (3,4)(6,8)(9,11)(10,12), (2,3)(6,11)(8,12)(9,10), (1,2)(5,10)(7,12)(8,9)] @@ -1833,13 +1842,13 @@ def weight_distribution(self, algorithm=None): sage: F. = GF(2^2,"z") sage: C = codes.HammingCode(F, 2); C [5, 3] Hamming Code over GF(4) - sage: C.weight_distribution() + sage: C.weight_distribution() # needs sage.libs.gap [1, 0, 0, 30, 15, 18] sage: C = codes.HammingCode(GF(2), 3); C [7, 4] Hamming Code over GF(2) sage: C.weight_distribution(algorithm="leon") # optional - gap_package_guava [1, 0, 0, 7, 7, 0, 0, 1] - sage: C.weight_distribution(algorithm="gap") # optional - sage.libs.gap + sage: C.weight_distribution(algorithm="gap") # needs sage.libs.gap [1, 0, 0, 7, 7, 0, 0, 1] sage: C.weight_distribution(algorithm="binary") [1, 0, 0, 7, 7, 0, 0, 1] @@ -1999,7 +2008,7 @@ def zeta_polynomial(self, name="T"): EXAMPLES:: sage: C = codes.HammingCode(GF(2), 3) - sage: C.zeta_polynomial() + sage: C.zeta_polynomial() # needs sage.libs.gap 2/5*T^2 + 2/5*T + 1/5 sage: C = codes.databases.best_linear_code_in_guava(6, 3, GF(2)) # optional - gap_package_guava @@ -2009,14 +2018,14 @@ def zeta_polynomial(self, name="T"): 2/5*T^2 + 2/5*T + 1/5 sage: C = codes.HammingCode(GF(2), 4) - sage: C.zeta_polynomial() + sage: C.zeta_polynomial() # needs sage.libs.gap 16/429*T^6 + 16/143*T^5 + 80/429*T^4 + 32/143*T^3 + 30/143*T^2 + 2/13*T + 1/13 sage: F. = GF(4,"z") sage: MS = MatrixSpace(F, 3, 6) sage: G = MS([[1,0,0,1,z,z],[0,1,0,z,1,z],[0,0,1,z,z,1]]) sage: C = LinearCode(G) # the "hexacode" - sage: C.zeta_polynomial() + sage: C.zeta_polynomial() # needs sage.libs.gap 1 REFERENCES: @@ -2067,7 +2076,7 @@ def zeta_function(self, name="T"): EXAMPLES:: sage: C = codes.HammingCode(GF(2), 3) - sage: C.zeta_function() + sage: C.zeta_function() # needs sage.libs.gap (1/5*T^2 + 1/5*T + 1/10)/(T^2 - 3/2*T + 1/2) """ P = self.zeta_polynomial() @@ -2087,6 +2096,7 @@ def cosetGraph(self): EXAMPLES:: + sage: # needs sage.graphs sage: C = codes.GolayCode(GF(3)) sage: G = C.cosetGraph() sage: G.is_distance_regular() @@ -2105,6 +2115,7 @@ def cosetGraph(self): TESTS:: + sage: # needs sage.graphs sage: C = codes.KasamiCode(4,2) sage: C.cosetGraph() Hamming Graph with parameters 4,2: Graph on 16 vertices @@ -2232,7 +2243,7 @@ class LinearCode(AbstractLinearCode): 4 sage: C.length() 7 - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 3 sage: C.spectrum() [1, 0, 0, 7, 7, 0, 0, 1] @@ -2243,15 +2254,14 @@ class LinearCode(AbstractLinearCode): optional parameter.:: sage: C = LinearCode(G, d=3) - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 3 Another example.:: sage: MS = MatrixSpace(GF(5),4,7) sage: G = MS([[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: C + sage: C = LinearCode(G); C [7, 4] linear code over GF(5) Providing a code as the parameter in order to "forget" its structure (see @@ -2290,7 +2300,7 @@ def __init__(self, generator, d=None): optional parameter.:: sage: C = LinearCode(G, d=3) - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 3 TESTS:: @@ -2316,7 +2326,7 @@ def __init__(self, generator, d=None): (0, 1, 0, 0, a + 1, 0, 1), (0, 0, 1, a, a + 1, a, a + 1) ] - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 3 We can construct a linear code directly from a vector space:: @@ -2631,10 +2641,10 @@ class LinearCodeSyndromeDecoder(Decoder): And now, we build a third syndrome decoder, whose ``maximum_error_weight`` is bigger than both the covering radius and half the minimum distance:: - sage: D = C.decoder("Syndrome", maximum_error_weight=5) # long time - sage: D.decoder_type() # long time + sage: D = C.decoder("Syndrome", maximum_error_weight=5) # long time + sage: D.decoder_type() # long time {'complete', 'hard-decision', 'might-error'} - sage: D.decoding_radius() # long time + sage: D.decoding_radius() # long time 4 In that case, the decoder might still return an unexpected codeword, but @@ -2883,11 +2893,10 @@ def decode_to_code(self, r): EXAMPLES:: - sage: G = Matrix(GF(3),[ - ....: [1, 0, 0, 0, 2, 2, 1, 1], - ....: [0, 1, 0, 0, 0, 0, 1, 1], - ....: [0, 0, 1, 0, 2, 0, 0, 2], - ....: [0, 0, 0, 1, 0, 2, 0, 1]]) + sage: G = Matrix(GF(3), [[1, 0, 0, 0, 2, 2, 1, 1], + ....: [0, 1, 0, 0, 0, 0, 1, 1], + ....: [0, 0, 1, 0, 2, 0, 0, 2], + ....: [0, 0, 0, 1, 0, 2, 0, 1]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C, maximum_error_weight = 1) sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), 1) @@ -3073,7 +3082,7 @@ def decoding_radius(self): ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeNearestNeighborDecoder(C) - sage: D.decoding_radius() + sage: D.decoding_radius() # needs sage.libs.gap 1 """ return (self.code().minimum_distance()-1) // 2 diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index 95963d8a2a1..84caa850245 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Generic structures for linear codes of any metric @@ -900,6 +900,7 @@ def is_permutation_automorphism(self, g): EXAMPLES:: + sage: # needs sage.groups sage: C = codes.HammingCode(GF(3), 3) sage: g = SymmetricGroup(13).random_element() sage: C.is_permutation_automorphism(g) @@ -932,6 +933,7 @@ def permuted_code(self, p): EXAMPLES:: + sage: # needs sage.groups sage: C = codes.HammingCode(GF(2), 3) sage: G = C.permutation_automorphism_group(); G Permutation Group with generators diff --git a/src/sage/coding/linear_rank_metric.py b/src/sage/coding/linear_rank_metric.py index 6a7cd14cb62..9f592ddab57 100644 --- a/src/sage/coding/linear_rank_metric.py +++ b/src/sage/coding/linear_rank_metric.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Generic structures for linear codes over the rank metric diff --git a/src/sage/coding/parity_check_code.py b/src/sage/coding/parity_check_code.py index 0adafbbba57..73e7c9b7816 100644 --- a/src/sage/coding/parity_check_code.py +++ b/src/sage/coding/parity_check_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Parity-check code diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index 3caab922b1b..18e48887b85 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Punctured code diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 1d55ba6fa38..6e0fdd96175 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Reed-Muller code diff --git a/src/sage/coding/self_dual_codes.py b/src/sage/coding/self_dual_codes.py index d60d161d28d..f797a6b09d3 100644 --- a/src/sage/coding/self_dual_codes.py +++ b/src/sage/coding/self_dual_codes.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.groups sage.modules +# sage.doctest: needs sage.groups sage.modules r""" Enumerating binary self-dual codes diff --git a/src/sage/coding/source_coding/huffman.py b/src/sage/coding/source_coding/huffman.py index 1d41f84d77f..bb25e4cc47d 100644 --- a/src/sage/coding/source_coding/huffman.py +++ b/src/sage/coding/source_coding/huffman.py @@ -236,7 +236,7 @@ def __init__(self, source): Feeding anything else than a string or a dictionary:: - sage: Huffman(Graph()) # optional - sage.graphs + sage: Huffman(Graph()) # needs sage.graphs Traceback (most recent call last): ... ValueError: Input must be either a string or a dictionary. @@ -511,9 +511,9 @@ def tree(self): sage: from sage.coding.source_coding.huffman import Huffman sage: str = "Sage is my most favorite general purpose computer algebra system" sage: h = Huffman(str) - sage: T = h.tree(); T # optional - sage.graphs + sage: T = h.tree(); T # needs sage.graphs Digraph on 39 vertices - sage: T.show(figsize=[20,20]) # optional - sage.graphs sage.plot + sage: T.show(figsize=[20,20]) # needs sage.graphs sage.plot """ from sage.graphs.digraph import DiGraph @@ -544,8 +544,8 @@ def _generate_edges(self, tree, parent="", bit=""): sage: from sage.coding.source_coding.huffman import Huffman sage: H = Huffman("Sage") - sage: T = H.tree() # optional - sage.graphs - sage: T.edges(sort=True, labels=None) # indirect doctest # optional - sage.graphs + sage: T = H.tree() # needs sage.graphs + sage: T.edges(sort=True, labels=None) # indirect doctest # needs sage.graphs [('0', 'S: 00'), ('0', 'a: 01'), ('1', 'e: 10'), ('1', 'g: 11'), ('root', '0'), ('root', '1')] """ if parent == "": diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index c876ef73e63..19d4bf4a4d7 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Subfield subcode diff --git a/src/sage/coding/two_weight_db.py b/src/sage/coding/two_weight_db.py index 1ad3d584310..094c29a43c9 100644 --- a/src/sage/coding/two_weight_db.py +++ b/src/sage/coding/two_weight_db.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules sage.rings.finite_rings +# sage.doctest: needs sage.libs.gap sage.modules sage.rings.finite_rings r""" Database of two-weight codes From 8945dce87dcb804a76ee82b1a4e95fa641f637f5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 May 2024 18:40:55 -0700 Subject: [PATCH 2/7] src/sage/coding/databases.py: Make import of GapPackage method-local --- src/sage/coding/databases.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index fc814b1901b..b12cc3cbee3 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -2,7 +2,6 @@ r""" Access functions to online databases for coding theory """ -from sage.features.gap import GapPackage from sage.misc.lazy_import import lazy_import lazy_import('sage.libs.gap.libgap', 'libgap') @@ -52,6 +51,7 @@ def best_linear_code_in_guava(n, k, F): between 2 and 4. Use ``bounds_on_minimum_distance_in_guava(10,5,GF(2))`` for further details. """ + from sage.features.gap import GapPackage from .linear_code import LinearCode GapPackage("guava", spkg="gap_packages").require() libgap.load_package("guava") @@ -112,6 +112,7 @@ def bounds_on_minimum_distance_in_guava(n, k, F): upperBound := 4, upperBoundExplanation := ... ) """ + from sage.features.gap import GapPackage GapPackage("guava", spkg="gap_packages").require() libgap.load_package("guava") return libgap.BoundsMinimumDistance(n, k, F) From c2bcd6331648505d518c1dd010ecafe9bc84d297 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 May 2024 18:43:31 -0700 Subject: [PATCH 3/7] src/sage/coding/databases.py: Make import of libgap method-local --- src/sage/coding/databases.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index b12cc3cbee3..e8f31f5c536 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -4,8 +4,6 @@ """ from sage.misc.lazy_import import lazy_import -lazy_import('sage.libs.gap.libgap', 'libgap') - # Import the following function so that it is available as # sage.codes.databases.self_dual_binary_codes sage.codes.databases functions # somewhat like a catalog in this respect. @@ -54,6 +52,7 @@ def best_linear_code_in_guava(n, k, F): from sage.features.gap import GapPackage from .linear_code import LinearCode GapPackage("guava", spkg="gap_packages").require() + from sage.libs.gap.libgap import libgap libgap.load_package("guava") C = libgap.BestKnownLinearCode(n, k, F) return LinearCode(C.GeneratorMat()._matrix_(F)) @@ -114,6 +113,7 @@ def bounds_on_minimum_distance_in_guava(n, k, F): """ from sage.features.gap import GapPackage GapPackage("guava", spkg="gap_packages").require() + from sage.libs.gap.libgap import libgap libgap.load_package("guava") return libgap.BoundsMinimumDistance(n, k, F) From 3ff12549b92c5cd6c2b10066e52e7f9abbc568ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 May 2024 19:29:43 -0700 Subject: [PATCH 4/7] src/sage/coding/databases.py: Rewrite comments on imports --- src/sage/coding/databases.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index e8f31f5c536..a6a7e2204d0 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -5,14 +5,15 @@ from sage.misc.lazy_import import lazy_import # Import the following function so that it is available as -# sage.codes.databases.self_dual_binary_codes sage.codes.databases functions -# somewhat like a catalog in this respect. +# - sage.codes.databases.self_dual_binary_codes +# - codes.databases.self_dual_binary_codes (which functions as a catalog). lazy_import('sage.coding.self_dual_codes', 'self_dual_binary_codes') del lazy_import # Do not put any global imports here since this module is accessible as -# sage.codes.databases. +# - sage.codes.databases. +# - codes.databases. def best_linear_code_in_guava(n, k, F): From 71514a4b9922049b22dfd915704a35d93b18e35a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 May 2024 19:31:21 -0700 Subject: [PATCH 5/7] src/sage/coding/code_constructions.py: Use block # needs --- src/sage/coding/code_constructions.py | 40 ++++++++++++++------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index 94a8eddde95..211d01a37f9 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -227,47 +227,49 @@ def permutation_action(g, v): EXAMPLES:: + sage: # needs sage.groups sage: V = VectorSpace(GF(3),5) sage: v = V([0,1,2,0,1]) - sage: G = SymmetricGroup(5) # needs sage.groups - sage: g = G([(1,2,3)]) # needs sage.groups - sage: permutation_action(g,v) # needs sage.groups + sage: G = SymmetricGroup(5) + sage: g = G([(1,2,3)]) + sage: permutation_action(g,v) (1, 2, 0, 0, 1) - sage: g = G([()]) # needs sage.groups - sage: permutation_action(g,v) # needs sage.groups + sage: g = G([()]) + sage: permutation_action(g,v) (0, 1, 2, 0, 1) - sage: g = G([(1,2,3,4,5)]) # needs sage.groups - sage: permutation_action(g,v) # needs sage.groups + sage: g = G([(1,2,3,4,5)]) + sage: permutation_action(g,v) (1, 2, 0, 1, 0) sage: L = Sequence([1,2,3,4,5]) - sage: permutation_action(g,L) # needs sage.groups + sage: permutation_action(g,L) [2, 3, 4, 5, 1] sage: MS = MatrixSpace(GF(3),3,7) sage: A = MS([[1,0,0,0,1,1,0],[0,1,0,1,0,1,0],[0,0,0,0,0,0,1]]) - sage: S5 = SymmetricGroup(5) # needs sage.groups - sage: g = S5([(1,2,3)]) # needs sage.groups + sage: S5 = SymmetricGroup(5) + sage: g = S5([(1,2,3)]) sage: A [1 0 0 0 1 1 0] [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] - sage: permutation_action(g,A) # needs sage.groups + sage: permutation_action(g,A) [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] [1 0 0 0 1 1 0] It also works on lists and is a "left action":: + sage: # needs sage.groups sage: v = [0,1,2,0,1] - sage: G = SymmetricGroup(5) # needs sage.groups - sage: g = G([(1,2,3)]) # needs sage.groups - sage: gv = permutation_action(g,v); gv # needs sage.groups + sage: G = SymmetricGroup(5) + sage: g = G([(1,2,3)]) + sage: gv = permutation_action(g,v); gv [1, 2, 0, 0, 1] - sage: permutation_action(g,v) == g(v) # needs sage.groups + sage: permutation_action(g,v) == g(v) True - sage: h = G([(3,4)]) # needs sage.groups - sage: gv = permutation_action(g,v) # needs sage.groups - sage: hgv = permutation_action(h,gv) # needs sage.groups - sage: hgv == permutation_action(h*g,v) # needs sage.groups + sage: h = G([(3,4)]) + sage: gv = permutation_action(g,v) + sage: hgv = permutation_action(h,gv) + sage: hgv == permutation_action(h*g,v) True AUTHORS: From b5eb8ad46bbf761600ae29b3f83bfec1c9dcef14 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 May 2024 19:34:14 -0700 Subject: [PATCH 6/7] src/sage/coding/linear_code.py: Use block # needs --- src/sage/coding/linear_code.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index ec326b03281..16627f121ca 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -1144,18 +1144,20 @@ def construction_x(self, other, aux): [15, 7] BCH Code over GF(2) with designed distance 5 sage: C.is_subcode(D) True - sage: C.minimum_distance() # needs sage.libs.gap + + sage: # needs sage.libs.gap + sage: C.minimum_distance() 7 - sage: D.minimum_distance() # needs sage.libs.gap + sage: D.minimum_distance() 5 sage: aux = codes.HammingCode(GF(2),2) sage: aux = aux.dual_code() - sage: aux.minimum_distance() # needs sage.libs.gap + sage: aux.minimum_distance() 2 sage: Cx = D.construction_x(C,aux) sage: Cx [18, 7] linear code over GF(2) - sage: Cx.minimum_distance() # needs sage.libs.gap + sage: Cx.minimum_distance() 7 """ if not other.is_subcode(self): From 560b9292bac2941e7714f1dedbe30009af024038 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 May 2024 20:56:46 -0700 Subject: [PATCH 7/7] src/sage/coding/databases.py: Rewrite comments on imports (fixup) --- src/sage/coding/databases.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index a6a7e2204d0..f393ff2dcb0 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -5,14 +5,14 @@ from sage.misc.lazy_import import lazy_import # Import the following function so that it is available as -# - sage.codes.databases.self_dual_binary_codes +# - sage.coding.databases.self_dual_binary_codes # - codes.databases.self_dual_binary_codes (which functions as a catalog). lazy_import('sage.coding.self_dual_codes', 'self_dual_binary_codes') del lazy_import # Do not put any global imports here since this module is accessible as -# - sage.codes.databases. +# - sage.coding.databases. # - codes.databases.