diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 58e459532b6..e484070c4e8 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -4,7 +4,7 @@ This module gathers everything related to Balanced Incomplete Block Designs. One can build a BIBD (or check that it can be built) with :func:`balanced_incomplete_block_design`:: - sage: BIBD = designs.balanced_incomplete_block_design(7,3,1) + sage: BIBD = designs.balanced_incomplete_block_design(7,3,1) # needs sage.schemes In particular, Sage can build a `(v,k,1)`-BIBD when one exists for all `k\leq 5`. The following functions are available: @@ -75,12 +75,12 @@ def biplane(n, existence=False): - ``existence`` (boolean) -- instead of building the design, return: - - ``True`` -- meaning that Sage knows how to build the design + - ``True`` -- meaning that Sage knows how to build the design - - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + - ``Unknown`` -- meaning that Sage does not know how to build the + design, but that the design may exist (see :mod:`sage.misc.unknown`). - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist. .. SEEALSO:: @@ -88,21 +88,22 @@ def biplane(n, existence=False): EXAMPLES:: - sage: designs.biplane(4) # optional - sage.rings.finite_rings + sage: designs.biplane(4) # needs sage.rings.finite_rings (16,6,2)-Balanced Incomplete Block Design - sage: designs.biplane(7, existence=True) + sage: designs.biplane(7, existence=True) # needs sage.schemes True - sage: designs.biplane(11) + sage: designs.biplane(11) # needs sage.schemes (79,13,2)-Balanced Incomplete Block Design TESTS:: - sage: designs.biplane(9) + sage: designs.biplane(9) # needs sage.libs.gap (56,11,2)-Balanced Incomplete Block Design Check all known biplanes:: - sage: [n for n in [0,1,2,3,4,7,9,11] if designs.biplane(n, existence=True) is True] + sage: [n for n in [0,1,2,3,4,7,9,11] # needs sage.schemes + ....: if designs.biplane(n, existence=True) is True] [0, 1, 2, 3, 4, 7, 9, 11] """ k = n+2 @@ -153,9 +154,10 @@ def balanced_incomplete_block_design(v, k, lambd=1, existence=False, use_LJCR=Fa EXAMPLES:: - sage: designs.balanced_incomplete_block_design(7, 3, 1).blocks() + sage: designs.balanced_incomplete_block_design(7, 3, 1).blocks() # needs sage.schemes [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] - sage: B = designs.balanced_incomplete_block_design(66, 6, 1, use_LJCR=True) # optional - internet + sage: B = designs.balanced_incomplete_block_design(66, 6, 1, # optional - internet + ....: use_LJCR=True) sage: B # optional - internet (66,6,1)-Balanced Incomplete Block Design sage: B.blocks() # optional - internet @@ -169,11 +171,11 @@ def balanced_incomplete_block_design(v, k, lambd=1, existence=False, use_LJCR=Fa sage: designs.balanced_incomplete_block_design(85,5,existence=True) True - sage: _ = designs.balanced_incomplete_block_design(85,5) + sage: _ = designs.balanced_incomplete_block_design(85,5) # needs sage.libs.pari A BIBD from a Finite Projective Plane:: - sage: _ = designs.balanced_incomplete_block_design(21,5) + sage: _ = designs.balanced_incomplete_block_design(21,5) # needs sage.schemes Some trivial BIBD:: @@ -184,22 +186,23 @@ def balanced_incomplete_block_design(v, k, lambd=1, existence=False, use_LJCR=Fa Existence of BIBD with `k=3,4,5`:: - sage: [v for v in range(50) if designs.balanced_incomplete_block_design(v,3,existence=True)] + sage: [v for v in range(50) if designs.balanced_incomplete_block_design(v,3,existence=True)] # needs sage.schemes [1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49] - sage: [v for v in range(100) if designs.balanced_incomplete_block_design(v,4,existence=True)] + sage: [v for v in range(100) if designs.balanced_incomplete_block_design(v,4,existence=True)] # needs sage.schemes [1, 4, 13, 16, 25, 28, 37, 40, 49, 52, 61, 64, 73, 76, 85, 88, 97] - sage: [v for v in range(150) if designs.balanced_incomplete_block_design(v,5,existence=True)] + sage: [v for v in range(150) if designs.balanced_incomplete_block_design(v,5,existence=True)] # needs sage.schemes [1, 5, 21, 25, 41, 45, 61, 65, 81, 85, 101, 105, 121, 125, 141, 145] For `k > 5` there are currently very few constructions:: - sage: [v for v in range(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is True] + sage: [v for v in range(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is True] # needs sage.schemes [1, 6, 31, 66, 76, 91, 96, 106, 111, 121, 126, 136, 141, 151, 156, 171, 181, 186, 196, 201, 211, 241, 271] - sage: [v for v in range(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is Unknown] + sage: [v for v in range(300) if designs.balanced_incomplete_block_design(v,6,existence=True) is Unknown] # needs sage.schemes [51, 61, 81, 166, 216, 226, 231, 246, 256, 261, 276, 286, 291] Here are some constructions with `k \geq 7` and `v` a prime power:: + sage: # needs sage.libs.pari sage: designs.balanced_incomplete_block_design(169,7) (169,7,1)-Balanced Incomplete Block Design sage: designs.balanced_incomplete_block_design(617,8) @@ -218,22 +221,22 @@ def balanced_incomplete_block_design(v, k, lambd=1, existence=False, use_LJCR=Fa sage: designs.balanced_incomplete_block_design(176, 50, 14, existence=True) True - sage: designs.balanced_incomplete_block_design(64,28,12) + sage: designs.balanced_incomplete_block_design(64,28,12) # needs sage.libs.pari (64,28,12)-Balanced Incomplete Block Design - sage: designs.balanced_incomplete_block_design(37,9,8) + sage: designs.balanced_incomplete_block_design(37,9,8) # needs sage.libs.pari (37,9,8)-Balanced Incomplete Block Design - sage: designs.balanced_incomplete_block_design(15,7,3) + sage: designs.balanced_incomplete_block_design(15,7,3) # needs sage.schemes (15,7,3)-Balanced Incomplete Block Design Some BIBDs from the recursive construction :: - sage: designs.balanced_incomplete_block_design(76,16,4) + sage: designs.balanced_incomplete_block_design(76,16,4) # needs sage.libs.pari (76,16,4)-Balanced Incomplete Block Design - sage: designs.balanced_incomplete_block_design(10,4,2) + sage: designs.balanced_incomplete_block_design(10,4,2) # needs sage.libs.pari (10,4,2)-Balanced Incomplete Block Design - sage: designs.balanced_incomplete_block_design(50,25,24) + sage: designs.balanced_incomplete_block_design(50,25,24) # needs sage.schemes (50,25,24)-Balanced Incomplete Block Design - sage: designs.balanced_incomplete_block_design(29,15,15) + sage: designs.balanced_incomplete_block_design(29,15,15) # needs sage.libs.pari (29,15,15)-Balanced Incomplete Block Design """ # Trivial BIBD @@ -387,15 +390,15 @@ def BruckRyserChowla_check(v, k, lambd): Nonexistence of projective planes of order 6 and 14 sage: from sage.combinat.designs.bibd import BruckRyserChowla_check - sage: BruckRyserChowla_check(43,7,1) + sage: BruckRyserChowla_check(43,7,1) # needs sage.schemes False - sage: BruckRyserChowla_check(211,15,1) + sage: BruckRyserChowla_check(211,15,1) # needs sage.schemes False Existence of symmetric BIBDs with parameters `(79,13,2)` and `(56,11,2)` sage: from sage.combinat.designs.bibd import BruckRyserChowla_check - sage: BruckRyserChowla_check(79,13,2) + sage: BruckRyserChowla_check(79,13,2) # needs sage.schemes True sage: BruckRyserChowla_check(56,11,2) True @@ -413,7 +416,7 @@ def BruckRyserChowla_check(v, k, lambd): Clearly wrong parameters satisfying the theorem:: sage: from sage.combinat.designs.bibd import BruckRyserChowla_check - sage: BruckRyserChowla_check(13,25,50) + sage: BruckRyserChowla_check(13,25,50) # needs sage.schemes True """ @@ -569,23 +572,23 @@ def BIBD_from_TD(v,k,existence=False): First construction:: sage: from sage.combinat.designs.bibd import BIBD_from_TD - sage: BIBD_from_TD(25,5,existence=True) + sage: BIBD_from_TD(25,5,existence=True) # needs sage.schemes True - sage: _ = BlockDesign(25,BIBD_from_TD(25,5)) + sage: _ = BlockDesign(25,BIBD_from_TD(25,5)) # needs sage.schemes Second construction:: sage: from sage.combinat.designs.bibd import BIBD_from_TD - sage: BIBD_from_TD(21,5,existence=True) + sage: BIBD_from_TD(21,5,existence=True) # needs sage.schemes True - sage: _ = BlockDesign(21,BIBD_from_TD(21,5)) + sage: _ = BlockDesign(21,BIBD_from_TD(21,5)) # needs sage.schemes Third construction:: sage: from sage.combinat.designs.bibd import BIBD_from_TD - sage: BIBD_from_TD(85,5,existence=True) + sage: BIBD_from_TD(85,5,existence=True) # needs sage.schemes True - sage: _ = BlockDesign(85,BIBD_from_TD(85,5)) + sage: _ = BlockDesign(85,BIBD_from_TD(85,5)) # needs sage.schemes No idea:: @@ -866,8 +869,8 @@ def BIBD_from_PBD(PBD, v, k, check=True, base_cases=None): sage: from sage.combinat.designs.bibd import PBD_4_5_8_9_12 sage: from sage.combinat.designs.bibd import BIBD_from_PBD sage: from sage.combinat.designs.bibd import is_pairwise_balanced_design - sage: PBD = PBD_4_5_8_9_12(17) - sage: bibd = is_pairwise_balanced_design(BIBD_from_PBD(PBD,52,4),52,[4]) + sage: PBD = PBD_4_5_8_9_12(17) # needs sage.schemes + sage: bibd = is_pairwise_balanced_design(BIBD_from_PBD(PBD,52,4),52,[4]) # needs sage.schemes """ if base_cases is None: base_cases = {} @@ -904,11 +907,11 @@ def _relabel_bibd(B,n,p=None): - ``n`` (integer) -- number of points. - - ``p`` (optional) -- the point that will be labeled with n-1. + - ``p`` (optional) -- the point that will be labeled with `n-1`. EXAMPLES:: - sage: designs.balanced_incomplete_block_design(40,4).blocks() # indirect doctest + sage: designs.balanced_incomplete_block_design(40,4).blocks() # indirect doctest # needs sage.schemes [[0, 1, 2, 12], [0, 3, 6, 9], [0, 4, 8, 10], [0, 5, 7, 11], [0, 13, 26, 39], [0, 14, 25, 28], [0, 15, 27, 38], [0, 16, 22, 32], [0, 17, 23, 34], @@ -950,7 +953,7 @@ def PBD_4_5_8_9_12(v, check=True): EXAMPLES:: - sage: designs.balanced_incomplete_block_design(40,4).blocks() # indirect doctest + sage: designs.balanced_incomplete_block_design(40,4).blocks() # indirect doctest # needs sage.schemes [[0, 1, 2, 12], [0, 3, 6, 9], [0, 4, 8, 10], [0, 5, 7, 11], [0, 13, 26, 39], [0, 14, 25, 28], [0, 15, 27, 38], [0, 16, 22, 32], [0, 17, 23, 34], @@ -959,7 +962,7 @@ def PBD_4_5_8_9_12(v, check=True): Check that :trac:`16476` is fixed:: sage: from sage.combinat.designs.bibd import PBD_4_5_8_9_12 - sage: for v in (0,1,4,5,8,9,12,13,16,17,20,21,24,25): + sage: for v in (0,1,4,5,8,9,12,13,16,17,20,21,24,25): # needs sage.schemes ....: _ = PBD_4_5_8_9_12(v) """ if v % 4 not in [0, 1]: @@ -1029,7 +1032,7 @@ def _PBD_4_5_8_9_12_closure(B): EXAMPLES:: - sage: designs.balanced_incomplete_block_design(40,4).blocks() # indirect doctest + sage: designs.balanced_incomplete_block_design(40,4).blocks() # indirect doctest # needs sage.schemes [[0, 1, 2, 12], [0, 3, 6, 9], [0, 4, 8, 10], [0, 5, 7, 11], [0, 13, 26, 39], [0, 14, 25, 28], [0, 15, 27, 38], [0, 16, 22, 32], [0, 17, 23, 34], @@ -1121,7 +1124,7 @@ def v_5_1_BIBD(v, check=True): sage: from sage.combinat.designs.bibd import v_5_1_BIBD sage: i = 0 - sage: while i<200: + sage: while i<200: # needs sage.libs.pari ....: i += 20 ....: _ = v_5_1_BIBD(i+1) ....: _ = v_5_1_BIBD(i+5) @@ -1130,7 +1133,7 @@ def v_5_1_BIBD(v, check=True): Check that the needed difference families are there:: - sage: for v in [21,41,61,81,141,161,281]: + sage: for v in [21,41,61,81,141,161,281]: # needs sage.libs.pari ....: assert designs.difference_family(v,5,existence=True) ....: _ = designs.difference_family(v,5) """ @@ -1316,14 +1319,14 @@ def BIBD_from_arc_in_desarguesian_projective_plane(n,k,existence=False): sage: from sage.combinat.designs.bibd import BIBD_from_arc_in_desarguesian_projective_plane sage: from sage.combinat.designs.bibd import BalancedIncompleteBlockDesign - sage: D = BIBD_from_arc_in_desarguesian_projective_plane(232,8) # optional - sage.libs.gap sage.modules sage.rings.finite_rings - sage: BalancedIncompleteBlockDesign(232,D) # optional - sage.libs.gap sage.modules sage.rings.finite_rings + sage: D = BIBD_from_arc_in_desarguesian_projective_plane(232,8) # needs sage.libs.gap sage.modules sage.rings.finite_rings + sage: BalancedIncompleteBlockDesign(232,D) # needs sage.libs.gap sage.modules sage.rings.finite_rings (232,8,1)-Balanced Incomplete Block Design A `(120,8,1)`-BIBD:: - sage: D = BIBD_from_arc_in_desarguesian_projective_plane(120,8) # optional - sage.libs.gap sage.modules sage.rings.finite_rings - sage: BalancedIncompleteBlockDesign(120,D) # optional - sage.libs.gap sage.modules sage.rings.finite_rings + sage: D = BIBD_from_arc_in_desarguesian_projective_plane(120,8) # needs sage.libs.gap sage.modules sage.rings.finite_rings + sage: BalancedIncompleteBlockDesign(120,D) # needs sage.libs.gap sage.modules sage.rings.finite_rings (120,8,1)-Balanced Incomplete Block Design Other parameters:: @@ -1569,14 +1572,13 @@ def arc(self, s=2, solver=None, verbose=0, *, integrality_tolerance=1e-3): EXAMPLES:: + sage: # needs sage.schemes sage: B = designs.balanced_incomplete_block_design(21, 5) - sage: a2 = B.arc() - sage: a2 # random + sage: a2 = B.arc(); a2 # random [5, 9, 10, 12, 15, 20] sage: len(a2) 6 - sage: a4 = B.arc(4) - sage: a4 # random + sage: a4 = B.arc(4); a4 # random [0, 1, 2, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20] sage: len(a4) 16 @@ -1591,13 +1593,14 @@ def arc(self, s=2, solver=None, verbose=0, *, integrality_tolerance=1e-3): sage: 1 + r*3 16 - sage: B.trace(a2).is_t_design(2, return_parameters=True) + sage: B.trace(a2).is_t_design(2, return_parameters=True) # needs sage.schemes (True, (2, 6, 2, 1)) - sage: B.trace(a4).is_t_design(2, return_parameters=True) + sage: B.trace(a4).is_t_design(2, return_parameters=True) # needs sage.schemes (True, (2, 16, 4, 1)) Some other examples which are not maximal:: + sage: # needs sage.numerical.mip sage: B = designs.balanced_incomplete_block_design(25, 4) sage: a2 = B.arc(2) sage: r = (25-1)//(4-1) @@ -1609,6 +1612,7 @@ def arc(self, s=2, solver=None, verbose=0, *, integrality_tolerance=1e-3): sage: B.trace(a2).is_t_design(2) False + sage: # needs sage.numerical.mip sage: a3 = B.arc(3) sage: len(a3), 1 + 2*r (15, 17) @@ -1622,9 +1626,9 @@ def arc(self, s=2, solver=None, verbose=0, *, integrality_tolerance=1e-3): Test consistency with relabeling:: - sage: b = designs.balanced_incomplete_block_design(7,3) - sage: b.relabel(list("abcdefg")) - sage: set(b.arc()).issubset(b.ground_set()) + sage: b = designs.balanced_incomplete_block_design(7,3) # needs sage.schemes + sage: b.relabel(list("abcdefg")) # needs sage.schemes + sage: set(b.arc()).issubset(b.ground_set()) # needs sage.schemes True """ s = int(s) diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index 28f3746ad88..98774d77a42 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.rings.finite_rings +# sage.doctest: needs sage.rings.finite_rings r""" Block designs @@ -54,14 +54,17 @@ #***************************************************************************** from sage.arith.misc import binomial, integer_floor, is_prime_power from sage.categories.sets_cat import EmptySetError -from sage.modules.free_module import VectorSpace +from sage.misc.lazy_import import lazy_import +from sage.misc.unknown import Unknown from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ + from .incidence_structures import IncidenceStructure -from sage.rings.finite_rings.finite_field_constructor import FiniteField -from sage.misc.unknown import Unknown -from sage.matrix.matrix_space import MatrixSpace -from sage.libs.gap.libgap import libgap + +lazy_import('sage.libs.gap.libgap', 'libgap') +lazy_import('sage.matrix.matrix_space', 'MatrixSpace') +lazy_import('sage.modules.free_module', 'VectorSpace') +lazy_import('sage.rings.finite_rings.finite_field_constructor', 'FiniteField') BlockDesign = IncidenceStructure @@ -214,8 +217,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch The set of `d`-dimensional subspaces in a `n`-dimensional projective space forms `2`-designs (or balanced incomplete block designs):: - sage: PG = designs.ProjectiveGeometryDesign(4, 2, GF(2)) - sage: PG + sage: PG = designs.ProjectiveGeometryDesign(4, 2, GF(2)); PG Incidence structure with 31 points and 155 blocks sage: PG.is_t_design(return_parameters=True) (True, (2, 31, 7, 7)) @@ -226,8 +228,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch Check with ``F`` being a prime power:: - sage: PG = designs.ProjectiveGeometryDesign(3, 2, 4) - sage: PG + sage: PG = designs.ProjectiveGeometryDesign(3, 2, 4); PG Incidence structure with 85 points and 85 blocks Use coordinates:: @@ -900,10 +901,10 @@ def CremonaRichmondConfiguration(): EXAMPLES:: - sage: H = designs.CremonaRichmondConfiguration(); H # optional - networkx + sage: H = designs.CremonaRichmondConfiguration(); H # needs networkx Incidence structure with 15 points and 15 blocks - sage: g = graphs.TutteCoxeterGraph() # optional - networkx - sage: H.incidence_graph().is_isomorphic(g) # optional - networkx + sage: g = graphs.TutteCoxeterGraph() # needs networkx + sage: H.incidence_graph().is_isomorphic(g) # needs networkx True """ from sage.graphs.generators.smallgraphs import TutteCoxeterGraph @@ -956,16 +957,16 @@ def HadamardDesign(n): EXAMPLES:: - sage: designs.HadamardDesign(7) # optional - sage.modules + sage: designs.HadamardDesign(7) # needs sage.modules Incidence structure with 7 points and 7 blocks - sage: print(designs.HadamardDesign(7)) # optional - sage.modules + sage: print(designs.HadamardDesign(7)) # needs sage.modules Incidence structure with 7 points and 7 blocks For example, the Hadamard 2-design with `n = 11` is a design whose parameters are `2-(11, 5, 2)`. We verify that `NJ = 5J` for this design. :: - sage: D = designs.HadamardDesign(11); N = D.incidence_matrix() # optional - sage.modules - sage: J = matrix(ZZ, 11, 11, [1]*11*11); N*J # optional - sage.modules + sage: D = designs.HadamardDesign(11); N = D.incidence_matrix() # needs sage.modules + sage: J = matrix(ZZ, 11, 11, [1]*11*11); N*J # needs sage.modules [5 5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5 5] @@ -1009,7 +1010,7 @@ def Hadamard3Design(n): EXAMPLES:: - sage: designs.Hadamard3Design(12) # optional - sage.modules + sage: designs.Hadamard3Design(12) # needs sage.modules Incidence structure with 12 points and 22 blocks We verify that any two blocks of the Hadamard `3`-design `3-(8, 4, 1)` @@ -1019,9 +1020,9 @@ def Hadamard3Design(n): :: - sage: D = designs.Hadamard3Design(8) # optional - sage.modules - sage: N = D.incidence_matrix() # optional - sage.modules - sage: N.transpose()*N # optional - sage.modules + sage: D = designs.Hadamard3Design(8) # needs sage.modules + sage: N = D.incidence_matrix() # needs sage.modules + sage: N.transpose()*N # needs sage.modules [4 2 2 2 2 2 2 2 2 2 2 2 2 0] [2 4 2 2 2 2 2 2 2 2 2 2 0 2] [2 2 4 2 2 2 2 2 2 2 2 0 2 2] diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 0bb4d88a0fa..3e095e619ee 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -81,7 +81,7 @@ def _MOLS_from_string(s,k): EXAMPLES:: - sage: _ = designs.mutually_orthogonal_latin_squares(2,10) # indirect doctest # optional - sage.modules + sage: _ = designs.mutually_orthogonal_latin_squares(2,10) # indirect doctest # needs sage.modules """ from sage.matrix.constructor import Matrix matrices = [[] for _ in range(k)] @@ -101,13 +101,13 @@ def MOLS_10_2(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_10_2 - sage: MOLS = MOLS_10_2() # optional - sage.modules - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules + sage: MOLS = MOLS_10_2() # needs sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # needs sage.modules True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(2,10) # optional - sage.modules + sage: designs.orthogonal_arrays.is_available(2,10) True """ from sage.matrix.constructor import Matrix @@ -143,8 +143,8 @@ def MOLS_12_5(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_12_5 - sage: MOLS = MOLS_12_5() # optional - sage.modules - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules + sage: MOLS = MOLS_12_5() # needs sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # needs sage.modules True """ M = """ @@ -175,13 +175,13 @@ def MOLS_14_4(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_14_4 - sage: MOLS = MOLS_14_4() # optional - sage.modules - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules + sage: MOLS = MOLS_14_4() # needs sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # needs sage.modules True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(4,14) + sage: designs.orthogonal_arrays.is_available(4,14) # needs sage.schemes True REFERENCE: @@ -219,13 +219,13 @@ def MOLS_15_4(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_15_4 - sage: MOLS = MOLS_15_4() # optional - sage.modules - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules + sage: MOLS = MOLS_15_4() # needs sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # needs sage.modules True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(4,15) + sage: designs.orthogonal_arrays.is_available(4,15) # needs sage.schemes True """ M = """ @@ -258,8 +258,8 @@ def MOLS_18_3(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_18_3 - sage: MOLS = MOLS_18_3() # optional - sage.modules - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules + sage: MOLS = MOLS_18_3() # needs sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # needs sage.modules True The design is available from the general constructor:: @@ -328,7 +328,7 @@ def OA_7_18(): The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(7,18) + sage: designs.orthogonal_arrays.is_available(7,18) # needs sage.schemes True """ M = """ @@ -377,13 +377,13 @@ def OA_9_40(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_9_40 - sage: OA = OA_9_40() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,9,40,2) # optional - sage.rings.finite_rings + sage: OA = OA_9_40() # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,9,40,2) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(9,40) + sage: designs.orthogonal_arrays.is_available(9,40) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -416,13 +416,13 @@ def OA_7_66(): sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: from sage.combinat.designs.database import OA_7_66 - sage: OA = OA_7_66() - sage: is_orthogonal_array(OA,7,66,2) + sage: OA = OA_7_66() # needs sage.schemes + sage: is_orthogonal_array(OA,7,66,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(7,66) + sage: designs.orthogonal_arrays.is_available(7,66) # needs sage.schemes True """ @@ -456,13 +456,13 @@ def OA_7_68(): sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: from sage.combinat.designs.database import OA_7_68 - sage: OA = OA_7_68() - sage: is_orthogonal_array(OA,7,68,2) + sage: OA = OA_7_68() # needs sage.schemes + sage: is_orthogonal_array(OA,7,68,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(7,68) + sage: designs.orthogonal_arrays.is_available(7,68) # needs sage.schemes True """ @@ -496,13 +496,13 @@ def OA_8_69(): sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: from sage.combinat.designs.database import OA_8_69 - sage: OA = OA_8_69() - sage: is_orthogonal_array(OA,8,69,2) + sage: OA = OA_8_69() # needs sage.schemes + sage: is_orthogonal_array(OA,8,69,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(8,69) + sage: designs.orthogonal_arrays.is_available(8,69) # needs sage.schemes True """ # base block of a (73,9,1) BIBD @@ -568,13 +568,13 @@ def OA_7_74(): sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: from sage.combinat.designs.database import OA_7_74 - sage: OA = OA_7_74() - sage: is_orthogonal_array(OA,7,74,2) + sage: OA = OA_7_74() # needs sage.schemes + sage: is_orthogonal_array(OA,7,74,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(7,74) + sage: designs.orthogonal_arrays.is_available(7,74) # needs sage.schemes True """ @@ -608,13 +608,13 @@ def OA_8_76(): sage: from sage.combinat.designs.orthogonal_arrays import is_orthogonal_array sage: from sage.combinat.designs.database import OA_8_76 - sage: OA = OA_8_76() - sage: is_orthogonal_array(OA,8,76,2) + sage: OA = OA_8_76() # needs sage.schemes + sage: is_orthogonal_array(OA,8,76,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(8,76) + sage: designs.orthogonal_arrays.is_available(8,76) # needs sage.schemes True """ # base block of a (91,10,1) BIBD @@ -676,13 +676,13 @@ def OA_11_80(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_80 - sage: OA = OA_11_80() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,11,80,2) # optional - sage.rings.finite_rings + sage: OA = OA_11_80() # needs sage.rings.finite_rings sage.schemes + sage: is_orthogonal_array(OA,11,80,2) # needs sage.rings.finite_rings sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(11,80) + sage: designs.orthogonal_arrays.is_available(11,80) # needs sage.rings.finite_rings sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -718,13 +718,13 @@ def OA_15_112(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_15_112 - sage: OA = OA_15_112() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,15,112,2) # optional - sage.rings.finite_rings + sage: OA = OA_15_112() # needs sage.rings.finite_rings sage.schemes + sage: is_orthogonal_array(OA,15,112,2) # needs sage.rings.finite_rings sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(15,112) + sage: designs.orthogonal_arrays.is_available(15,112) # needs sage.rings.finite_rings sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -768,13 +768,13 @@ def OA_9_120(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_9_120 - sage: OA = OA_9_120() # optional - sage.modules - sage: is_orthogonal_array(OA,9,120,2) # optional - sage.modules + sage: OA = OA_9_120() # needs sage.modules sage.schemes + sage: is_orthogonal_array(OA,9,120,2) # needs sage.modules sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(9,120) + sage: designs.orthogonal_arrays.is_available(9,120) # needs sage.schemes True """ RBIBD_120 = RBIBD_120_8_1() @@ -816,20 +816,19 @@ def OA_9_135(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_9_135 - sage: OA = OA_9_135() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,9,135,2) # optional - sage.rings.finite_rings + sage: OA = OA_9_135() # needs sage.rings.finite_rings sage.schemes + sage: is_orthogonal_array(OA,9,135,2) # needs sage.rings.finite_rings sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(9,135) + sage: designs.orthogonal_arrays.is_available(9,135) # needs sage.schemes True As this orthogonal array requires a `(273,17,1)` cyclic difference set, we check that it is available:: - sage: G,D = designs.difference_family(273,17,1) - sage: G + sage: G,D = designs.difference_family(273,17,1); G # needs sage.libs.pari Ring of integers modulo 273 """ from .bibd import BIBD_from_difference_family @@ -896,13 +895,13 @@ def OA_11_160(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_160 - sage: OA = OA_11_160() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,11,160,2) # optional - sage.rings.finite_rings + sage: OA = OA_11_160() # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,11,160,2) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(11,160) + sage: designs.orthogonal_arrays.is_available(11,160) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -939,13 +938,13 @@ def OA_16_176(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_16_176 - sage: OA = OA_16_176() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,16,176,2) # optional - sage.rings.finite_rings + sage: OA = OA_16_176() # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,16,176,2) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(16,176) + sage: designs.orthogonal_arrays.is_available(16,176) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -998,13 +997,13 @@ def OA_11_185(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_185 - sage: OA = OA_11_185() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,11,185,2) # optional - sage.rings.finite_rings + sage: OA = OA_11_185() # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,11,185,2) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(11,185) + sage: designs.orthogonal_arrays.is_available(11,185) # needs sage.schemes True """ @@ -1074,13 +1073,13 @@ def OA_10_205(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_10_205 - sage: OA = OA_10_205() - sage: is_orthogonal_array(OA,10,205,2) + sage: OA = OA_10_205() # needs sage.schemes + sage: is_orthogonal_array(OA,10,205,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(10,205) + sage: designs.orthogonal_arrays.is_available(10,205) # needs sage.schemes True """ # Base block of a cyclic PG(2,4^2) @@ -1138,13 +1137,13 @@ def OA_16_208(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_16_208 - sage: OA = OA_16_208() # not tested -- too long # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,16,208,2) # not tested -- too long # optional - sage.rings.finite_rings + sage: OA = OA_16_208() # not tested (too long) # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,16,208,2) # not tested (too long) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(16,208) + sage: designs.orthogonal_arrays.is_available(16,208) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1197,13 +1196,13 @@ def OA_15_224(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_15_224 - sage: OA = OA_15_224() # not tested -- too long # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,15,224,2) # not tested -- too long # optional - sage.rings.finite_rings + sage: OA = OA_15_224() # not tested (too long) # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,15,224,2) # not tested (too long) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(15,224) + sage: designs.orthogonal_arrays.is_available(15,224) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1248,13 +1247,13 @@ def OA_11_254(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_254 - sage: OA = OA_11_254() - sage: is_orthogonal_array(OA,11,254,2) + sage: OA = OA_11_254() # needs sage.schemes + sage: is_orthogonal_array(OA,11,254,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(11,254) + sage: designs.orthogonal_arrays.is_available(11,254) # needs sage.schemes True """ @@ -1283,13 +1282,13 @@ def OA_20_352(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_20_352 - sage: OA = OA_20_352() # not tested (~25s) # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,20,352,2) # not tested (~25s) # optional - sage.rings.finite_rings + sage: OA = OA_20_352() # not tested (~25s) # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,20,352,2) # not tested (~25s) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(20,352) + sage: designs.orthogonal_arrays.is_available(20,352) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1342,13 +1341,13 @@ def OA_20_416(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_20_416 - sage: OA = OA_20_416() # not tested (~35s) # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,20,416,2) # not tested # optional - sage.rings.finite_rings + sage: OA = OA_20_416() # not tested (~35s) # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,20,416,2) # not tested # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(20,416) + sage: designs.orthogonal_arrays.is_available(20,416) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1402,13 +1401,13 @@ def OA_20_544(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_20_544 - sage: OA = OA_20_544() # not tested (too long ~1mn) # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,20,544,2) # not tested # optional - sage.rings.finite_rings + sage: OA = OA_20_544() # not tested (too long ~1mn) # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,20,544,2) # not tested # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(20,544) + sage: designs.orthogonal_arrays.is_available(20,544) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1466,13 +1465,13 @@ def OA_17_560(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_17_560 - sage: OA = OA_17_560() # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,17,560,2) # optional - sage.rings.finite_rings + sage: OA = OA_17_560() # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,17,560,2) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(17,560) + sage: designs.orthogonal_arrays.is_available(17,560) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF @@ -1530,13 +1529,13 @@ def OA_11_640(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_640 - sage: OA = OA_11_640() # not tested (too long) # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,11,640,2) # not tested (too long) # optional - sage.rings.finite_rings + sage: OA = OA_11_640() # not tested (too long) # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,11,640,2) # not tested (too long) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(11,640) + sage: designs.orthogonal_arrays.is_available(11,640) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1580,13 +1579,13 @@ def OA_10_796(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_10_796 - sage: OA = OA_10_796() - sage: is_orthogonal_array(OA,10,796,2) + sage: OA = OA_10_796() # needs sage.schemes + sage: is_orthogonal_array(OA,10,796,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(10,796) + sage: designs.orthogonal_arrays.is_available(10,796) # needs sage.schemes True """ from sage.combinat.designs.orthogonal_arrays import OA_relabel @@ -1658,13 +1657,13 @@ def OA_10_469(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_10_469 - sage: OA = OA_10_469() # long time - sage: is_orthogonal_array(OA,10,469,2) # long time + sage: OA = OA_10_469() # long time # needs sage.schemes + sage: is_orthogonal_array(OA,10,469,2) # long time # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(10,469) + sage: designs.orthogonal_arrays.is_available(10,469) # needs sage.schemes True """ from .orthogonal_arrays_build_recursive import _reorder_matrix @@ -1787,13 +1786,13 @@ def OA_10_520(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_10_520 - sage: OA = OA_10_520() - sage: is_orthogonal_array(OA,10,520,2) + sage: OA = OA_10_520() # needs sage.schemes + sage: is_orthogonal_array(OA,10,520,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(10,520) + sage: designs.orthogonal_arrays.is_available(10,520) # needs sage.schemes True """ return OA_520_plus_x(0) @@ -1809,13 +1808,13 @@ def OA_12_522(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_12_522 - sage: OA = OA_12_522() - sage: is_orthogonal_array(OA,12,522,2) + sage: OA = OA_12_522() # needs sage.schemes + sage: is_orthogonal_array(OA,12,522,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(12,522) + sage: designs.orthogonal_arrays.is_available(12,522) # needs sage.schemes True """ return OA_520_plus_x(2) @@ -1831,13 +1830,13 @@ def OA_14_524(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_14_524 - sage: OA = OA_14_524() - sage: is_orthogonal_array(OA,14,524,2) + sage: OA = OA_14_524() # needs sage.schemes + sage: is_orthogonal_array(OA,14,524,2) # needs sage.schemes True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(14,524) + sage: designs.orthogonal_arrays.is_available(14,524) # needs sage.schemes True """ return OA_520_plus_x(4) @@ -1857,13 +1856,13 @@ def OA_15_896(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_15_896 - sage: OA = OA_15_896() # not tested -- too long (~2min) # optional - sage.rings.finite_rings - sage: is_orthogonal_array(OA,15,896,2) # not tested -- too long # optional - sage.rings.finite_rings + sage: OA = OA_15_896() # not tested (too long, ~2min) # needs sage.rings.finite_rings + sage: is_orthogonal_array(OA,15,896,2) # not tested (too long) # needs sage.rings.finite_rings True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(15,896) + sage: designs.orthogonal_arrays.is_available(15,896) # needs sage.schemes True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1914,7 +1913,7 @@ def OA_9_1078(): The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(9,1078) + sage: designs.orthogonal_arrays.is_available(9,1078) # needs sage.schemes True """ return wilson_construction(None,9,11,89,[[(11,9)]]) @@ -1940,7 +1939,7 @@ def OA_25_1262(): The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(25,1262) + sage: designs.orthogonal_arrays.is_available(25,1262) # needs sage.schemes True """ @@ -1981,7 +1980,7 @@ def OA_9_1612(): The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(9,1612) + sage: designs.orthogonal_arrays.is_available(9,1612) # needs sage.schemes True """ return wilson_construction(None,9,17,89,[[(11,9)]]) @@ -2011,7 +2010,7 @@ def OA_10_1620(): The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(10,1620) + sage: designs.orthogonal_arrays.is_available(10,1620) # needs sage.schemes True """ return wilson_construction(None,10,11,144,[[(9,4)]]) @@ -2194,8 +2193,8 @@ def QDM_25_6_1_1_5(): sage: from sage.combinat.designs.database import QDM_25_6_1_1_5 sage: from sage.combinat.designs.designs_pyx import is_quasi_difference_matrix - sage: G,M = QDM_25_6_1_1_5() # optional - sage.modules - sage: is_quasi_difference_matrix(M,G,6,1,1,5) # optional - sage.modules + sage: G,M = QDM_25_6_1_1_5() # needs sage.modules + sage: is_quasi_difference_matrix(M,G,6,1,1,5) # needs sage.modules True """ M = [ @@ -2431,8 +2430,8 @@ def QDM_57_9_1_1_8(): sage: from sage.combinat.designs.database import QDM_57_9_1_1_8 sage: from sage.combinat.designs.designs_pyx import is_quasi_difference_matrix - sage: G,M = QDM_57_9_1_1_8() - sage: is_quasi_difference_matrix(M,G,9,1,1,8) + sage: G,M = QDM_57_9_1_1_8() # needs sage.schemes + sage: is_quasi_difference_matrix(M,G,9,1,1,8) # needs sage.schemes True """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as G @@ -2718,7 +2717,7 @@ def QDM_57_9_1_1_8(): sage: from sage.combinat.designs.designs_pyx import is_quasi_difference_matrix sage: from sage.combinat.designs.orthogonal_arrays import QDM_from_Vmt sage: from sage.combinat.designs.database import Vmt_vectors - sage: for (m,t),(vec,source) in sorted(Vmt_vectors.items()): # optional - sage.rings.finite_rings + sage: for (m,t),(vec,source) in sorted(Vmt_vectors.items()): # needs sage.rings.finite_rings ....: G,M = QDM_from_Vmt(m,t,vec) ....: if m*t < 600: ....: assert is_quasi_difference_matrix(M,G,m+2,1,1,t,verbose=1),(m,t) @@ -3147,7 +3146,7 @@ def DM_12_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(12,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(12,6) REFERENCES: @@ -3189,7 +3188,7 @@ def DM_21_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(21,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(21,6) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic M = [[ 8, 17, 20, 2], @@ -3224,7 +3223,7 @@ def DM_24_8_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(24,8) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(24,8) """ M = ("0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "+ "0000 0010 0100 0110 1000 1010 1100 1110 2000 2010 2100 2110 "+ @@ -3265,13 +3264,13 @@ def DM_28_6_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_28_6_1 - sage: G,M = DM_28_6_1() # optional - sage.modules - sage: is_difference_matrix(M,G,6,1) # optional - sage.modules + sage: G,M = DM_28_6_1() # needs sage.modules + sage: is_difference_matrix(M,G,6,1) # needs sage.modules True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(28,6) # optional - sage.modules + sage: _ = designs.difference_matrix(28,6) # needs sage.modules """ z=2 M = [ @@ -3314,7 +3313,7 @@ def DM_33_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(33,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(33,6) # needs sage.rings.finite_rings """ M = [ [ 0, 0, 0, 0, 0, 0], @@ -3356,7 +3355,7 @@ def DM_35_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(35,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(35,6) # needs sage.rings.finite_rings """ M = [ [ 0, 15, 30, 10, 25, 1, 16, 31, 11, 26, 2, 17, 32, 12, 6, 3, 18, 33, 27, 21, 4, 19, 13, 7, 22, 5, 34, 28, 8, 23, 20, 14, 29, 9, 24], @@ -3382,13 +3381,13 @@ def DM_36_9_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_36_9_1 - sage: G,M = DM_36_9_1() # optional - sage.modules - sage: is_difference_matrix(M,G,9,1) # optional - sage.modules + sage: G,M = DM_36_9_1() # needs sage.modules + sage: is_difference_matrix(M,G,9,1) # needs sage.modules True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(36,9) # optional - sage.modules + sage: _ = designs.difference_matrix(36,9) # needs sage.modules """ M = [ [(0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0)], @@ -3441,7 +3440,7 @@ def DM_39_6_1(): The design is available from the general constructor:: - sage: designs.difference_matrix(39,6,existence=True) # optional - sage.rings.finite_rings + sage: designs.difference_matrix(39,6,existence=True) # needs sage.rings.finite_rings True """ M = [ @@ -3485,7 +3484,7 @@ def DM_44_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(44,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(44,6) """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic from sage.categories.cartesian_product import cartesian_product @@ -3541,13 +3540,13 @@ def DM_45_7_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_45_7_1 - sage: G,M = DM_45_7_1() # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,G,7,1) # optional - sage.rings.finite_rings + sage: G,M = DM_45_7_1() + sage: is_difference_matrix(M,G,7,1) True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(45,7) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(45,7) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField from sage.categories.cartesian_product import cartesian_product @@ -3594,13 +3593,13 @@ def DM_48_9_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_48_9_1 - sage: G,M = DM_48_9_1() # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,G,9,1) # optional - sage.rings.finite_rings + sage: G,M = DM_48_9_1() # needs sage.rings.finite_rings + sage: is_difference_matrix(M,G,9,1) # needs sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(48,9) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(48,9) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField F16 = FiniteField(16,'x') @@ -3649,7 +3648,7 @@ def DM_51_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(51,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(51,6) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic G = AdditiveCyclic(51) @@ -3685,13 +3684,13 @@ def DM_52_6_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_52_6_1 - sage: G,M = DM_52_6_1() # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,G,6,1) # optional - sage.rings.finite_rings + sage: G,M = DM_52_6_1() # needs sage.rings.finite_rings + sage: is_difference_matrix(M,G,6,1) # needs sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(52,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(52,6) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField F4 = FiniteField(4,'z') @@ -3763,7 +3762,7 @@ def DM_55_7_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(55,7) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(55,7) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic G = AdditiveCyclic(55) @@ -3796,13 +3795,13 @@ def DM_56_8_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_56_8_1 - sage: G,M = DM_56_8_1() # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,G,8,1) # optional - sage.rings.finite_rings + sage: G,M = DM_56_8_1() # needs sage.rings.finite_rings + sage: is_difference_matrix(M,G,8,1) # needs sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(56,8) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(56,8) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField F8 = FiniteField(8,'z') @@ -3843,13 +3842,13 @@ def DM_57_8_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_57_8_1 - sage: G,M = DM_57_8_1() # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,G,8,1) # optional - sage.rings.finite_rings + sage: G,M = DM_57_8_1() # needs sage.rings.finite_rings + sage: is_difference_matrix(M,G,8,1) # needs sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(57,8) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(57,8) # needs sage.rings.finite_rings """ M = orthogonal_array(8,8) M = [R for R in M if any(x!=R[0] for x in R)] # removing the 0..0, 1..1, 7..7 rows. @@ -3887,7 +3886,7 @@ def DM_60_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(60,6) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(60,6) """ M60 = [[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)], [(1, 10), (1, 6), (0, 17), (0, 7), (1, 5), (0, 9), (0, 3), (1, 13), (1, 17), (0, 13)], @@ -3923,13 +3922,13 @@ def DM_75_8_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_75_8_1 - sage: G,M = DM_75_8_1() # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,G,8,1) # optional - sage.rings.finite_rings + sage: G,M = DM_75_8_1() + sage: is_difference_matrix(M,G,8,1) True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(75,8) # optional - sage.rings.finite_rings + sage: _ = designs.difference_matrix(75,8) # needs sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField from sage.categories.cartesian_product import cartesian_product @@ -3971,13 +3970,13 @@ def DM_273_17_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_273_17_1 - sage: G,M = DM_273_17_1() - sage: is_difference_matrix(M,G,17,1) + sage: G,M = DM_273_17_1() # needs sage.schemes + sage: is_difference_matrix(M,G,17,1) # needs sage.schemes True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(273,17) + sage: _ = designs.difference_matrix(273,17) # needs sage.schemes """ M = orthogonal_array(17,17) M = [R for R in M if any(x!=R[0] for x in R)] # removing the 0..0, 1..1, ... rows. @@ -3999,13 +3998,13 @@ def DM_993_32_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_993_32_1 - sage: G,M = DM_993_32_1() - sage: is_difference_matrix(M,G,32,1) + sage: G,M = DM_993_32_1() # needs sage.schemes + sage: is_difference_matrix(M,G,32,1) # needs sage.schemes True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(993,32) + sage: _ = designs.difference_matrix(993,32) # needs sage.schemes """ M = orthogonal_array(32,32) M = [R for R in M if any(x!=R[0] for x in R)] # removing the 0..0, 1..1, ... rows. @@ -4080,19 +4079,19 @@ def RBIBD_120_8_1(): sage: from sage.combinat.designs.database import RBIBD_120_8_1 sage: from sage.combinat.designs.bibd import is_pairwise_balanced_design - sage: RBIBD = RBIBD_120_8_1() # optional - sage.modules - sage: is_pairwise_balanced_design(RBIBD,120,[8]) # optional - sage.modules + sage: RBIBD = RBIBD_120_8_1() # needs sage.modules + sage: is_pairwise_balanced_design(RBIBD,120,[8]) # needs sage.modules True It is indeed resolvable, and the parallel classes are given by 17 slices of consecutive 15 blocks:: - sage: for i in range(17): # optional - sage.modules + sage: for i in range(17): # needs sage.modules ....: assert len(set(sum(RBIBD[i*15:(i+1)*15],[]))) == 120 The BIBD is available from the constructor:: - sage: _ = designs.balanced_incomplete_block_design(120,8) # optional - sage.modules + sage: _ = designs.balanced_incomplete_block_design(120,8) # needs sage.modules """ from .incidence_structures import IncidenceStructure n=273 @@ -4148,15 +4147,15 @@ def BIBD_45_9_8(from_code=False): sage: from sage.combinat.designs.database import BIBD_45_9_8 sage: from sage.combinat.designs.bibd import BalancedIncompleteBlockDesign - sage: B = BalancedIncompleteBlockDesign(45, BIBD_45_9_8(), lambd=8); B # optional - sage.rings.finite_rings + sage: B = BalancedIncompleteBlockDesign(45, BIBD_45_9_8(), lambd=8); B (45,9,8)-Balanced Incomplete Block Design TESTS: From the definition (takes around 12s):: - sage: B2 = Hypergraph(BIBD_45_9_8(from_code=True)) # not tested # optional - sage.rings.finite_rings - sage: B2.is_isomorphic(B) # not tested # optional - sage.rings.finite_rings + sage: B2 = Hypergraph(BIBD_45_9_8(from_code=True)) # not tested # needs sage.rings.finite_rings + sage: B2.is_isomorphic(B) # not tested # needs sage.rings.finite_rings True REFERENCE: @@ -4580,8 +4579,8 @@ def BIBD_79_13_2(): EXAMPLES: sage: from sage.combinat.designs.database import BIBD_79_13_2 - sage: D = IncidenceStructure(BIBD_79_13_2()) # optional - sage.libs.gap - sage: D.is_t_design(t=2, v=79, k=13, l=2) # optional - sage.libs.gap + sage: D = IncidenceStructure(BIBD_79_13_2()) # needs sage.libs.gap + sage: D.is_t_design(t=2, v=79, k=13, l=2) # needs sage.libs.gap True """ from sage.libs.gap.libgap import libgap @@ -4658,8 +4657,8 @@ def BIBD_56_11_2(): EXAMPLES: sage: from sage.combinat.designs.database import BIBD_56_11_2 - sage: D = IncidenceStructure(BIBD_56_11_2()) # optional - sage.libs.gap - sage: D.is_t_design(t=2, v=56, k=11, l=2) # optional - sage.libs.gap + sage: D = IncidenceStructure(BIBD_56_11_2()) # needs sage.libs.gap + sage: D.is_t_design(t=2, v=56, k=11, l=2) # needs sage.libs.gap True """ from sage.libs.gap.libgap import libgap diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index be8745f2acb..565b7d83184 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -36,6 +36,7 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O EXAMPLES:: + sage: # needs sage.schemes sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: OA = designs.orthogonal_arrays.build(8,9) sage: is_orthogonal_array(OA,8,9) @@ -48,26 +49,27 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O sage: is_orthogonal_array(OA,8,9,verbose=True) Columns 0 and 3 are not orthogonal False - sage: is_orthogonal_array(OA,8,9,verbose=True,terminology="MOLS") + sage: is_orthogonal_array(OA,8,9, verbose=True, terminology="MOLS") Squares 0 and 3 are not orthogonal False TESTS:: - sage: is_orthogonal_array(OA,8,9,t=3) + sage: # needs sage.schemes + sage: is_orthogonal_array(OA,8,9, t=3) Traceback (most recent call last): ... NotImplementedError: only implemented for t=2 - sage: is_orthogonal_array([[3]*8],8,9,verbose=True) + sage: is_orthogonal_array([[3]*8],8,9, verbose=True) The number of rows is 1 instead of 9^2=81 False - sage: is_orthogonal_array([[3]*8],8,9,verbose=True,terminology="MOLS") + sage: is_orthogonal_array([[3]*8],8,9, verbose=True, terminology="MOLS") All squares do not have dimension n^2=9^2 False - sage: is_orthogonal_array([[3]*7],8,9,verbose=True) + sage: is_orthogonal_array([[3]*7],8,9, verbose=True) Some row does not have length 8 False - sage: is_orthogonal_array([[3]*7],8,9,verbose=True,terminology="MOLS") + sage: is_orthogonal_array([[3]*7],8,9, verbose=True, terminology="MOLS") The number of squares is not 6 False @@ -77,7 +79,7 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology="O sage: from itertools import product sage: n = 0 - sage: for a in product(product((0,1), repeat=3), repeat=4): + sage: for a in product(product((0,1), repeat=3), repeat=4): # needs sage.schemes ....: if is_orthogonal_array(a,3,2): ....: n += 1 sage: n @@ -183,16 +185,16 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals EXAMPLES:: sage: from sage.combinat.designs.designs_pyx import is_group_divisible_design - sage: TD = designs.transversal_design(4,10) # optional - sage.modules - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.modules - sage: is_group_divisible_design(groups,TD,40,lambd=1) # optional - sage.modules + sage: TD = designs.transversal_design(4,10) # needs sage.modules + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] + sage: is_group_divisible_design(groups,TD,40,lambd=1) # needs sage.modules True TESTS:: - sage: TD = designs.transversal_design(4,10) # optional - sage.modules - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.modules - sage: is_group_divisible_design(groups, TD, 40, lambd=2, verbose=True) # optional - sage.modules + sage: TD = designs.transversal_design(4,10) # needs sage.modules + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] + sage: is_group_divisible_design(groups, TD, 40, lambd=2, verbose=True) # needs sage.modules the pair (0,10) has been seen 1 times but lambda=2 False sage: is_group_divisible_design([[1,2],[3,4]],[[1,2]],40,lambd=1,verbose=True) @@ -214,6 +216,7 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals a block has size 2 while K=[1] False + sage: # needs sage.schemes sage: p = designs.projective_plane(3) sage: is_group_divisible_design(None, p.blocks(), 13) (True, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]]) @@ -362,24 +365,24 @@ def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False): sage: sts = designs.steiner_triple_system(9) sage: is_pairwise_balanced_design(sts,9,[3],1) True - sage: TD = designs.transversal_design(4,10).blocks() # optional - sage.modules - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.modules - sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 1, verbose=True) # optional - sage.modules + sage: TD = designs.transversal_design(4,10).blocks() # needs sage.modules + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] + sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 1, verbose=True) # needs sage.modules True TESTS:: sage: from sage.combinat.designs.designs_pyx import is_pairwise_balanced_design - sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 2, verbose=True) # optional - sage.modules + sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 2, verbose=True) # needs sage.modules the pair (0,1) has been seen 1 times but lambda=2 False - sage: is_pairwise_balanced_design(TD + groups, 40, [10], 1, verbose=True) # optional - sage.modules + sage: is_pairwise_balanced_design(TD + groups, 40, [10], 1, verbose=True) # needs sage.modules a block has size 4 while K=[10] False - sage: is_pairwise_balanced_design([[2,2]],40,[2],1,verbose=True) + sage: is_pairwise_balanced_design([[2,2]], 40, [2], 1, verbose=True) The following block has repeated elements: [2, 2] False - sage: is_pairwise_balanced_design([["e",2]],40,[2],1,verbose=True) + sage: is_pairwise_balanced_design([["e",2]], 40, [2], 1, verbose=True) e does not belong to [0,...,39] False """ @@ -415,11 +418,12 @@ def is_projective_plane(blocks, verbose=False): EXAMPLES:: sage: from sage.combinat.designs.designs_pyx import is_projective_plane - sage: p = designs.projective_plane(4) - sage: b = p.blocks() - sage: is_projective_plane(b, verbose=True) + sage: p = designs.projective_plane(4) # needs sage.schemes + sage: b = p.blocks() # needs sage.schemes + sage: is_projective_plane(b, verbose=True) # needs sage.schemes True + sage: # needs sage.schemes sage: p = designs.projective_plane(2) sage: b = p.blocks() sage: is_projective_plane(b) @@ -437,6 +441,7 @@ def is_projective_plane(blocks, verbose=False): First block has less than 3 points. False + sage: # needs sage.schemes sage: p = designs.projective_plane(2) sage: b = p.blocks() sage: b[2].append(4) @@ -486,38 +491,39 @@ def is_difference_matrix(M,G,k,lmbda=1,verbose=False): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: q = 3**3 - sage: F = GF(q,'x') # optional - sage.rings.finite_rings - sage: M = [[x*y for y in F] for x in F] # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings + sage: F = GF(q,'x') # needs sage.rings.finite_rings + sage: M = [[x*y for y in F] for x in F] # needs sage.rings.finite_rings + sage: is_difference_matrix(M,F,q,verbose=1) # needs sage.rings.finite_rings True sage: B = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ....: [0, 1, 2, 3, 4, 2, 3, 4, 0, 1], ....: [0, 2, 4, 1, 3, 3, 0, 2, 4, 1]] - sage: G = GF(5) # optional - sage.rings.finite_rings - sage: B = [[G(b) for b in R] for R in B] # optional - sage.rings.finite_rings - sage: is_difference_matrix(list(zip(*B)),G,3,2) # optional - sage.rings.finite_rings + sage: G = GF(5) + sage: B = [[G(b) for b in R] for R in B] + sage: is_difference_matrix(list(zip(*B)),G,3,2) True Bad input:: - sage: for R in M: R.append(None) # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: for R in M: R.append(None) + sage: is_difference_matrix(M,F,q,verbose=1) The matrix has 28 columns but k=27 False - sage: for R in M: _=R.pop(-1) # optional - sage.rings.finite_rings - sage: M.append([None]*3**3) # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings + sage: for R in M: _=R.pop(-1) + sage: M.append([None]*3**3) + sage: is_difference_matrix(M,F,q,verbose=1) The matrix has 28 rows instead of lambda(|G|-1+2u)+mu=1(27-1+2.0)+1=27 False - sage: _= M.pop(-1) # optional - sage.rings.finite_rings - sage: for R in M: R[-1] = 0 # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings + sage: _= M.pop(-1) + sage: for R in M: R[-1] = 0 + sage: is_difference_matrix(M,F,q,verbose=1) Columns 0 and 26 generate 0 exactly 27 times instead of the expected mu(=1) False - sage: for R in M: R[-1] = 1 # optional - sage.rings.finite_rings - sage: M[-1][-1] = 0 # optional - sage.rings.finite_rings - sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings + sage: for R in M: R[-1] = 1 + sage: M[-1][-1] = 0 + sage: is_difference_matrix(M,F,q,verbose=1) Columns 0 and 26 do not generate all elements of G exactly lambda(=1) times. The element x appeared 0 times as a difference. False @@ -560,17 +566,17 @@ def is_quasi_difference_matrix(M,G,int k,int lmbda,int mu,int u,verbose=False): sage: from sage.combinat.designs.designs_pyx import is_quasi_difference_matrix sage: q = 3**3 - sage: F = GF(q,'x') # optional - sage.rings.finite_rings - sage: M = [[x*y for y in F] for x in F] # optional - sage.rings.finite_rings - sage: is_quasi_difference_matrix(M,F,q,1,1,0,verbose=1) # optional - sage.rings.finite_rings + sage: F = GF(q,'x') # needs sage.rings.finite_rings + sage: M = [[x*y for y in F] for x in F] # needs sage.rings.finite_rings + sage: is_quasi_difference_matrix(M,F,q,1,1,0,verbose=1) # needs sage.rings.finite_rings True sage: B = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ....: [0, 1, 2, 3, 4, 2, 3, 4, 0, 1], ....: [0, 2, 4, 1, 3, 3, 0, 2, 4, 1]] - sage: G = GF(5) # optional - sage.rings.finite_rings - sage: B = [[G(b) for b in R] for R in B] # optional - sage.rings.finite_rings - sage: is_quasi_difference_matrix(list(zip(*B)),G,3,2,2,0) # optional - sage.rings.finite_rings + sage: G = GF(5) + sage: B = [[G(b) for b in R] for R in B] + sage: is_quasi_difference_matrix(list(zip(*B)),G,3,2,2,0) True A quasi-difference matrix from the database:: diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index 080439ce6bc..382240627ab 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -5,7 +5,7 @@ This module gathers everything related to difference families. One can build a difference family (or check that it can be built) with :func:`difference_family`:: - sage: G,F = designs.difference_family(13,4,1) # optional - sage.modules + sage: G,F = designs.difference_family(13,4,1) # needs sage.libs.pari sage.modules It defines the following functions: @@ -70,9 +70,9 @@ def group_law(G): sage: from sage.combinat.designs.difference_family import group_law sage: group_law(Zmod(3)) (0, , ) - sage: group_law(SymmetricGroup(5)) # optional - sage.groups + sage: group_law(SymmetricGroup(5)) # needs sage.groups ((), , ) - sage: group_law(VectorSpace(QQ, 3)) # optional - sage.modules + sage: group_law(VectorSpace(QQ, 3)) # needs sage.modules ((0, 0, 0), , ) """ import operator @@ -176,13 +176,14 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): sage: is_difference_family(G, D) True - sage: G = AdditiveAbelianGroup([3]*4) # optional - sage.modules - sage: a,b,c,d = G.gens() # optional - sage.modules - sage: D = [[d, -a+d, -c+d, a-b-d, b+c+d], # optional - sage.modules + sage: # needs sage.modules + sage: G = AdditiveAbelianGroup([3]*4) + sage: a,b,c,d = G.gens() + sage: D = [[d, -a+d, -c+d, a-b-d, b+c+d], ....: [c, a+b-d, -b+c, a-b+d, a+b+c], ....: [-a-b+c+d, a-b-c-d, -a+c-d, b-c+d, a+b], ....: [-b-d, a+b+d, a-b+c-d, a-b+c, -b+c+d]] - sage: is_difference_family(G, D) # optional - sage.modules + sage: is_difference_family(G, D) True The following example has a third block with a non-trivial stabilizer:: @@ -195,23 +196,25 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): The function also supports multiplicative groups (non necessarily Abelian):: - sage: G = DihedralGroup(8) # optional - sage.groups - sage: x,y = G.gens() # optional - sage.groups - sage: i = G.one() # optional - sage.groups - sage: D1 = [[i,x,x^4], [i,x^2, y*x], [i,x^5,y], [i,x^6,y*x^2], [i,x^7,y*x^5]] # optional - sage.groups - sage: is_difference_family(G, D1, 16, 3, 2) # optional - sage.groups + sage: # needs sage.groups + sage: G = DihedralGroup(8) + sage: x,y = G.gens() + sage: i = G.one() + sage: D1 = [[i,x,x^4], [i,x^2, y*x], [i,x^5,y], [i,x^6,y*x^2], [i,x^7,y*x^5]] + sage: is_difference_family(G, D1, 16, 3, 2) True sage: from sage.combinat.designs.bibd import BIBD_from_difference_family - sage: bibd = BIBD_from_difference_family(G, D1, lambd=2) # optional - sage.groups + sage: bibd = BIBD_from_difference_family(G, D1, lambd=2) TESTS:: - sage: K = GF(3^2,'z') # optional - sage.rings.finite_rings - sage: z = K.gen() # optional - sage.rings.finite_rings - sage: D = [[1,z+1,2]] # optional - sage.rings.finite_rings - sage: _ = is_difference_family(K, D, verbose=True) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K = GF(3^2,'z') + sage: z = K.gen() + sage: D = [[1,z+1,2]] + sage: _ = is_difference_family(K, D, verbose=True) the number of differences (=6) must be a multiple of v-1=8 - sage: _ # optional - sage.rings.finite_rings + sage: _ False """ identity, mul, inv = group_law(G) @@ -353,23 +356,23 @@ def singer_difference_set(q,d): EXAMPLES:: sage: from sage.combinat.designs.difference_family import singer_difference_set, is_difference_family - sage: G,D = singer_difference_set(3,2) # optional - sage.rings.finite_rings - sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings + sage: G,D = singer_difference_set(3,2) # needs sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # needs sage.rings.finite_rings It is a (13,4,1)-difference family True - sage: G,D = singer_difference_set(4,2) # optional - sage.rings.finite_rings - sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings + sage: G,D = singer_difference_set(4,2) # needs sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # needs sage.rings.finite_rings It is a (21,5,1)-difference family True - sage: G,D = singer_difference_set(3,3) # optional - sage.rings.finite_rings - sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings + sage: G,D = singer_difference_set(3,3) # needs sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # needs sage.rings.finite_rings It is a (40,13,4)-difference family True - sage: G,D = singer_difference_set(9,3) # optional - sage.rings.finite_rings - sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings + sage: G,D = singer_difference_set(9,3) # needs sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # needs sage.rings.finite_rings It is a (820,91,10)-difference family True """ @@ -417,13 +420,14 @@ def df_q_6_1(K, existence=False, check=True): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.combinat.designs.difference_family import is_difference_family, df_q_6_1 - sage: prime_powers = [v for v in range(31,500,30) if is_prime_power(v)] # optional - sage.rings.finite_rings - sage: parameters = [v for v in prime_powers # optional - sage.rings.finite_rings + sage: prime_powers = [v for v in range(31,500,30) if is_prime_power(v)] + sage: parameters = [v for v in prime_powers ....: if df_q_6_1(GF(v,'a'), existence=True) is True] - sage: parameters # optional - sage.rings.finite_rings + sage: parameters [31, 151, 181, 211, 241, 271, 331, 361, 421] - sage: for v in parameters: # optional - sage.rings.finite_rings + sage: for v in parameters: ....: K = GF(v, 'a') ....: df = df_q_6_1(K, check=True) ....: assert is_difference_family(K, df, v, 6, 1) @@ -479,13 +483,13 @@ def radical_difference_set(K, k, l=1, existence=False, check=True): sage: from sage.combinat.designs.difference_family import radical_difference_set - sage: D = radical_difference_set(GF(7), 3, 1); D # optional - sage.rings.finite_rings + sage: D = radical_difference_set(GF(7), 3, 1); D # needs sage.rings.finite_rings [[1, 2, 4]] - sage: sorted(x-y for x in D[0] for y in D[0] if x != y) # optional - sage.rings.finite_rings + sage: sorted(x-y for x in D[0] for y in D[0] if x != y) # needs sage.rings.finite_rings [1, 2, 3, 4, 5, 6] - sage: D = radical_difference_set(GF(16,'a'), 6, 2) # optional - sage.rings.finite_rings - sage: sorted(x-y for x in D[0] for y in D[0] if x != y) # optional - sage.rings.finite_rings + sage: D = radical_difference_set(GF(16,'a'), 6, 2) # needs sage.rings.finite_rings + sage: sorted(x-y for x in D[0] for y in D[0] if x != y) # needs sage.rings.finite_rings [1, 1, a, @@ -498,7 +502,7 @@ def radical_difference_set(K, k, l=1, existence=False, check=True): a^3 + a^2 + a + 1, a^3 + a^2 + a + 1] - sage: for k in range(2,50): # optional - sage.rings.finite_rings + sage: for k in range(2,50): # needs sage.rings.finite_rings ....: for l in reversed(divisors(k*(k-1))): ....: v = k*(k-1)//l + 1 ....: if is_prime_power(v) and radical_difference_set(GF(v,'a'),k,l,existence=True) is True: @@ -757,12 +761,12 @@ def one_radical_difference_family(K, k): ....: one_radical_difference_family, ....: is_difference_family) - sage: one_radical_difference_family(GF(13),4) # optional - sage.rings.finite_rings + sage: one_radical_difference_family(GF(13),4) # needs sage.rings.finite_rings [[0, 1, 3, 9]] The parameters that appear in [Bu95]_:: - sage: df = one_radical_difference_family(GF(449), 8); df # optional - sage.rings.finite_rings + sage: df = one_radical_difference_family(GF(449), 8); df # needs sage.rings.finite_rings [[0, 1, 18, 25, 176, 324, 359, 444], [0, 9, 88, 162, 222, 225, 237, 404], [0, 11, 140, 198, 275, 357, 394, 421], @@ -771,7 +775,7 @@ def one_radical_difference_family(K, k): [0, 70, 99, 197, 230, 362, 403, 435], [0, 121, 141, 193, 293, 331, 335, 382], [0, 191, 285, 295, 321, 371, 390, 392]] - sage: is_difference_family(GF(449), df, 449, 8, 1) # optional - sage.rings.finite_rings + sage: is_difference_family(GF(449), df, 449, 8, 1) # needs sage.rings.finite_rings True """ q = K.cardinality() @@ -843,10 +847,10 @@ def radical_difference_family(K, k, l=1, existence=False, check=True): sage: from sage.combinat.designs.difference_family import radical_difference_family - sage: radical_difference_family(GF(73), 9) # optional - sage.rings.finite_rings + sage: radical_difference_family(GF(73), 9) # needs sage.rings.finite_rings [[1, 2, 4, 8, 16, 32, 37, 55, 64]] - sage: radical_difference_family(GF(281), 5) # optional - sage.rings.finite_rings + sage: radical_difference_family(GF(281), 5) # needs sage.rings.finite_rings [[1, 86, 90, 153, 232], [4, 50, 63, 79, 85], [5, 36, 149, 169, 203], @@ -862,7 +866,7 @@ def radical_difference_family(K, k, l=1, existence=False, check=True): [111, 123, 155, 181, 273], [156, 209, 224, 264, 271]] - sage: for k in range(5,10): # optional - sage.rings.finite_rings + sage: for k in range(5,10): # needs sage.rings.finite_rings ....: print("k = {}".format(k)) ....: list_q = [] ....: for q in range(k*(k-1)+1, 2000, k*(k-1)): @@ -946,10 +950,10 @@ def twin_prime_powers_difference_set(p, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import twin_prime_powers_difference_set - sage: G, D = twin_prime_powers_difference_set(3) # optional - sage.rings.finite_rings - sage: G # optional - sage.rings.finite_rings + sage: G, D = twin_prime_powers_difference_set(3) + sage: G The Cartesian product of (Finite Field of size 3, Finite Field of size 5) - sage: D # optional - sage.rings.finite_rings + sage: D [[(1, 1), (1, 4), (2, 2), (2, 3), (0, 0), (1, 0), (2, 0)]] """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -997,20 +1001,21 @@ def are_mcfarland_1973_parameters(v, k, lmbda, return_parameters=False): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.combinat.designs.difference_family import are_mcfarland_1973_parameters - sage: are_mcfarland_1973_parameters(64, 28, 12) # optional - sage.rings.finite_rings + sage: are_mcfarland_1973_parameters(64, 28, 12) True - sage: are_mcfarland_1973_parameters(64, 28, 12, return_parameters=True) # optional - sage.rings.finite_rings + sage: are_mcfarland_1973_parameters(64, 28, 12, return_parameters=True) (True, (2, 2)) - sage: are_mcfarland_1973_parameters(60, 13, 5) # optional - sage.rings.finite_rings + sage: are_mcfarland_1973_parameters(60, 13, 5) False - sage: are_mcfarland_1973_parameters(98125, 19500, 3875) # optional - sage.rings.finite_rings + sage: are_mcfarland_1973_parameters(98125, 19500, 3875) True - sage: are_mcfarland_1973_parameters(98125, 19500, 3875, True) # optional - sage.rings.finite_rings + sage: are_mcfarland_1973_parameters(98125, 19500, 3875, True) (True, (5, 3)) sage: from sage.combinat.designs.difference_family import are_mcfarland_1973_parameters - sage: for v in range(1, 100): # optional - sage.rings.finite_rings + sage: for v in range(1, 100): # needs sage.rings.finite_rings ....: for k in range(1,30): ....: for l in range(1,15): ....: if are_mcfarland_1973_parameters(v,k,l): @@ -1088,11 +1093,11 @@ def mcfarland_1973_construction(q, s): sage: from sage.combinat.designs.difference_family import ( ....: mcfarland_1973_construction, is_difference_family) - sage: G,D = mcfarland_1973_construction(3, 1) # optional - sage.modules sage.rings.finite_rings - sage: assert is_difference_family(G, D, 45, 12, 3) # optional - sage.modules sage.rings.finite_rings + sage: G,D = mcfarland_1973_construction(3, 1) # needs sage.modules + sage: assert is_difference_family(G, D, 45, 12, 3) # needs sage.modules - sage: G,D = mcfarland_1973_construction(2, 2) # optional - sage.modules sage.rings.finite_rings - sage: assert is_difference_family(G, D, 64, 28, 12) # optional - sage.modules sage.rings.finite_rings + sage: G,D = mcfarland_1973_construction(2, 2) # needs sage.modules + sage: assert is_difference_family(G, D, 64, 28, 12) # needs sage.modules """ from sage.rings.finite_rings.finite_field_constructor import GF from sage.modules.free_module import VectorSpace @@ -1151,7 +1156,7 @@ def hadamard_difference_set_product_parameters(N): EXAMPLES:: sage: from sage.combinat.designs.difference_family import hadamard_difference_set_product_parameters - sage: hadamard_difference_set_product_parameters(8) # optional - sage.rings.finite_rings + sage: hadamard_difference_set_product_parameters(8) # needs sage.rings.finite_rings (2, 2) """ if N % 2: @@ -1191,16 +1196,16 @@ def hadamard_difference_set_product(G1, D1, G2, D2): sage: from sage.combinat.designs.difference_family import hadamard_difference_set_product sage: from sage.combinat.designs.difference_family import is_difference_family - sage: G1,D1 = designs.difference_family(16,6,2) # optional - sage.rings.finite_rings - sage: G2,D2 = designs.difference_family(36,15,6) # optional - sage.rings.finite_rings + sage: G1,D1 = designs.difference_family(16,6,2) # needs sage.rings.finite_rings + sage: G2,D2 = designs.difference_family(36,15,6) # needs sage.rings.finite_rings - sage: G11,D11 = hadamard_difference_set_product(G1,D1,G1,D1) # optional - sage.rings.finite_rings - sage: assert is_difference_family(G11, D11, 256, 120, 56) # optional - sage.rings.finite_rings - sage: assert designs.difference_family(256, 120, 56, existence=True) is True # optional - sage.rings.finite_rings + sage: G11,D11 = hadamard_difference_set_product(G1,D1,G1,D1) # needs sage.rings.finite_rings + sage: assert is_difference_family(G11, D11, 256, 120, 56) # needs sage.rings.finite_rings + sage: assert designs.difference_family(256, 120, 56, existence=True) is True # needs sage.rings.finite_rings - sage: G12,D12 = hadamard_difference_set_product(G1,D1,G2,D2) # optional - sage.rings.finite_rings - sage: assert is_difference_family(G12, D12, 576, 276, 132) # optional - sage.rings.finite_rings - sage: assert designs.difference_family(576, 276, 132, existence=True) is True # optional - sage.rings.finite_rings + sage: G12,D12 = hadamard_difference_set_product(G1,D1,G2,D2) # needs sage.rings.finite_rings + sage: assert is_difference_family(G12, D12, 576, 276, 132) # needs sage.rings.finite_rings + sage: assert designs.difference_family(576, 276, 132, existence=True) is True # needs sage.rings.finite_rings """ from sage.categories.cartesian_product import cartesian_product @@ -1317,11 +1322,11 @@ def _create_m_sequence(q, n, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import _create_m_sequence - sage: _create_m_sequence(3, 2) # random # optional - sage.rings.finite_rings + sage: _create_m_sequence(3, 2) # random # needs sage.rings.finite_rings [1, 0, 1, 2, 2, 0, 2, 1] - sage: _create_m_sequence(4, 2, check=False) # random # optional - sage.rings.finite_rings + sage: _create_m_sequence(4, 2, check=False) # random # needs sage.rings.finite_rings [1, 0, a, a + 1, a, a, 0, a + 1, 1, a + 1, a + 1, 0, 1, a, 1] - sage: _create_m_sequence(6, 2) # optional - sage.rings.finite_rings + sage: _create_m_sequence(6, 2) Traceback (most recent call last): ... ValueError: q must be a prime power @@ -1371,12 +1376,13 @@ def _get_submodule_of_order(G, order): TESTS: + sage: # needs sage.modules sage: from sage.combinat.designs.difference_family import _get_submodule_of_order - sage: G = AdditiveAbelianGroup([48]) # optional - sage.modules - sage: _get_submodule_of_order(G, 6).order() # optional - sage.modules + sage: G = AdditiveAbelianGroup([48]) + sage: _get_submodule_of_order(G, 6).order() 6 - sage: G = AdditiveAbelianGroup([13^2 - 1]) # optional - sage.modules - sage: _get_submodule_of_order(G, 12).order() # optional - sage.modules + sage: G = AdditiveAbelianGroup([13^2 - 1]) + sage: _get_submodule_of_order(G, 12).order() 12 """ for el in G: @@ -1410,13 +1416,13 @@ def relative_difference_set_from_m_sequence(q, N, check=True, return_group=False EXAMPLES:: sage: from sage.combinat.designs.difference_family import relative_difference_set_from_m_sequence - sage: relative_difference_set_from_m_sequence(2, 4, # random # optional - sage.modules sage.rings.finite_rings + sage: relative_difference_set_from_m_sequence(2, 4, # random # needs sage.modules sage.rings.finite_rings ....: return_group=True) (Additive abelian group isomorphic to Z/15, [(0), (4), (5), (6), (7), (9), (11), (12)]) - sage: relative_difference_set_from_m_sequence(8, 2, check=False) # random # optional - sage.modules sage.rings.finite_rings + sage: relative_difference_set_from_m_sequence(8, 2, check=False) # random # needs sage.modules sage.rings.finite_rings [(0), (6), (30), (40), (41), (44), (56), (61)] - sage: relative_difference_set_from_m_sequence(6, 2) # optional - sage.modules sage.rings.finite_rings + sage: relative_difference_set_from_m_sequence(6, 2) # needs sage.modules Traceback (most recent call last): ... ValueError: q must be a prime power @@ -1425,17 +1431,17 @@ def relative_difference_set_from_m_sequence(q, N, check=True, return_group=False sage: from sage.combinat.designs.difference_family import is_relative_difference_set, _get_submodule_of_order sage: q, N = 5, 3 - sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, # optional - sage.modules sage.rings.finite_rings + sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, # needs sage.modules sage.rings.finite_rings ....: return_group=True) - sage: H = _get_submodule_of_order(G, q-1) # optional - sage.modules sage.rings.finite_rings - sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + sage: H = _get_submodule_of_order(G, q-1) # needs sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # needs sage.modules sage.rings.finite_rings ....: ((q^N-1)//(q-1), q-1, q^(N-1), q^(N-2))) True sage: q, N = 13, 2 - sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, # optional - sage.modules sage.rings.finite_rings + sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, # needs sage.modules sage.rings.finite_rings ....: return_group=True) - sage: H = _get_submodule_of_order(G, q-1) # optional - sage.modules sage.rings.finite_rings - sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + sage: H = _get_submodule_of_order(G, q-1) # needs sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # needs sage.modules sage.rings.finite_rings ....: ((q^N-1)//(q-1), q-1, q^(N-1), q^(N-2))) True """ @@ -1485,12 +1491,13 @@ def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group= EXAMPLES:: sage: from sage.combinat.designs.difference_family import relative_difference_set_from_homomorphism - sage: relative_difference_set_from_homomorphism(7, 2, 3) #random + sage: relative_difference_set_from_homomorphism(7, 2, 3) # random # needs sage.modules sage.rings.finite_rings [(0), (3), (4), (2), (13), (7), (14)] - sage: relative_difference_set_from_homomorphism(9, 2, 4, check=False, return_group=True) #random + sage: relative_difference_set_from_homomorphism(9, 2, 4, # random # needs sage.modules sage.rings.finite_rings + ....: check=False, return_group=True) (Additive abelian group isomorphic to Z/80, [(0), (4), (6), (13), (7), (12), (15), (8), (9)]) - sage: relative_difference_set_from_homomorphism(9, 2, 5) # optional - sage.modules sage.rings.finite_rings + sage: relative_difference_set_from_homomorphism(9, 2, 5) # needs sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q-1 must be a multiple of d @@ -1499,17 +1506,17 @@ def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group= sage: from sage.combinat.designs.difference_family import is_relative_difference_set, _get_submodule_of_order sage: q, N, d = 11, 2, 5 - sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, # optional - sage.modules sage.rings.finite_rings + sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, # needs sage.modules sage.rings.finite_rings ....: return_group=True) - sage: H = _get_submodule_of_order(G, (q-1)//d) # optional - sage.modules sage.rings.finite_rings - sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + sage: H = _get_submodule_of_order(G, (q-1)//d) # needs sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # needs sage.modules sage.rings.finite_rings ....: ((q**N-1)//(q-1), (q-1)//d, q**(N-1), q**(N-2)*d)) True sage: q, N, d = 9, 2, 4 - sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, # optional - sage.modules sage.rings.finite_rings + sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, # needs sage.modules sage.rings.finite_rings ....: return_group=True) - sage: H = _get_submodule_of_order(G, (q-1)//d) # optional - sage.modules sage.rings.finite_rings - sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + sage: H = _get_submodule_of_order(G, (q-1)//d) # needs sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # needs sage.modules sage.rings.finite_rings ....: ((q**N-1)//(q-1), (q-1)//d, q**(N-1), q**(N-2)*d)) True """ @@ -1540,6 +1547,7 @@ def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group= return G2, second_diff_set return second_diff_set + def is_relative_difference_set(R, G, H, params, verbose=False): r""" Check if ``R`` is a difference set of ``G`` relative to ``H``, with the given parameters. @@ -1563,15 +1571,15 @@ def is_relative_difference_set(R, G, H, params, verbose=False): sage: from sage.combinat.designs.difference_family import _get_submodule_of_order, relative_difference_set_from_m_sequence, is_relative_difference_set sage: q, N = 5, 2 sage: params = ((q^N-1) // (q-1), q - 1, q^(N-1), q^(N-2)) - sage: G, R = relative_difference_set_from_m_sequence(q, N, return_group=True) # optional - sage.modules - sage: H = _get_submodule_of_order(G, q - 1) # optional - sage.modules - sage: is_relative_difference_set(R, G, H, params) # optional - sage.modules + sage: G, R = relative_difference_set_from_m_sequence(q, N, return_group=True) # needs sage.libs.pari sage.modules + sage: H = _get_submodule_of_order(G, q - 1) # needs sage.libs.pari sage.modules + sage: is_relative_difference_set(R, G, H, params) # needs sage.libs.pari sage.modules True If we pass the ``verbose`` argument, the function will explain why it failed:: - sage: R2 = [G[1], G[2], G[3], G[5], G[6]] # optional - sage.modules - sage: is_relative_difference_set(R2, G, H, params, verbose=True) # optional - sage.modules + sage: R2 = [G[1], G[2], G[3], G[5], G[6]] # needs sage.libs.pari sage.modules + sage: is_relative_difference_set(R2, G, H, params, verbose=True) # needs sage.libs.pari sage.modules There is a value in the difference set which is not repeated d times False """ @@ -1641,33 +1649,34 @@ def is_supplementary_difference_set(Ks, v=None, lmbda=None, G=None, verbose=Fals EXAMPLES:: sage: from sage.combinat.designs.difference_family import supplementary_difference_set_from_rel_diff_set, is_supplementary_difference_set - sage: G, [S1, S2, S3, S4] = supplementary_difference_set_from_rel_diff_set(17) # optional - sage.modules sage.rings.finite_rings - sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16, G=G) # optional - sage.modules sage.rings.finite_rings + sage: G, [S1, S2, S3, S4] = supplementary_difference_set_from_rel_diff_set(17) # needs sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16, G=G) # needs sage.modules sage.rings.finite_rings True The parameter ``v`` can be given instead of ``G``:: - sage: is_supplementary_difference_set([S1, S2, S3, S4], v=16, lmbda=16) # optional - sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], v=16, lmbda=16) # needs sage.modules sage.rings.finite_rings True - sage: is_supplementary_difference_set([S1, S2, S3, S4], v=20, lmbda=16) # optional - sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], v=20, lmbda=16) # needs sage.modules sage.rings.finite_rings False If ``verbose=True``, the function will be verbose:: - sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=14, G=G, # optional - sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=14, G=G, # needs sage.modules sage.rings.finite_rings ....: verbose=True) Number of pairs with difference (1) is 16, but lambda is 14 False TESTS:: - sage: is_supplementary_difference_set([[1], [1]], lmbda=0, G=Zmod(3)) # optional - sage.modules sage.rings.finite_rings + sage: # needs sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([[1], [1]], lmbda=0, G=Zmod(3)) True - sage: is_supplementary_difference_set([S1, S2, S3, S4], v=17, lmbda=16, G=G) # optional - sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], v=17, lmbda=16, G=G) False - sage: is_supplementary_difference_set([S1, S2, S3, S4], G=G) # optional - sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], G=G) True - sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16) # optional - sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16) Traceback (most recent call last): ... ValueError: one of G or v must be specified @@ -1740,7 +1749,7 @@ def supplementary_difference_set_from_rel_diff_set(q, existence=False, check=Tru EXAMPLES:: sage: from sage.combinat.designs.difference_family import supplementary_difference_set_from_rel_diff_set - sage: supplementary_difference_set_from_rel_diff_set(17) #random + sage: supplementary_difference_set_from_rel_diff_set(17) #random # needs sage.libs.pari (Additive abelian group isomorphic to Z/16, [[(1), (5), (6), (7), (9), (13), (14), (15)], [(0), (2), (3), (5), (6), (10), (11), (13), (14)], @@ -1756,6 +1765,7 @@ def supplementary_difference_set_from_rel_diff_set(q, existence=False, check=Tru TESTS:: + sage: # needs sage.libs.pari sage: from sage.combinat.designs.difference_family import is_supplementary_difference_set sage: G, sets = supplementary_difference_set_from_rel_diff_set(17, check=False) sage: is_supplementary_difference_set(sets, lmbda=16, G=G) @@ -1780,8 +1790,8 @@ def supplementary_difference_set_from_rel_diff_set(q, existence=False, check=Tru Check that the function works even when s > 1:: - sage: G, sets = supplementary_difference_set_from_rel_diff_set(353, check=False) #long time - sage: is_supplementary_difference_set(sets, lmbda=352, G=G) #long time + sage: G, sets = supplementary_difference_set_from_rel_diff_set(353, check=False) # long time, needs sage.libs.pari + sage: is_supplementary_difference_set(sets, lmbda=352, G=G) # long time, needs sage.libs.pari True .. SEEALSO:: @@ -1922,30 +1932,31 @@ def get_fixed_relative_difference_set(G, rel_diff_set, as_elements=False): EXAMPLES:: sage: from sage.combinat.designs.difference_family import relative_difference_set_from_m_sequence, get_fixed_relative_difference_set - sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) # optional - sage.modules - sage: get_fixed_relative_difference_set(G, s1) # random # optional - sage.modules + sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) # needs sage.libs.pari sage.modules + sage: get_fixed_relative_difference_set(G, s1) # random # needs sage.libs.pari sage.modules [2, 10, 19, 23, 0] If ``as_elements=True``, the result will contain elements of the group:: - sage: get_fixed_relative_difference_set(G, s1, as_elements=True) # random # optional - sage.modules + sage: get_fixed_relative_difference_set(G, s1, as_elements=True) # random # needs sage.libs.pari sage.modules [(2), (10), (19), (23), (0)] TESTS:: + sage: # needs sage.libs.pari sage.modules sage: from sage.combinat.designs.difference_family import is_fixed_relative_difference_set - sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) # optional - sage.modules - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) # optional - sage.modules - sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules + sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) + sage: is_fixed_relative_difference_set(s2, len(s2)) True - sage: G, s1 = relative_difference_set_from_m_sequence(9, 2, return_group=True) # optional - sage.modules - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) # optional - sage.modules - sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules + sage: G, s1 = relative_difference_set_from_m_sequence(9, 2, return_group=True) + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) + sage: is_fixed_relative_difference_set(s2, len(s2)) True - sage: type(s2[0]) # optional - sage.modules + sage: type(s2[0]) - sage: s2 = get_fixed_relative_difference_set(G, s1) # optional - sage.modules - sage: type(s2[0]) # optional - sage.modules + sage: s2 = get_fixed_relative_difference_set(G, s1) + sage: type(s2[0]) """ q = len(rel_diff_set) @@ -1985,21 +1996,22 @@ def is_fixed_relative_difference_set(R, q): EXAMPLES:: + sage: # needs sage.modules sage: from sage.combinat.designs.difference_family import relative_difference_set_from_m_sequence, get_fixed_relative_difference_set, is_fixed_relative_difference_set - sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) # optional - sage.modules - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) # optional - sage.modules - sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules + sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) # needs sage.libs.pari + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) # needs sage.libs.pari + sage: is_fixed_relative_difference_set(s2, len(s2)) # needs sage.libs.pari True - sage: G = AdditiveAbelianGroup([15]) # optional - sage.modules - sage: s3 = [G[1], G[2], G[3], G[4]] # optional - sage.modules - sage: is_fixed_relative_difference_set(s3, len(s3)) # optional - sage.modules + sage: G = AdditiveAbelianGroup([15]) + sage: s3 = [G[1], G[2], G[3], G[4]] + sage: is_fixed_relative_difference_set(s3, len(s3)) False If the relative difference set does not contain elements of the group, the method returns false:: - sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) # optional - sage.modules - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=False) # optional - sage.modules - sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules + sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) # needs sage.libs.pari sage.modules + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=False) # needs sage.libs.pari sage.modules + sage: is_fixed_relative_difference_set(s2, len(s2)) # needs sage.libs.pari sage.modules False """ for el in R: @@ -2034,7 +2046,7 @@ def skew_supplementary_difference_set_over_polynomial_ring(n, existence=False, c EXAMPLES:: sage: from sage.combinat.designs.difference_family import skew_supplementary_difference_set_over_polynomial_ring - sage: G, [S1, S2, S3, S4] = skew_supplementary_difference_set_over_polynomial_ring(81) + sage: G, [S1, S2, S3, S4] = skew_supplementary_difference_set_over_polynomial_ring(81) # needs sage.libs.pari If ``existence=True``, the function returns a boolean:: @@ -2830,7 +2842,7 @@ def complementary_difference_setsI(n, check=True): Traceback (most recent call last): ... ValueError: the parameter 17 is not valid - sage: complementary_difference_setsI(15) + sage: complementary_difference_setsI(15) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: the parameter 15 is not valid @@ -2887,11 +2899,12 @@ def complementary_difference_setsII(n, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import complementary_difference_setsII - sage: complementary_difference_setsII(5) + sage: complementary_difference_setsII(5) # needs sage.libs.pari (Finite Field of size 5, [1, 2], [1, 3]) TESTS:: + sage: # needs sage.libs.pari sage: from sage.combinat.designs.difference_family import are_complementary_difference_sets sage: G, A, B = complementary_difference_setsII(25, check=False) sage: are_complementary_difference_sets(G, A, B) @@ -2966,23 +2979,23 @@ def complementary_difference_setsIII(n, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import complementary_difference_setsIII - sage: complementary_difference_setsIII(11) + sage: complementary_difference_setsIII(11) # needs sage.libs.pari (Ring of integers modulo 11, [1, 2, 5, 7, 8], [0, 1, 3, 8, 10]) TESTS:: sage: from sage.combinat.designs.difference_family import are_complementary_difference_sets - sage: G, A, B = complementary_difference_setsIII(21, check=False) - sage: are_complementary_difference_sets(G, A, B) + sage: G, A, B = complementary_difference_setsIII(21, check=False) # needs sage.libs.pari + sage: are_complementary_difference_sets(G, A, B) # needs sage.libs.pari True - sage: G, A, B = complementary_difference_setsIII(65, check=False) - sage: are_complementary_difference_sets(G, A, B) + sage: G, A, B = complementary_difference_setsIII(65, check=False) # needs sage.libs.pari + sage: are_complementary_difference_sets(G, A, B) # needs sage.libs.pari True sage: complementary_difference_setsIII(10) Traceback (most recent call last): ... ValueError: the parameter 10 is not valid - sage: complementary_difference_setsIII(17) + sage: complementary_difference_setsIII(17) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: the parameter 17 is not valid @@ -3046,12 +3059,12 @@ def complementary_difference_sets(n, existence=False, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import complementary_difference_sets - sage: complementary_difference_sets(15) + sage: complementary_difference_sets(15) # needs sage.libs.pari (Ring of integers modulo 15, [1, 2, 4, 6, 7, 10, 12], [0, 1, 2, 6, 9, 13, 14]) If ``existence=True``, the function returns a boolean:: - sage: complementary_difference_sets(15, existence=True) + sage: complementary_difference_sets(15, existence=True) # needs sage.libs.pari True sage: complementary_difference_sets(16, existence=True) False @@ -3059,17 +3072,17 @@ def complementary_difference_sets(n, existence=False, check=True): TESTS:: sage: from sage.combinat.designs.difference_family import are_complementary_difference_sets - sage: G, A, B = complementary_difference_sets(29) - sage: are_complementary_difference_sets(G, A, B) + sage: G, A, B = complementary_difference_sets(29) # needs sage.libs.pari + sage: are_complementary_difference_sets(G, A, B) # needs sage.libs.pari True - sage: G, A, B = complementary_difference_sets(65) - sage: are_complementary_difference_sets(G, A, B) + sage: G, A, B = complementary_difference_sets(65) # needs sage.libs.pari + sage: are_complementary_difference_sets(G, A, B) # needs sage.libs.pari True sage: complementary_difference_sets(10) Traceback (most recent call last): ... ValueError: the parameter n must be odd - sage: complementary_difference_sets(17) + sage: complementary_difference_sets(17) # needs sage.libs.pari Traceback (most recent call last): ... NotImplementedError: complementary difference sets of order 17 are not implemented yet @@ -3150,10 +3163,10 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch EXAMPLES:: - sage: G,D = designs.difference_family(73,4) - sage: G + sage: G,D = designs.difference_family(73,4) # needs sage.libs.pari + sage: G # needs sage.libs.pari Finite Field of size 73 - sage: D + sage: D # needs sage.libs.pari [[0, 1, 5, 18], [0, 3, 15, 54], [0, 9, 45, 16], @@ -3164,6 +3177,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch sage: print(designs.difference_family(73, 4, explain_construction=True)) The database contains a (73,4)-evenly distributed set + sage: # needs sage.libs.pari sage: G,D = designs.difference_family(15,7,3) sage: G Ring of integers modulo 15 @@ -3172,11 +3186,11 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch sage: print(designs.difference_family(15,7,3,explain_construction=True)) Singer difference set - sage: print(designs.difference_family(91,10,1,explain_construction=True)) + sage: print(designs.difference_family(91,10,1,explain_construction=True)) # needs sage.libs.pari Singer difference set - sage: print(designs.difference_family(64,28,12, explain_construction=True)) + sage: print(designs.difference_family(64,28,12, explain_construction=True)) # needs sage.libs.pari McFarland 1973 construction - sage: print(designs.difference_family(576, 276, 132, explain_construction=True)) + sage: print(designs.difference_family(576, 276, 132, explain_construction=True)) # needs sage.libs.pari Hadamard difference set product from N1=2 and N2=3 For `k=6,7` we look at the set of small prime powers for which a @@ -3191,7 +3205,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch sage: from itertools import islice sage: l6 = {True:[], False: [], Unknown: []} - sage: for q in islice(prime_power_mod(1,30), int(60)): + sage: for q in islice(prime_power_mod(1,30), int(60)): # needs sage.libs.pari ....: l6[designs.difference_family(q,6,existence=True)].append(q) sage: l6[True] [31, 121, 151, 181, 211, ..., 3061, 3121, 3181] @@ -3201,7 +3215,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch [] sage: l7 = {True: [], False: [], Unknown: []} - sage: for q in islice(prime_power_mod(1,42), int(60)): + sage: for q in islice(prime_power_mod(1,42), int(60)): # needs sage.libs.pari ....: l7[designs.difference_family(q,7,existence=True)].append(q) sage: l7[True] [169, 337, 379, 421, 463, 547, 631, 673, 757, 841, 883, 967, ..., 4621, 4957, 5167] @@ -3212,7 +3226,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch List available constructions:: - sage: for v in range(2,100): + sage: for v in range(2,100): # needs sage.libs.pari ....: constructions = [] ....: for k in range(2,10): ....: for l in range(1,10): @@ -3289,7 +3303,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch sage: Q15 = [76231] sage: Q4 = [13, 73, 97, 109, 181, 229, 241, 277, 337, 409, 421, 457] sage: Q8 = [1009, 3137, 3697] - sage: for Q,k in [(Q4,4),(Q5,5),(Q8,8),(Q9,9),(Q15,15)]: + sage: for Q,k in [(Q4,4),(Q5,5),(Q8,8),(Q9,9),(Q15,15)]: # needs sage.libs.pari ....: for q in Q: ....: assert designs.difference_family(q,k,1,existence=True) is True ....: _ = designs.difference_family(q,k,1) @@ -3298,7 +3312,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch sage: sgp = lambda q,d: ((q**(d+1)-1)//(q-1), (q**d-1)//(q-1), (q**(d-1)-1)//(q-1)) - sage: for q in range(2,10): + sage: for q in range(2,10): # needs sage.libs.pari ....: if is_prime_power(q): ....: for d in [2,3,4]: ....: v,k,l = sgp(q,d) @@ -3307,13 +3321,13 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch Check twin primes difference sets:: - sage: for p in [3,5,7,9,11]: + sage: for p in [3,5,7,9,11]: # needs sage.libs.pari ....: v = p*(p+2); k = (v-1)/2; lmbda = (k-1)/2 ....: G,D = designs.difference_family(v,k,lmbda) Check Complementary difference sets:: - sage: for v in [15, 33, 35, 39, 51]: + sage: for v in [15, 33, 35, 39, 51]: # needs sage.libs.pari ....: G, D = designs.difference_family(v, (v-1)//2, (v-1)//2-1) Check the database:: @@ -3323,14 +3337,14 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch ....: assert designs.difference_family(v,k,l,existence=True) is True ....: df = designs.difference_family(v,k,l,check=True) - sage: for k in EDS: + sage: for k in EDS: # needs sage.libs.pari ....: for v in EDS[k]: ....: assert designs.difference_family(v,k,1,existence=True) is True ....: df = designs.difference_family(v,k,1,check=True) Check the known Hadamard parameters:: - sage: for N in range(2,21): + sage: for N in range(2,21): # needs sage.libs.pari ....: v = 4*N^2; k = 2*N^2-N; l = N^2-N ....: status = designs.difference_family(v,k,l,existence=True) ....: print("{:2} {}".format(N,designs.difference_family(v,k,l,explain_construction=True) if status is True else status)) @@ -3369,7 +3383,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch sage: designs.difference_family(3, 2, 1, explain_construction=True) 'Trivial difference family' - sage: for _ in range(100): + sage: for _ in range(100): # needs sage.libs.pari ....: v = randint(1, 30) ....: k = randint(2, 30) ....: l = randint(1, 30) diff --git a/src/sage/combinat/designs/difference_matrices.py b/src/sage/combinat/designs/difference_matrices.py index 6d609fc94f4..8ad1f7bf088 100644 --- a/src/sage/combinat/designs/difference_matrices.py +++ b/src/sage/combinat/designs/difference_matrices.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.finite_rings r""" Difference Matrices @@ -146,12 +147,12 @@ def difference_matrix(g,k,lmbda=1,existence=False,check=True): - ``existence`` (boolean) -- instead of building the design, return: - - ``True`` -- meaning that Sage knows how to build the design + - ``True`` -- meaning that Sage knows how to build the design - - ``Unknown`` -- meaning that Sage does not know how to build the - design, but that the design may exist (see :mod:`sage.misc.unknown`). + - ``Unknown`` -- meaning that Sage does not know how to build the + design, but that the design may exist (see :mod:`sage.misc.unknown`). - - ``False`` -- meaning that the design does not exist. + - ``False`` -- meaning that the design does not exist. .. NOTE:: diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index a19267a4bdb..36d48d50b30 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: needs sage.rings.finite_rings r""" Evenly distributed sets in finite fields @@ -111,7 +111,7 @@ cdef class EvenlyDistributedSetsBacktracker: Or only count them:: - sage: for k in range(13, 200, 12): # optional - sage.rings.finite_rings + sage: for k in range(13, 200, 12): ....: if is_prime_power(k): ....: K = GF(k,'a') ....: E1 = EvenlyDistributedSetsBacktracker(K, 4, False) @@ -357,9 +357,9 @@ cdef class EvenlyDistributedSetsBacktracker: sage: from sage.combinat.designs.evenly_distributed_sets import EvenlyDistributedSetsBacktracker - sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4) # optional - sage.rings.finite_rings + sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4) 4-evenly distributed sets (up to isomorphism) in Finite Field in a of size 5^2 - sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, # optional - sage.rings.finite_rings + sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, ....: up_to_isomorphism=False) 4-evenly distributed sets in Finite Field in a of size 5^2 """ @@ -379,15 +379,15 @@ cdef class EvenlyDistributedSetsBacktracker: sage: from sage.combinat.designs.evenly_distributed_sets import EvenlyDistributedSetsBacktracker - sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'), 4); E # optional - sage.rings.finite_rings + sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'), 4); E 4-evenly distributed sets (up to isomorphism) in Finite Field in a of size 5^2 - sage: E.cardinality() # optional - sage.rings.finite_rings + sage: E.cardinality() 4 - sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, # optional - sage.rings.finite_rings + sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, ....: up_to_isomorphism=False) - sage: E.cardinality() # optional - sage.rings.finite_rings + sage: E.cardinality() 40 """ cdef n = 0 diff --git a/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx b/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx index cdc5cc7c472..26da661f3cd 100644 --- a/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx +++ b/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.gap r""" Database of generalised quadrangles with spread diff --git a/src/sage/combinat/designs/group_divisible_designs.py b/src/sage/combinat/designs/group_divisible_designs.py index 738cec0222c..0bc9c38ef00 100644 --- a/src/sage/combinat/designs/group_divisible_designs.py +++ b/src/sage/combinat/designs/group_divisible_designs.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.finite_rings r""" Group-Divisible Designs (GDD) diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 3be5a2d8866..83927348b05 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -105,8 +105,8 @@ class IncidenceStructure(): Or by its adjacency matrix (a `\{0,1\}`-matrix in which rows are indexed by points and columns by blocks):: - sage: m = matrix([[0,1,0],[0,0,1],[1,0,1],[1,1,1]]) - sage: IncidenceStructure(m) + sage: m = matrix([[0,1,0],[0,0,1],[1,0,1],[1,1,1]]) # needs sage.modules + sage: IncidenceStructure(m) # needs sage.modules Incidence structure with 4 points and 3 blocks The points can be any (hashable) object:: @@ -160,9 +160,10 @@ def __init__(self, points=None, blocks=None, incidence_matrix=None, We avoid to convert to integers when the points are not (but compare equal to integers because of coercion):: + sage: # needs sage.rings.finite_rings sage: V = GF(5) sage: e0,e1,e2,e3,e4 = V - sage: [e0,e1,e2,e3,e4] == list(range(5)) # coercion makes them equal + sage: [e0,e1,e2,e3,e4] == list(range(5)) # coercion makes them equal True sage: blocks = [[e0,e1,e2],[e0,e1],[e2,e4]] sage: I = IncidenceStructure(V, blocks) @@ -282,9 +283,9 @@ def __eq__(self, other): sage: blocks = [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]] sage: BD1 = IncidenceStructure(7, blocks) - sage: M = BD1.incidence_matrix() - sage: BD2 = IncidenceStructure(incidence_matrix=M) - sage: BD1 == BD2 + sage: M = BD1.incidence_matrix() # needs sage.modules + sage: BD2 = IncidenceStructure(incidence_matrix=M) # needs sage.modules + sage: BD1 == BD2 # needs sage.modules True sage: e1 = frozenset([0,1]) @@ -326,9 +327,9 @@ def __ne__(self, other): EXAMPLES:: sage: BD1 = IncidenceStructure(7, [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) - sage: M = BD1.incidence_matrix() - sage: BD2 = IncidenceStructure(incidence_matrix=M) - sage: BD1 != BD2 + sage: M = BD1.incidence_matrix() # needs sage.modules + sage: BD2 = IncidenceStructure(incidence_matrix=M) # needs sage.modules + sage: BD1 != BD2 # needs sage.modules False """ return not self == other @@ -363,8 +364,9 @@ def __contains__(self, block): True sage: ["Am", "I", "finally", "done ?"] in IS False - sage: IS = designs.ProjectiveGeometryDesign(3, 1, GF(2), point_coordinates=False) - sage: [3,8,7] in IS + sage: IS = designs.ProjectiveGeometryDesign(3, 1, GF(2), # needs sage.rings.finite_rings + ....: point_coordinates=False) + sage: [3,8,7] in IS # needs sage.rings.finite_rings True sage: [3,8,9] in IS False @@ -393,6 +395,7 @@ def canonical_label(self): EXAMPLES:: + sage: # needs sage.schemes sage: fano1 = designs.balanced_incomplete_block_design(7,3) sage: fano2 = designs.projective_plane(2) sage: fano1 == fano2 @@ -427,6 +430,7 @@ def is_isomorphic(self, other, certificate=False): EXAMPLES:: + sage: # needs sage.schemes sage: fano1 = designs.balanced_incomplete_block_design(7,3) sage: fano2 = designs.projective_plane(2) sage: fano1.is_isomorphic(fano2) @@ -436,29 +440,32 @@ def is_isomorphic(self, other, certificate=False): TESTS:: - sage: IS = IncidenceStructure([["A",5,pi],["A",5,"Wouhou"], # optional - sage.symbolic + sage: # needs sage.symbolic + sage: IS = IncidenceStructure([["A",5,pi],["A",5,"Wouhou"], ....: ["A","Wouhou",(9,9)],[pi,12]]) - sage: IS2 = IS.copy() # optional - sage.symbolic - sage: IS2.relabel(IS2.canonical_label()) # optional - sage.symbolic - sage: IS.is_isomorphic(IS2) # optional - sage.symbolic + sage: IS2 = IS.copy() + sage: IS2.relabel(IS2.canonical_label()) + sage: IS.is_isomorphic(IS2) True - sage: canon = IS.is_isomorphic(IS2, certificate=True) # optional - sage.symbolic - sage: IS.relabel(canon) # optional - sage.symbolic - sage: IS==IS2 # optional - sage.symbolic + sage: canon = IS.is_isomorphic(IS2, certificate=True) + sage: IS.relabel(canon) + sage: IS==IS2 True sage: IS2 = IncidenceStructure([[1,2]]) - sage: IS2.is_isomorphic(IS) # optional - sage.symbolic + sage: IS2.is_isomorphic(IS) # needs sage.symbolic False - sage: IS2.is_isomorphic(IS, certificate=True) # optional - sage.symbolic + sage: IS2.is_isomorphic(IS, certificate=True) # needs sage.symbolic {} Checking whether two :class:`IncidenceStructure` are isomorphic incidentally computes their canonical label (if necessary). Thus, subsequent calls to :meth:`is_isomorphic` will be faster:: + sage: # needs sage.schemes sage: IS1 = designs.projective_plane(3) - sage: IS2 = IS1.relabel(Permutations(IS1.ground_set()).random_element(), inplace=False) + sage: IS2 = IS1.relabel(Permutations(IS1.ground_set()).random_element(), + ....: inplace=False) sage: IS2 = IncidenceStructure(IS2.blocks()) sage: IS1._canonical_label is None and IS2._canonical_label is None True @@ -548,10 +555,10 @@ def isomorphic_substructures_iterator(self, H2,induced=False): The number of copies of `H` in itself is the size of its automorphism group:: - sage: H = designs.projective_plane(3) - sage: sum(1 for _ in H.isomorphic_substructures_iterator(H)) + sage: H = designs.projective_plane(3) # needs sage.schemes + sage: sum(1 for _ in H.isomorphic_substructures_iterator(H)) # needs sage.schemes 5616 - sage: H.automorphism_group().cardinality() + sage: H.automorphism_group().cardinality() # needs sage.groups sage.schemes 5616 """ from sage.combinat.designs.subhypergraph_search import SubHypergraphSearch @@ -673,6 +680,7 @@ def trace(self, points, min_size=1, multiset=True): A Baer subplane of order 2 (i.e. a Fano plane) in a projective plane of order 4:: + sage: # needs sage.schemes sage: P4 = designs.projective_plane(4) sage: F = designs.projective_plane(2) sage: for x in Subsets(P4.ground_set(),7): @@ -685,6 +693,7 @@ def trace(self, points, min_size=1, multiset=True): TESTS:: + sage: # needs sage.schemes sage: F.trace([0..50]) Traceback (most recent call last): ... @@ -929,11 +938,11 @@ def is_regular(self, r=None) -> bool | int: EXAMPLES:: - sage: designs.balanced_incomplete_block_design(7,3).is_regular() + sage: designs.balanced_incomplete_block_design(7,3).is_regular() # needs sage.schemes 3 - sage: designs.balanced_incomplete_block_design(7,3).is_regular(r=3) + sage: designs.balanced_incomplete_block_design(7,3).is_regular(r=3) # needs sage.schemes True - sage: designs.balanced_incomplete_block_design(7,3).is_regular(r=4) + sage: designs.balanced_incomplete_block_design(7,3).is_regular(r=4) # needs sage.schemes False TESTS:: @@ -980,11 +989,11 @@ def is_uniform(self, k=None) -> bool | int: EXAMPLES:: - sage: designs.balanced_incomplete_block_design(7,3).is_uniform() + sage: designs.balanced_incomplete_block_design(7,3).is_uniform() # needs sage.schemes 3 - sage: designs.balanced_incomplete_block_design(7,3).is_uniform(k=3) + sage: designs.balanced_incomplete_block_design(7,3).is_uniform(k=3) # needs sage.schemes True - sage: designs.balanced_incomplete_block_design(7,3).is_uniform(k=4) + sage: designs.balanced_incomplete_block_design(7,3).is_uniform(k=4) # needs sage.schemes False TESTS:: @@ -1119,10 +1128,11 @@ def incidence_matrix(self): EXAMPLES:: - sage: BD = IncidenceStructure(7, [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) + sage: BD = IncidenceStructure(7, [[0,1,2],[0,3,4],[0,5,6],[1,3,5], + ....: [1,4,6],[2,3,6],[2,4,5]]) sage: BD.block_sizes() [3, 3, 3, 3, 3, 3, 3] - sage: BD.incidence_matrix() + sage: BD.incidence_matrix() # needs sage.modules [1 1 1 0 0 0 0] [1 0 0 1 1 0 0] [1 0 0 0 0 1 1] @@ -1132,7 +1142,7 @@ def incidence_matrix(self): [0 0 1 0 1 1 0] sage: I = IncidenceStructure('abc', ('ab','abc','ac','c')) - sage: I.incidence_matrix() + sage: I.incidence_matrix() # needs sage.modules [1 1 1 0] [1 1 0 0] [0 1 1 1] @@ -1157,26 +1167,28 @@ def incidence_graph(self,labels=False): - ``labels`` (boolean) -- whether to return a graph whose vertices are integers, or labelled elements. - - ``labels is False`` (default) -- in this case the first vertices - of the graphs are the elements of :meth:`ground_set`, and appear - in the same order. Similarly, the following vertices represent the - elements of :meth:`blocks`, and appear in the same order. + - ``labels is False`` (default) -- in this case the first vertices + of the graphs are the elements of :meth:`ground_set`, and appear + in the same order. Similarly, the following vertices represent the + elements of :meth:`blocks`, and appear in the same order. - - ``labels is True``, the points keep their original labels, and the - blocks are :func:`Set ` objects. + - ``labels is True``, the points keep their original labels, and the + blocks are :func:`Set ` objects. - Note that the labelled incidence graph can be incorrect when - blocks are repeated, and on some (rare) occasions when the - elements of :meth:`ground_set` mix :func:`Set` and non-:func:`Set - ` objects. + Note that the labelled incidence graph can be incorrect when + blocks are repeated, and on some (rare) occasions when the + elements of :meth:`ground_set` mix :func:`Set` and non-:func:`Set + ` objects. EXAMPLES:: - sage: BD = IncidenceStructure(7, [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) - sage: BD.incidence_graph() + sage: BD = IncidenceStructure(7, [[0,1,2],[0,3,4],[0,5,6],[1,3,5], + ....: [1,4,6],[2,3,6],[2,4,5]]) + sage: BD.incidence_graph() # needs sage.modules Bipartite graph on 14 vertices - sage: A = BD.incidence_matrix() - sage: Graph(block_matrix([[A*0,A],[A.transpose(),A*0]])) == BD.incidence_graph() + sage: A = BD.incidence_matrix() # needs sage.modules + sage: Graph(block_matrix([[A*0, A], # needs sage.modules + ....: [A.transpose(),A*0]])) == BD.incidence_graph() True TESTS: @@ -1219,9 +1231,9 @@ def is_berge_cyclic(self): EXAMPLES:: - sage: Hypergraph(5, [[1, 2, 3], [2, 3 ,4]]).is_berge_cyclic() + sage: Hypergraph(5, [[1, 2, 3], [2, 3, 4]]).is_berge_cyclic() # needs sage.modules True - sage: Hypergraph(6, [[1, 2, 3], [3 ,4, 5]]).is_berge_cyclic() + sage: Hypergraph(6, [[1, 2, 3], [3, 4, 5]]).is_berge_cyclic() # needs sage.modules False TESTS:: @@ -1260,10 +1272,10 @@ def complement(self,uniform=False): :class:`~sage.combinat.designs.bibd.BalancedIncompleteBlockDesign` is also a `2`-design:: - sage: bibd = designs.balanced_incomplete_block_design(13,4) - sage: bibd.is_t_design(return_parameters=True) + sage: bibd = designs.balanced_incomplete_block_design(13,4) # needs sage.schemes + sage: bibd.is_t_design(return_parameters=True) # needs sage.schemes (True, (2, 13, 4, 1)) - sage: bibd.complement().is_t_design(return_parameters=True) + sage: bibd.complement().is_t_design(return_parameters=True) # needs sage.schemes (True, (2, 13, 9, 6)) The "uniform" complement of a graph is a graph:: @@ -1279,8 +1291,8 @@ def complement(self,uniform=False): TESTS:: - sage: bibd.relabel({i:str(i) for i in bibd.ground_set()}) - sage: bibd.complement().ground_set() + sage: bibd.relabel({i:str(i) for i in bibd.ground_set()}) # needs sage.schemes + sage: bibd.complement().ground_set() # needs sage.schemes ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] sage: I = IncidenceStructure('abc', ['ab','ac','bc']) @@ -1336,17 +1348,19 @@ def relabel(self, perm=None, inplace=True): EXAMPLES:: - sage: TD=designs.transversal_design(5,5) - sage: TD.relabel({i:chr(97+i) for i in range(25)}) + sage: # needs sage.schemes + sage: TD = designs.transversal_design(5,5) + sage: TD.relabel({i: chr(97+i) for i in range(25)}) sage: TD.ground_set() - ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y'] + ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y'] sage: TD.blocks()[:3] [['a', 'f', 'k', 'p', 'u'], ['a', 'g', 'm', 's', 'y'], ['a', 'h', 'o', 'q', 'x']] Relabel to integer points:: - sage: TD.relabel() - sage: TD.blocks()[:3] + sage: TD.relabel() # needs sage.schemes + sage: TD.blocks()[:3] # needs sage.schemes [[0, 5, 10, 15, 20], [0, 6, 12, 18, 24], [0, 7, 14, 16, 23]] TESTS: @@ -1365,7 +1379,7 @@ def relabel(self, perm=None, inplace=True): And one can also verify that we have exactly two automorphisms:: - sage: I.automorphism_group() + sage: I.automorphism_group() # needs sage.groups Permutation Group with generators [(2,4)] """ if not inplace: @@ -1431,10 +1445,10 @@ def packing(self, solver=None, verbose=0, *, integrality_tolerance=1e-3): EXAMPLES:: - sage: P = IncidenceStructure([[1,2],[3,4],[2,3]]).packing() - sage: sorted(sorted(b) for b in P) + sage: P = IncidenceStructure([[1,2],[3,4],[2,3]]).packing() # needs sage.numerical.mip + sage: sorted(sorted(b) for b in P) # needs sage.numerical.mip [[1, 2], [3, 4]] - sage: len(designs.steiner_triple_system(9).packing()) + sage: len(designs.steiner_triple_system(9).packing()) # needs sage.numerical.mip 3 """ from sage.numerical.mip import MixedIntegerLinearProgram @@ -1499,7 +1513,7 @@ def is_t_design(self, t=None, v=None, k=None, l=None, return_parameters=False): sage: BD.is_t_design(0,6,3,7) or BD.is_t_design(0,7,4,7) or BD.is_t_design(0,7,3,8) False - sage: BD = designs.AffineGeometryDesign(3, 1, GF(2)) + sage: BD = designs.AffineGeometryDesign(3, 1, GF(2)) # needs sage.rings.finite_rings sage: BD.is_t_design(1) True sage: BD.is_t_design(2) @@ -1568,12 +1582,15 @@ def is_t_design(self, t=None, v=None, k=None, l=None, return_parameters=False): [(8, 4, 7)] sage: [(v,k,l) for v in R for k in R for l in R if S4_8.is_t_design(0,v,k,l)] [(8, 4, 14)] + + sage: # needs sage.rings.finite_rings sage: A = designs.AffineGeometryDesign(3, 1, GF(2)) sage: A.is_t_design(return_parameters=True) (True, (2, 8, 2, 1)) sage: A = designs.AffineGeometryDesign(4, 2, GF(2)) sage: A.is_t_design(return_parameters=True) (True, (3, 16, 4, 1)) + sage: I = IncidenceStructure(2, []) sage: I.is_t_design(return_parameters=True) (True, (0, 2, 0, 0)) @@ -1695,30 +1712,31 @@ def is_generalized_quadrangle(self, verbose=False, parameters=False): EXAMPLES:: - sage: h = designs.CremonaRichmondConfiguration() - sage: h.is_generalized_quadrangle() + sage: h = designs.CremonaRichmondConfiguration() # needs networkx + sage: h.is_generalized_quadrangle() # needs networkx True This is actually a *regular* generalized quadrangle:: - sage: h.is_generalized_quadrangle(parameters=True) + sage: h.is_generalized_quadrangle(parameters=True) # needs networkx (2, 2) TESTS:: sage: H = IncidenceStructure((2*graphs.CompleteGraph(3)).edges(sort=True, labels=False)) - sage: H.is_generalized_quadrangle(verbose=True) + sage: H.is_generalized_quadrangle(verbose=True) # needs sage.modules Some point is at distance >3 from some block. False sage: G = graphs.CycleGraph(5) - sage: B = list(G.subgraph_search_iterator(graphs.PathGraph(3), return_graphs=False)) - sage: H = IncidenceStructure(B) - sage: H.is_generalized_quadrangle(verbose=True) + sage: B = list(G.subgraph_search_iterator(graphs.PathGraph(3), # needs sage.modules + ....: return_graphs=False)) + sage: H = IncidenceStructure(B) # needs sage.modules + sage: H.is_generalized_quadrangle(verbose=True) # needs sage.modules Two blocks intersect on >1 points. False - sage: hypergraphs.CompleteUniform(4,2).is_generalized_quadrangle(verbose=1) + sage: hypergraphs.CompleteUniform(4,2).is_generalized_quadrangle(verbose=1) # needs sage.modules Some point has two projections on some line. False """ @@ -1769,26 +1787,24 @@ def dual(self, algorithm=None): The dual of a projective plane is a projective plane:: - sage: PP = designs.DesarguesianProjectivePlaneDesign(4) - sage: PP.dual().is_t_design(return_parameters=True) + sage: PP = designs.DesarguesianProjectivePlaneDesign(4) # needs sage.rings.finite_rings + sage: PP.dual().is_t_design(return_parameters=True) # needs sage.modules sage.rings.finite_rings (True, (2, 21, 5, 1)) TESTS:: - sage: D = IncidenceStructure(4, [[0,2],[1,2,3],[2,3]]) - sage: D + sage: D = IncidenceStructure(4, [[0,2],[1,2,3],[2,3]]); D Incidence structure with 4 points and 3 blocks - sage: D.dual() + sage: D.dual() # needs sage.modules Incidence structure with 3 points and 4 blocks - sage: print(D.dual(algorithm="gap")) # optional - gap_packages + sage: print(D.dual(algorithm="gap")) # optional - gap_packages Incidence structure with 3 points and 4 blocks sage: blocks = [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]] - sage: BD = IncidenceStructure(7, blocks, name="FanoPlane") - sage: BD + sage: BD = IncidenceStructure(7, blocks, name="FanoPlane"); BD Incidence structure with 7 points and 7 blocks - sage: print(BD.dual(algorithm="gap")) # optional - gap_packages + sage: print(BD.dual(algorithm="gap")) # optional - gap_packages Incidence structure with 7 points and 7 blocks - sage: BD.dual() + sage: BD.dual() # needs sage.modules Incidence structure with 7 points and 7 blocks REFERENCE: @@ -1815,6 +1831,7 @@ def automorphism_group(self): EXAMPLES:: + sage: # needs sage.groups sage.rings.finite_rings sage: P = designs.DesarguesianProjectivePlaneDesign(2); P (7,3,1)-Balanced Incomplete Block Design sage: G = P.automorphism_group() @@ -1828,17 +1845,17 @@ def automorphism_group(self): A non self-dual example:: sage: IS = IncidenceStructure(list(range(4)), [[0,1,2,3],[1,2,3]]) - sage: IS.automorphism_group().cardinality() + sage: IS.automorphism_group().cardinality() # needs sage.groups 6 - sage: IS.dual().automorphism_group().cardinality() + sage: IS.dual().automorphism_group().cardinality() # needs sage.groups sage.modules 1 Examples with non-integer points:: sage: I = IncidenceStructure('abc', ('ab','ac','bc')) - sage: I.automorphism_group() + sage: I.automorphism_group() # needs sage.groups Permutation Group with generators [('b','c'), ('a','b')] - sage: IncidenceStructure([[(1,2),(3,4)]]).automorphism_group() + sage: IncidenceStructure([[(1,2),(3,4)]]).automorphism_group() # needs sage.groups Permutation Group with generators [((1,2),(3,4))] """ from sage.graphs.graph import Graph @@ -1907,19 +1924,19 @@ def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, sage: TD.is_resolvable() True - sage: AG = designs.AffineGeometryDesign(3,1,GF(2)) - sage: AG.is_resolvable() + sage: AG = designs.AffineGeometryDesign(3,1,GF(2)) # needs sage.rings.finite_rings + sage: AG.is_resolvable() # needs sage.rings.finite_rings True Their classes:: - sage: b,cls = TD.is_resolvable(True) + sage: b, cls = TD.is_resolvable(True) sage: b True sage: cls # random [[[0, 3], [1, 2]], [[1, 3], [0, 2]]] - sage: b,cls = AG.is_resolvable(True) + sage: b, cls = AG.is_resolvable(True) # needs sage.rings.finite_rings sage: b True sage: cls # random @@ -1933,17 +1950,17 @@ def is_resolvable(self, certificate=False, solver=None, verbose=0, check=True, A non-resolvable design:: - sage: Fano = designs.balanced_incomplete_block_design(7,3) - sage: Fano.is_resolvable() + sage: Fano = designs.balanced_incomplete_block_design(7,3) # needs sage.schemes + sage: Fano.is_resolvable() # needs sage.schemes False - sage: Fano.is_resolvable(True) + sage: Fano.is_resolvable(True) # needs sage.schemes (False, []) TESTS:: - sage: _,cls1 = AG.is_resolvable(certificate=True) - sage: _,cls2 = AG.is_resolvable(certificate=True) - sage: cls1 is cls2 + sage: _, cls1 = AG.is_resolvable(certificate=True) # needs sage.rings.finite_rings + sage: _, cls2 = AG.is_resolvable(certificate=True) # needs sage.rings.finite_rings + sage: cls1 is cls2 # needs sage.rings.finite_rings False """ if self._classes is None: @@ -2040,12 +2057,12 @@ def coloring(self, k=None, solver=None, verbose=0, The Fano plane has chromatic number 3:: - sage: len(designs.steiner_triple_system(7).coloring()) + sage: len(designs.steiner_triple_system(7).coloring()) # needs sage.numerical.mip 3 One admissible 3-coloring:: - sage: designs.steiner_triple_system(7).coloring() # not tested - architecture-dependent + sage: designs.steiner_triple_system(7).coloring() # not tested # needs sage.numerical.mip [[0, 2, 5, 1], [4, 3], [6]] The chromatic number of a graph is equal to the chromatic number of its @@ -2055,7 +2072,7 @@ def coloring(self, k=None, solver=None, verbose=0, sage: H = IncidenceStructure(g.edges(sort=True, labels=False)) sage: len(g.coloring()) 3 - sage: len(H.coloring()) + sage: len(H.coloring()) # needs sage.numerical.mip 3 """ if k is None: @@ -2150,10 +2167,11 @@ def _spring_layout(self): EXAMPLES:: + sage: # needs sage.plot sage: H = Hypergraph([{1,2,3},{2,3,4},{3,4,5},{4,5,6}]); H Incidence structure with 6 points and 4 blocks sage: L = H._spring_layout() - sage: L # random + sage: L # random {1: (0.238, -0.926), 2: (0.672, -0.518), 3: (0.449, -0.225), @@ -2166,7 +2184,7 @@ def _spring_layout(self): {1, 2, 3}: (0.393, -0.617)} sage: all(v in L for v in H.ground_set()) True - sage: all(v in L for v in map(Set,H.blocks())) + sage: all(v in L for v in map(Set, H.blocks())) True """ from sage.graphs.graph import Graph @@ -2196,9 +2214,10 @@ def _latex_(self): sage: g = graphs.Grid2dGraph(5,5) sage: C4 = graphs.CycleGraph(4) - sage: sets = Set(map(Set,list(g.subgraph_search_iterator(C4, return_graphs=False)))) - sage: H = Hypergraph(sets) - sage: view(H) # not tested + sage: sets = Set(map(Set, g.subgraph_search_iterator(C4, # needs sage.modules + ....: return_graphs=False))) + sage: H = Hypergraph(sets) # needs sage.modules + sage: view(H) # not tested # needs sage.modules sage.plot TESTS:: diff --git a/src/sage/combinat/designs/latin_squares.py b/src/sage/combinat/designs/latin_squares.py index 4dea7cd63d7..23e2f09bfac 100644 --- a/src/sage/combinat/designs/latin_squares.py +++ b/src/sage/combinat/designs/latin_squares.py @@ -1,11 +1,11 @@ -# -*- coding: utf-8 -*- +# sage.doctest: needs sage.modules r""" Mutually Orthogonal Latin Squares (MOLS) The main function of this module is :func:`mutually_orthogonal_latin_squares` and can be can be used to generate MOLS (or check that they exist):: - sage: MOLS = designs.mutually_orthogonal_latin_squares(4,8) + sage: MOLS = designs.mutually_orthogonal_latin_squares(4,8) # needs sage.schemes For more information on MOLS, see the :wikipedia:`Wikipedia entry on MOLS `. If you are only @@ -155,8 +155,8 @@ def are_mutually_orthogonal_latin_squares(l, verbose=False): Squares 0 and 2 are not orthogonal False - sage: m = designs.mutually_orthogonal_latin_squares(7,8) - sage: are_mutually_orthogonal_latin_squares(m) + sage: m = designs.mutually_orthogonal_latin_squares(7,8) # needs sage.schemes + sage: are_mutually_orthogonal_latin_squares(m) # needs sage.schemes True TESTS: @@ -239,7 +239,7 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): EXAMPLES:: - sage: designs.mutually_orthogonal_latin_squares(4,5) + sage: designs.mutually_orthogonal_latin_squares(4,5) # needs sage.schemes [ [0 2 4 1 3] [0 3 1 4 2] [0 4 3 2 1] [0 1 2 3 4] [4 1 3 0 2] [3 1 4 2 0] [2 1 0 4 3] [4 0 1 2 3] @@ -248,7 +248,7 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): [1 3 0 2 4], [2 0 3 1 4], [3 2 1 0 4], [1 2 3 4 0] ] - sage: designs.mutually_orthogonal_latin_squares(3,7) + sage: designs.mutually_orthogonal_latin_squares(3,7) # needs sage.schemes [ [0 2 4 6 1 3 5] [0 3 6 2 5 1 4] [0 4 1 5 2 6 3] [6 1 3 5 0 2 4] [5 1 4 0 3 6 2] [4 1 5 2 6 3 0] @@ -259,7 +259,7 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): [1 3 5 0 2 4 6], [2 5 1 4 0 3 6], [3 0 4 1 5 2 6] ] - sage: designs.mutually_orthogonal_latin_squares(2,5,partitions=True) + sage: designs.mutually_orthogonal_latin_squares(2,5,partitions=True) # needs sage.schemes [[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], @@ -283,7 +283,7 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): What is the maximum number of MOLS of size 8 that Sage knows how to build?:: - sage: designs.orthogonal_arrays.largest_available_k(8)-2 + sage: designs.orthogonal_arrays.largest_available_k(8)-2 # needs sage.schemes 7 If you only want to know if Sage is able to build a given set of @@ -291,12 +291,12 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): sage: designs.orthogonal_arrays.is_available(5+2, 5) # 5 MOLS of order 5 False - sage: designs.orthogonal_arrays.is_available(4+2,6) # 4 MOLS of order 6 + sage: designs.orthogonal_arrays.is_available(4+2,6) # 4 MOLS of order 6 # needs sage.schemes False Sage, however, is not able to prove that the second MOLS do not exist:: - sage: designs.orthogonal_arrays.exists(4+2,6) # 4 MOLS of order 6 + sage: designs.orthogonal_arrays.exists(4+2,6) # 4 MOLS of order 6 # needs sage.schemes Unknown If you ask for such a MOLS then you will respectively get an informative @@ -306,7 +306,7 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): Traceback (most recent call last): ... EmptySetError: there exist at most n-1 MOLS of size n if n>=2 - sage: designs.mutually_orthogonal_latin_squares(4,6) + sage: designs.mutually_orthogonal_latin_squares(4,6) # needs sage.schemes Traceback (most recent call last): ... NotImplementedError: I don't know how to build 4 MOLS of order 6 @@ -431,8 +431,8 @@ def latin_square_product(M, N, *others): EXAMPLES:: sage: from sage.combinat.designs.latin_squares import latin_square_product - sage: m=designs.mutually_orthogonal_latin_squares(3,4)[0] - sage: latin_square_product(m,m,m) + sage: m=designs.mutually_orthogonal_latin_squares(3,4)[0] # needs sage.schemes + sage: latin_square_product(m,m,m) # needs sage.schemes 64 x 64 sparse matrix over Integer Ring (use the '.str()' method to see the entries) """ from sage.matrix.constructor import Matrix @@ -476,6 +476,7 @@ def MOLS_table(start,stop=None,compare=False,width=None): EXAMPLES:: + sage: # needs sage.schemes sage: from sage.combinat.designs.latin_squares import MOLS_table sage: MOLS_table(100) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index 094a8118245..b37cf2be2b3 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.finite_rings r""" Orthogonal arrays (OA) @@ -1180,11 +1181,12 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): 10 holes of size 9 through the product construction:: - sage: iOA = designs.incomplete_orthogonal_array(10,153,[9]*10) # long time - sage: OA9 = designs.orthogonal_arrays.build(10,9) # long time - sage: for i in range(10): # long time + sage: # long time + sage: iOA = designs.incomplete_orthogonal_array(10,153,[9]*10) + sage: OA9 = designs.orthogonal_arrays.build(10,9) + sage: for i in range(10): ....: iOA.extend([[153-9*(i+1)+x for x in B] for B in OA9]) - sage: is_orthogonal_array(iOA,10,153) # long time + sage: is_orthogonal_array(iOA,10,153) True An `OA(9,82)-OA(9,9)-OA(9,1)`:: @@ -1954,7 +1956,8 @@ def OA_from_PBD(k,n,PBD, check=True): sage: OA_from_PBD(4,10,pbd) Traceback (most recent call last): ... - EmptySetError: There is no OA(n+1,n) - 3.OA(n+1,1) as all blocks intersect in a projective plane. + EmptySetError: There is no OA(n+1,n) - 3.OA(n+1,1) + as all blocks intersect in a projective plane. Or an `OA(3,6)` (as the PBD has 10 points):: diff --git a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py index ff62bae1b8e..c30041a9c9b 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py +++ b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.finite_rings r""" Orthogonal arrays (build recursive constructions) diff --git a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx index 8499f338ade..1843cbe00e8 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +++ b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.finite_rings # cython: cdivision=True r""" Orthogonal arrays (find recursive constructions) diff --git a/src/sage/combinat/designs/resolvable_bibd.py b/src/sage/combinat/designs/resolvable_bibd.py index 623b10be3d2..ed098ce746c 100644 --- a/src/sage/combinat/designs/resolvable_bibd.py +++ b/src/sage/combinat/designs/resolvable_bibd.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.rings.finite_rings r""" Resolvable Balanced Incomplete Block Design (RBIBD) diff --git a/src/sage/combinat/designs/subhypergraph_search.pyx b/src/sage/combinat/designs/subhypergraph_search.pyx index 39fb62300ad..ace387a4bf2 100644 --- a/src/sage/combinat/designs/subhypergraph_search.pyx +++ b/src/sage/combinat/designs/subhypergraph_search.pyx @@ -444,8 +444,8 @@ cdef class SubHypergraphSearch: EXAMPLES:: - sage: d = designs.projective_plane(3) - sage: d.isomorphic_substructures_iterator(d).relabel_heuristic() + sage: d = designs.projective_plane(3) # needs sage.schemes + sage: d.isomorphic_substructures_iterator(d).relabel_heuristic() # needs sage.schemes """ cdef hypergraph h2 = self.h2 cdef int x,y,i diff --git a/src/sage/combinat/designs/twographs.py b/src/sage/combinat/designs/twographs.py index 32a844083b9..b36d23f0162 100644 --- a/src/sage/combinat/designs/twographs.py +++ b/src/sage/combinat/designs/twographs.py @@ -84,8 +84,8 @@ def __init__(self, points=None, blocks=None, incidence_matrix=None, Traceback (most recent call last): ... AssertionError: the structure is not a 2-graph! - sage: p = graphs.PetersenGraph().twograph() # optional - sage.modules - sage: TwoGraph(p, check=True) # optional - sage.modules + sage: p = graphs.PetersenGraph().twograph() # needs sage.modules + sage: TwoGraph(p, check=True) # needs sage.modules Incidence structure with 10 points and 60 blocks """ IncidenceStructure.__init__(self, points=points, blocks=blocks, @@ -108,15 +108,16 @@ def is_regular_twograph(self, alpha=False): EXAMPLES:: - sage: p = graphs.PetersenGraph().twograph() # optional - sage.modules - sage: p.is_regular_twograph(alpha=True) # optional - sage.modules + sage: # needs sage.modules + sage: p = graphs.PetersenGraph().twograph() + sage: p.is_regular_twograph(alpha=True) 4 - sage: p.is_regular_twograph() # optional - sage.modules + sage: p.is_regular_twograph() True - sage: p = graphs.PathGraph(5).twograph() # optional - sage.modules - sage: p.is_regular_twograph(alpha=True) # optional - sage.modules + sage: p = graphs.PathGraph(5).twograph() + sage: p.is_regular_twograph(alpha=True) False - sage: p.is_regular_twograph() # optional - sage.modules + sage: p.is_regular_twograph() False """ r, (_, _, _, a) = self.is_t_design(t=2, k=3, return_parameters=True) @@ -139,8 +140,8 @@ def descendant(self, v): EXAMPLES:: - sage: p = graphs.PetersenGraph().twograph().descendant(0) # optional - sage.modules - sage: p.is_strongly_regular(parameters=True) # optional - sage.modules + sage: p = graphs.PetersenGraph().twograph().descendant(0) # needs sage.modules + sage: p.is_strongly_regular(parameters=True) # needs sage.modules (9, 4, 1, 2) """ from sage.graphs.graph import Graph @@ -159,14 +160,14 @@ def complement(self): EXAMPLES:: - sage: p = graphs.CompleteGraph(8).line_graph().twograph() # optional - sage.modules - sage: pc = p.complement(); pc # optional - sage.modules + sage: p = graphs.CompleteGraph(8).line_graph().twograph() # needs sage.modules + sage: pc = p.complement(); pc # needs sage.modules Incidence structure with 28 points and 1260 blocks TESTS:: sage: from sage.combinat.designs.twographs import is_twograph - sage: is_twograph(pc) # optional - sage.modules + sage: is_twograph(pc) # needs sage.modules True """ return super().complement(uniform=True) @@ -192,7 +193,7 @@ def taylor_twograph(q): EXAMPLES:: sage: from sage.combinat.designs.twographs import taylor_twograph - sage: T = taylor_twograph(3); T # optional - sage.rings.finite_rings + sage: T = taylor_twograph(3); T # needs sage.rings.finite_rings Incidence structure with 28 points and 1260 blocks """ from sage.graphs.generators.classical_geometries import TaylorTwographSRG @@ -211,25 +212,25 @@ def is_twograph(T): a two-graph from a graph:: sage: from sage.combinat.designs.twographs import (is_twograph, TwoGraph) - sage: p = graphs.PetersenGraph().twograph() # optional - sage.modules - sage: is_twograph(p) # optional - sage.modules + sage: p = graphs.PetersenGraph().twograph() # needs sage.modules + sage: is_twograph(p) # needs sage.modules True a non-regular 2-uniform hypergraph which is a two-graph:: - sage: is_twograph(TwoGraph([[1,2,3],[1,2,4]])) # optional - sage.modules + sage: is_twograph(TwoGraph([[1,2,3],[1,2,4]])) True TESTS: wrong size of blocks:: - sage: is_twograph(designs.projective_plane(3)) + sage: is_twograph(designs.projective_plane(3)) # needs sage.schemes False a triple system which is not a two-graph:: - sage: is_twograph(designs.projective_plane(2)) + sage: is_twograph(designs.projective_plane(2)) # needs sage.schemes False """ if not T.is_uniform(3): @@ -285,14 +286,14 @@ def twograph_descendant(G, v, name=None): sage: T8 = graphs.CompleteGraph(8).line_graph() sage: v = T8.vertices(sort=True)[0] - sage: twograph_descendant(T8, v) == T8.twograph().descendant(v) # optional - sage.modules + sage: twograph_descendant(T8, v) == T8.twograph().descendant(v) # needs sage.modules True sage: twograph_descendant(T8, v).is_strongly_regular(parameters=True) (27, 16, 10, 8) sage: p = graphs.PetersenGraph() - sage: twograph_descendant(p,5) + sage: twograph_descendant(p, 5) Graph on 9 vertices - sage: twograph_descendant(p,5,name=True) + sage: twograph_descendant(p, 5, name=True) descendant of Petersen graph at 5: Graph on 9 vertices """ G = G.seidel_switching(G.neighbors(v),inplace=False)