From 49ae09d68c23ecf4f94332187d2560144bcb6f50 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Tue, 5 Aug 2014 17:27:14 +0200 Subject: [PATCH] trac #16766: Improve the doc of combinat/designs/ --- src/doc/en/reference/combinat/designs.rst | 26 ++++++--- src/sage/combinat/designs/bibd.py | 44 ++++++++------- src/sage/combinat/designs/block_design.py | 3 +- src/sage/combinat/designs/design_catalog.py | 22 ++++---- .../combinat/designs/difference_family.py | 19 +++++++ src/sage/combinat/designs/ext_rep.py | 16 ++++-- .../combinat/designs/incidence_structures.py | 34 +++++++++--- src/sage/combinat/designs/latin_squares.py | 26 ++++++--- .../combinat/designs/orthogonal_arrays.py | 54 +++++++++++++++---- .../designs/orthogonal_arrays_recursive.py | 8 ++- 10 files changed, 180 insertions(+), 72 deletions(-) diff --git a/src/doc/en/reference/combinat/designs.rst b/src/doc/en/reference/combinat/designs.rst index 9fbb579f291..eb2181fac16 100644 --- a/src/doc/en/reference/combinat/designs.rst +++ b/src/doc/en/reference/combinat/designs.rst @@ -1,26 +1,40 @@ Designs and Incidence Structures ================================ +All designs can be accessed by ``designs.`` and are listed in +the design catalog: + .. toctree:: :maxdepth: 1 - ../sage/combinat/designs/covering_design - ../sage/combinat/designs/ext_rep - ../sage/combinat/designs/incidence_structures ../sage/combinat/designs/design_catalog -Constructions -------------- +**Design-related classes** + +.. toctree:: + :maxdepth: 1 + + ../sage/combinat/designs/incidence_structures + ../sage/combinat/designs/covering_design + +**Constructions** .. toctree:: :maxdepth: 1 ../sage/combinat/designs/block_design ../sage/combinat/designs/bibd - ../sage/combinat/designs/steiner_quadruple_systems ../sage/combinat/designs/latin_squares ../sage/combinat/designs/orthogonal_arrays ../sage/combinat/designs/orthogonal_arrays_recursive ../sage/combinat/designs/difference_family + ../sage/combinat/designs/steiner_quadruple_systems ../sage/combinat/designs/database +**Technical things** + +.. toctree:: + :maxdepth: 1 + + ../sage/combinat/designs/ext_rep + ../sage/combinat/designs/designs_pyx diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 238254209e1..0185dcd962f 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -1,27 +1,34 @@ r""" Balanced Incomplete Block Designs (BIBD) -This module implements two constructions of Balanced Incomplete Block Designs: +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`:: -* Steiner Triple Systems, i.e. `(v,3,1)`-BIBD. -* `K_4`-decompositions of `K_v`, i.e. `(v,4,1)`-BIBD. + sage: designs.balanced_incomplete_block_design(7,3) -These BIBD can be obtained through the :func:`balanced_incomplete_block_design` -method, available in Sage as ``designs.balanced_incomplete_block_design``. +In particular, Sage can build a `(v,k,1)`-BIBD when one exists for all `k\leq +5`. The following functions are available: -EXAMPLES:: +It defines the following functions: + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :func:`balanced_incomplete_block_design` | Returns a BIBD of parameters `v,k`. + :func:`BIBD_from_TD` | Returns a BIBD through TD-based constructions. + :func:`BIBD_from_difference_family` | Return the BIBD associated to the difference family ``D`` on the group ``G``. + :func:`BIBD_from_PBD` | Returns a `(v,k,1)`-BIBD from a `(r,K)`-PBD where `r=(v-1)/(k-1)`. + :func:`PBD_from_TD` | Returns a `(kt,\{k,t\})`-PBD if `u=0` and a `(kt+u,\{k,k+1,t,u\})`-PBD otherwise. + :func:`steiner_triple_system` | Returns a Steiner Triple System. + :func:`v_5_1_BIBD` | Returns a `(v,5,1)`-BIBD. + :func:`v_4_1_BIBD` | Returns a `(v,4,1)`-BIBD. + :func:`PBD_4_5_8_9_12` | Returns a `(v,\{4,5,8,9,12\})`-PBD on `v` elements. + :func:`BIBD_5q_5_for_q_prime_power` | Returns a `(5q,5,1)`-BIBD with `q\equiv 1\pmod 4` a prime power. - sage: designs.balanced_incomplete_block_design(7,3) - Incidence structure with 7 points and 7 blocks - sage: designs.balanced_incomplete_block_design(7,3).blocks() - [[0, 1, 3], [0, 2, 4], [0, 5, 6], [1, 2, 6], [1, 4, 5], [2, 3, 5], [3, 4, 6]] - sage: designs.balanced_incomplete_block_design(13,4).blocks() - [[0, 1, 2, 12], [0, 3, 6, 9], [0, 4, 8, 10], [0, 5, 7, 11], [1, 3, 8, 11], - [1, 4, 7, 9], [1, 5, 6, 10], [2, 3, 7, 10], [2, 4, 6, 11], [2, 5, 8, 9], - [3, 4, 5, 12], [6, 7, 8, 12], [9, 10, 11, 12]] -`K_4`-decompositions of `K_v` ------------------------------ +**Construction of BIBD when** `k=4` Decompositions of `K_v` into `K_4` (i.e. `(v,4,1)`-BIBD) are built following Douglas Stinson's construction as presented in [Stinson2004]_ page 167. It is @@ -30,8 +37,7 @@ can always be transformed into a `((k-1)v+1,4,1)`-BIBD, which covers all possible cases of `(v,4,1)`-BIBD. -`K_5`-decompositions of `K_v` ------------------------------ +**Construction of BIBD when** `k=5` Decompositions of `K_v` into `K_4` (i.e. `(v,4,1)`-BIBD) are built following Clayton Smith's construction [ClaytonSmith]_. @@ -796,7 +802,7 @@ def _relabel_bibd(B,n,p=None): def PBD_4_5_8_9_12(v, check=True): """ - Returns a `(v,\{4,5,8,9,12\})-`PBD on `v` elements. + Returns a `(v,\{4,5,8,9,12\})`-PBD on `v` elements. A `(v,\{4,5,8,9,12\})`-PBD exists if and only if `v\equiv 0,1 \pmod 4`. The construction implemented here appears page 168 in [Stinson2004]_. diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index b11b7e86ed5..da7356ef0d7 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -3,8 +3,7 @@ A *block design* is a set together with a family of subsets (repeated subsets are allowed) whose members are chosen to satisfy some set of properties that are -deemed useful for a particular application. See :wikipedia:`Block_design`. It is -an object equivalent to an incidence structure. +deemed useful for a particular application. See :wikipedia:`Block_design`. REFERENCES: diff --git a/src/sage/combinat/designs/design_catalog.py b/src/sage/combinat/designs/design_catalog.py index ffa0fdeecfa..e98f1a18a56 100644 --- a/src/sage/combinat/designs/design_catalog.py +++ b/src/sage/combinat/designs/design_catalog.py @@ -1,9 +1,8 @@ r""" Catalog of designs -This module gathers all designs that can be reached from a Sage sessions -through the ``designs`` objects. In order to create the Witt design on 24 points -it is sufficient to type:: +This module gathers all designs that can be reached through +``designs.``. Example with the the Witt design on 24 points:: sage: designs.WittDesign(24) # optional - gap_packages Incidence structure with 24 points and 759 blocks @@ -13,13 +12,11 @@ sage: designs.steiner_triple_system(19) Incidence structure with 19 points and 57 blocks -Online database -- Jolla Covering Repository (LJCR) : +**La Jolla Covering Repository** -There exists an online database of the best known covering designs, the La Jolla -Covering Repository (LJCR), available at [1]_. As it is over 60MB and changes -frequently that database is not included in Sage, but one can obtain individual -coverings and block designs from the LJCR using the method -:meth:`designs.best_known_covering_design_from_LJCR +The La Jolla Covering Repository (LJCR, see [1]_) is an online database of +covering designs. As it is frequently updated, it is not included in Sage, but +one can query it through :meth:`designs.best_known_covering_design_from_LJCR `:: sage: C = designs.best_known_covering_design_from_LJCR(7, 3, 2) # optional - internet @@ -31,7 +28,9 @@ sage: C.incidence_structure() # optional - internet Incidence structure with 7 points and 7 blocks -Currently, this module gathers the following designs : +**Design constructors** + +This module gathers the following designs : .. csv-table:: :class: contentstable @@ -40,7 +39,7 @@ :meth:`~sage.combinat.designs.block_design.ProjectiveGeometryDesign` :meth:`~sage.combinat.designs.block_design.DesarguesianProjectivePlaneDesign` - :meth:`~sage.combinat.designs.bibd.BalancedIncompleteBlockDesign` + :meth:`~sage.combinat.designs.bibd.balanced_incomplete_block_design` :meth:`~sage.combinat.designs.block_design.AffineGeometryDesign` :meth:`~sage.combinat.designs.block_design.WittDesign` :meth:`~sage.combinat.designs.block_design.HadamardDesign` @@ -48,6 +47,7 @@ :meth:`~sage.combinat.designs.latin_squares.mutually_orthogonal_latin_squares` :meth:`~sage.combinat.designs.orthogonal_arrays.transversal_design` :meth:`~sage.combinat.designs.orthogonal_arrays.orthogonal_array` + :meth:`~sage.combinat.designs.orthogonal_arrays.incomplete_orthogonal_array` :meth:`~sage.combinat.designs.bibd.steiner_triple_system` :meth:`~sage.combinat.designs.steiner_quadruple_systems.steiner_quadruple_system` :meth:`~sage.combinat.designs.block_design.projective_plane` diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index 17736d94a05..adbfa04e088 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -1,10 +1,29 @@ r""" Difference families +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: OA = designs.difference_family(7,4,1) + +It defines the following functions: + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :func:`is_difference_family` | Return a (``k``, ``l``)-difference family on an Abelian group of size ``v``. + :func:`singer_difference_set` | Return a difference set associated to hyperplanes in a projective space. + :func:`difference_family` | Return a (``k``, ``l``)-difference family on an Abelian group of size ``v``. + REFERENCES: .. [Wi72] R. M. Wilson "Cyclotomy and difference families in elementary Abelian groups", J. of Num. Th., 4 (1972), pp. 17-47. + +Functions +--------- """ #***************************************************************************** # Copyright (C) 2014 Vincent Delecroix <20100.delecroix@gmail.com> diff --git a/src/sage/combinat/designs/ext_rep.py b/src/sage/combinat/designs/ext_rep.py index 1e0b1e75c8e..ba4ece869b2 100644 --- a/src/sage/combinat/designs/ext_rep.py +++ b/src/sage/combinat/designs/ext_rep.py @@ -1,4 +1,4 @@ -""" +r""" External Representations of Block Designs The "ext_rep" module is an API to the abstract tree represented by @@ -14,10 +14,16 @@ .. [D2009] P. Dobcsanyi et al. DesignTheory.org http://designtheory.org/database/ -TODO: The XML data from the designtheory.org database contains a wealth -of information about things like automorphism groups, transitivity, -cycle type representatives, etc, but none of this data is made -available through the current implementation. +.. TODO:: + + The XML data from the designtheory.org database contains a wealth of + information about things like automorphism groups, transitivity, cycle type + representatives, etc, but none of this data is made available through the + current implementation. + +Functions +--------- + """ ########################################################################### diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 40f7033ac04..fa3fe0d35c9 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -1,8 +1,29 @@ -""" +r""" Incidence structures (i.e. hypergraphs, i.e. set systems) -An incidence structure is specified by a list of points, blocks, and -an incidence matrix ([1]_, [2]_). +An incidence structure is specified by a list of points, blocks, or an incidence +matrix ([1]_, [2]_). :class:`IncidenceStructure` instances have the following methods: + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :meth:`~IncidenceStructure.ground_set` | Return the ground set (i.e the list of points). + :meth:`~IncidenceStructure.num_points` | Returns the size of the ground set. + :meth:`~IncidenceStructure.num_blocks` | Returns the number of blocks. + :meth:`~IncidenceStructure.blocks` | Return the list of blocks. + :meth:`~IncidenceStructure.block_sizes` | Return the set of block sizes. + :meth:`~IncidenceStructure.degree` | Returns the degree of a point ``p`` + :meth:`~IncidenceStructure.is_connected` | Test whether the design is connected. + :meth:`~IncidenceStructure.is_simple` | Test whether this design is simple (i.e. no repeated block). + :meth:`~IncidenceStructure.incidence_matrix` | Return the incidence matrix `A` of the design + :meth:`~IncidenceStructure.incidence_graph` | Returns the incidence graph of the design + :meth:`~IncidenceStructure.packing` | Returns a maximum packing + :meth:`~IncidenceStructure.is_t_design` | Test whether ``self`` is a `t-(v,k,l)` design. + :meth:`~IncidenceStructure.dual` | Returns the dual design. + :meth:`~IncidenceStructure.automorphism_group` | Returns the automorphism group + :meth:`~IncidenceStructure.edge_coloring` | Returns an optimal edge coloring` REFERENCES: @@ -445,7 +466,7 @@ def ground_set(self, copy=True): def num_points(self): r""" - The number of points in that design. + Returns the size of the ground set. EXAMPLES:: @@ -459,7 +480,7 @@ def num_points(self): def num_blocks(self): r""" - The number of blocks. + Returns the number of blocks. EXAMPLES:: @@ -472,7 +493,8 @@ def num_blocks(self): return len(self._blocks) def blocks(self, copy=True): - """Return the list of blocks. + """ + Return the list of blocks. INPUT: diff --git a/src/sage/combinat/designs/latin_squares.py b/src/sage/combinat/designs/latin_squares.py index 4c06d6359e9..047b31d0721 100644 --- a/src/sage/combinat/designs/latin_squares.py +++ b/src/sage/combinat/designs/latin_squares.py @@ -2,9 +2,8 @@ r""" Mutually Orthogonal Latin Squares (MOLS) -This module gathers Sage's functions related to Mutually Orthogonal Latin -Squares. Its main function is :func:`mutually_orthogonal_latin_squares` which -can be used to generate 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) @@ -12,10 +11,23 @@ `. If you are only interested by latin squares, see :mod:`~sage.combinat.matrices.latin`. -The following table prints the maximum number of MOLS that Sage can build for -every order `n<600`, similarly to the `table of MOLS -`_ -from the Handbook of Combinatorial Designs 2ed [DesignHandbook]_. +The functions defined here are + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :meth:`mutually_orthogonal_latin_squares` | Returns `k` Mutually Orthogonal `n\times n` Latin Squares. + :meth:`are_mutually_orthogonal_latin_squares` | Check that the list ``l`` of matrices in are MOLS. + :meth:`latin_square_product` | Returns the product of two (or more) latin squares. + :meth:`MOLS_table` | Prints the MOLS table. + +**Table of MOLS** + +Sage can produce a table of MOLS similar to the one from the Handbook of +Combinatorial Designs [DesignHandbook]_ (`available here +`_). :: diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index 94ca0323c7c..8d660df92cc 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -1,8 +1,39 @@ -""" +r""" Orthogonal arrays -This module gathers anything related to orthogonal arrays, and, incidentally, -to transversal designs. +This module gathers everything related to orthogonal arrays (or transversal +designs). One can build an `OA(k,n)` (or check that it can be built) with +:func:`orthogonal_array`:: + + sage: OA = designs.orthogonal_array(4,8) + +It defines the following functions: + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :meth:`orthogonal_array` | Return an orthogonal array of parameters `k,n,t`. + :meth:`transversal_design` | Return a transversal design of parameters `k,n`. + :meth:`incomplete_orthogonal_array` | Returns an `OA(k,n)-\sum_{1\leq i\leq x} OA(k,s_i)`. + + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :meth:`is_transversal_design` | Check that a given set of blocks ``B`` is a transversal design. + :meth:`~sage.combinat.designs.designs_pyx.is_orthogonal_array` | Check that the integer matrix `OA` is an `OA(k,n,t)`. + :meth:`wilson_construction` | Returns a `OA(k,rm+u)` from a truncated `OA(k+s,r)` by Wilson's construction. + :meth:`TD_product` | Returns the product of two transversal designs. + :meth:`OA_find_disjoint_blocks` | Returns `x` disjoint blocks contained in a given `OA(k,n)`. + :meth:`OA_relabel` | Returns a relabelled version of the OA. + :meth:`OA_from_quasi_difference_matrix` | Returns an Orthogonal Array from a Quasi-Difference matrix + :meth:`OA_from_Vmt` | Returns an Orthogonal Array from a `V(m,t)` + :meth:`OA_from_PBD` | Returns an `OA(k,n)` from a PBD + :meth:`OA_from_wider_OA` | Returns the first `k` columns of `OA`. .. TODO:: @@ -20,6 +51,7 @@ Functions --------- + """ from sage.misc.cachefunc import cached_function from sage.categories.sets_cat import EmptySetError @@ -162,7 +194,7 @@ def transversal_design(k,n,check=True,existence=False): Those two errors correspond respectively to the cases where Sage answer ``Unknown`` or ``False`` when the parameter ``existence`` is set to - ``True``: + ``True``:: sage: designs.transversal_design(47, 100, existence=True) Unknown @@ -170,8 +202,8 @@ def transversal_design(k,n,check=True,existence=False): False If for a given `n` you want to know the largest `k` for which Sage is able - to build a `TD(k,n)` just call the function with `k` set to `None` and - `existence` set to `True` as follows:: + to build a `TD(k,n)` just call the function with `k` set to ``None`` and + ``existence`` set to ``True`` as follows:: sage: designs.transversal_design(None, 6, existence=True) 3 @@ -705,8 +737,8 @@ def orthogonal_array(k,n,t=2,check=True,existence=False): 6 If you ask for an orthogonal array that does not exist, then the function - either raise an `EmptySetError` (if it knows that such an orthogonal array - does not exist) or a `NotImplementedError`:: + either raise an ``EmptySetError`` (if it knows that such an orthogonal array + does not exist) or a ``NotImplementedError``:: sage: designs.orthogonal_array(4,2) Traceback (most recent call last): @@ -1148,7 +1180,7 @@ def OA_relabel(OA,k,n,blocks=tuple(),matrix=None): True Making sure that ``[2,2,2,2]`` is a block of `OA(4,3)`. We do this - by relabelling block ``[0,0,0,0]`` which belongs to the design. + by relabelling block ``[0,0,0,0]`` which belongs to the design:: sage: designs.orthogonal_array(4,3) [[0, 0, 0, 0], [0, 1, 2, 1], [0, 2, 1, 2], [1, 0, 2, 2], [1, 1, 1, 0], [1, 2, 0, 1], [2, 0, 1, 1], [2, 1, 0, 2], [2, 2, 2, 0]] @@ -1356,12 +1388,12 @@ def OA_from_PBD(k,n,PBD, check=True): **Construction** - Let `\\mathcal B` be a `(n,K,1)`-PBD. If there exists for every `i\in K` a + Let `\mathcal B` be a `(n,K,1)`-PBD. If there exists for every `i\in K` a `TD(k,i)-i\times TD(k,1)` (i.e. if there exist `k` idempotent MOLS), then one can obtain a `OA(k,n)` by concatenating: - A `TD(k,i)-i\times TD(k,1)` defined over the elements of `B` for every `B - \in \\mathcal B`. + \in \mathcal B`. - The rows `(i,...,i)` of length `k` for every `i\in [n]`. diff --git a/src/sage/combinat/designs/orthogonal_arrays_recursive.py b/src/sage/combinat/designs/orthogonal_arrays_recursive.py index 757ab5b82eb..62e2d03104e 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_recursive.py +++ b/src/sage/combinat/designs/orthogonal_arrays_recursive.py @@ -2,9 +2,7 @@ Orthogonal arrays (Recursive constructions) This module implements several functions to find recursive constructions of -:mod:`Orthogonal Arrays ` using -Wilson's construction. To this end, they compute and truncate OA in specific -ways. +:mod:`Orthogonal Arrays `. The main function of this module, i.e. :func:`find_recursive_construction`, queries all implemented recursive constructions of designs. It is used by @@ -131,7 +129,7 @@ def find_wilson_decomposition_with_one_truncated_group(k,n): OUTPUT: - A pair `f,args` such that `f(*args)` is an `OA(k,n)` or ``False`` if no + A pair ``f,args`` such that ``f(*args)`` is an `OA(k,n)` or ``False`` if no decomposition with one truncated block was found. EXAMPLES:: @@ -227,7 +225,7 @@ def find_wilson_decomposition_with_two_truncated_groups(k,n): def simple_wilson_construction(k,r,m,u): r""" - Return an `OA(k,r*m + \sum u_i)` from Wilson construction. + Return an `OA(k,rm + \sum u_i)` from Wilson construction. INPUT: