Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Group-Divisible Designs (GDD)
This module gathers everything related to Group-Divisible Designs. The constructions defined here can be accessed through ``designs.<tab>``::
sage: designs.group_divisible_design(14,{4},{2}) Group Divisible Design on 14 points of type 2^7
The main function implemented here is :meth:`group_divisible_design` (which calls all others) and the main class is :class:`GroupDivisibleDesign`. The following functions are available:
.. csv-table:: :class: contentstable :widths: 30, 70 :delim: |
:func:`group_divisible_design` | Return a `(v,K,G)`-Group Divisible Design. :func:`GDD_4_2` | Return a `(2q,\{4\},\{2\})`-GDD for `q` a prime power with `q\equiv 1\pmod{6}`.
Functions --------- """ from __future__ import absolute_import, division
#***************************************************************************** # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from six.moves import range
from sage.arith.all import is_prime_power from sage.misc.unknown import Unknown from .incidence_structures import IncidenceStructure
def group_divisible_design(v,K,G,existence=False,check=False): r""" Return a `(v,K,G)`-Group Divisible Design.
A `(v,K,G)`-GDD is a pair `(\mathcal G, \mathcal B)` where:
- `\mathcal G` is a partition of `X=\bigcup \mathcal G` where `|X|=v`
- `\forall S\in \mathcal G, |S| \in G`
- `\forall S\in \mathcal B, |S| \in K`
- `\mathcal G\cup \mathcal B` is a `(v,K\cup G)`-PBD
For more information, see the documentation of :class:`~sage.combinat.designs.incidence_structures.GroupDivisibleDesign` or :class:`~sage.combinat.designs.bibd.PairwiseBalancedDesign`.
INPUT:
- ``v`` (integer)
- ``K,G`` (sets of integers)
- ``existence`` (boolean) -- instead of building the design, return:
- ``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`).
- ``False`` -- meaning that the design does not exist.
- ``check`` -- (boolean) Whether to check that output is correct before returning it. As this is expected to be useless (but we are cautious guys), you may want to disable it whenever you want speed. Set to ``True`` by default.
.. NOTE::
The GDD returned by this function are defined on ``range(v)``, and its groups are sets of consecutive integers.
EXAMPLES::
sage: designs.group_divisible_design(14,{4},{2}) Group Divisible Design on 14 points of type 2^7 """
# from a (v+1,k,1)-BIBD len(K) == 1 and G[0]+1 in K): return balanced_incomplete_block_design(v+1,k,existence=True)
# (v,{4},{2})-GDD K == [4] and G == [2] and GDD_4_2(v//2,existence=True)): return True
# From a TD(k,g) elif (len(G) == 1 and len(K) == 1 and K[0]*G[0] == v): from .orthogonal_arrays import transversal_design return transversal_design(k=K[0],n=G[0],existence=existence)
groups = groups, blocks = blocks, G = G, K = K, check = check, copy = True)
if existence: return Unknown raise NotImplementedError
def GDD_4_2(q,existence=False,check=True): r""" Return a `(2q,\{4\},\{2\})`-GDD for `q` a prime power with `q\equiv 1\pmod{6}`.
This method implements Lemma VII.5.17 from [BJL99] (p.495).
INPUT:
- ``q`` (integer)
- ``existence`` (boolean) -- instead of building the design, return:
- ``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`).
- ``False`` -- meaning that the design does not exist.
- ``check`` -- (boolean) Whether to check that output is correct before returning it. As this is expected to be useless (but we are cautious guys), you may want to disable it whenever you want speed. Set to ``True`` by default.
EXAMPLES::
sage: from sage.combinat.designs.group_divisible_designs import GDD_4_2 sage: GDD_4_2(7,existence=True) True sage: GDD_4_2(7) Group Divisible Design on 14 points of type 2^7 sage: GDD_4_2(8,existence=True) Unknown sage: GDD_4_2(8) Traceback (most recent call last): ... NotImplementedError """
# A first parallel class is defined. G acts on it, which yields all others. for i in range((q - 1) // 6)]
for S in first_class] for g in G for j in range(2)]
groups = [[i,i+1] for i in range(0,2*q,2)], blocks = sum(classes,[]), K = [4], G = [2], check = check, copy = False)
class GroupDivisibleDesign(IncidenceStructure): r""" Group Divisible Design (GDD)
Let `K` and `G` be sets of positive integers and let `\lambda` be a positive integer. A Group Divisible Design of index `\lambda` and order `v` is a triple `(V,\mathcal G,\mathcal B)` where:
- `V` is a set of cardinality `v`
- `\mathcal G` is a partition of `V` into groups whose size belongs to `G`
- `\mathcal B` is a family of subsets of `V` whose size belongs to `K` such that any two points `p_1,p_2\in V` from different groups appear simultaneously in exactly `\lambda` elements of `\mathcal B`. Besides, a group and a block intersect on at most one point.
If `K=\{k_1,...,k_l\}` and `G` has exactly `m_i` groups of cardinality `k_i` then `G` is said to have type `k_1^{m_1}...k_l^{m_l}`.
INPUT:
- ``points`` -- the underlying set. If ``points`` is an integer `v`, then the set is considered to be `\{0, ..., v-1\}`.
- ``groups`` -- the groups of the design. Set to ``None`` for an automatic guess (this triggers ``check=True`` and can thus cost some time).
- ``blocks`` -- collection of blocks
- ``G`` -- list of integers of which the sizes of the groups must be elements. Set to ``None`` (automatic guess) by default.
- ``K`` -- list of integers of which the sizes of the blocks must be elements. Set to ``None`` (automatic guess) by default.
- ``lambd`` (integer) -- value of `\lambda`, set to `1` by default.
- ``check`` (boolean) -- whether to check that the design is indeed a `GDD` with the right parameters. Set to ``True`` by default.
- ``copy`` -- (use with caution) if set to ``False`` then ``blocks`` must be a list of lists of integers. The list will not be copied but will be modified in place (each block is sorted, and the whole list is sorted). Your ``blocks`` object will become the instance's internal data.
EXAMPLES::
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign sage: TD = designs.transversal_design(4,10) sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD Group Divisible Design on 40 points of type 10^4
With unspecified groups::
sage: D = designs.transversal_design(4,3).relabel(list('abcdefghiklm'),inplace=False).blocks() sage: GDD = GroupDivisibleDesign('abcdefghiklm',None,D) sage: sorted(GDD.groups()) [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['k', 'l', 'm']]
""" def __init__(self, points, groups, blocks, G=None, K=None, lambd=1, check=True, copy=True,**kwds): r""" Constructor function
EXAMPLES::
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign sage: TD = designs.transversal_design(4,10) sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD Group Divisible Design on 40 points of type 10^4 """
points, blocks, copy=copy, check=False, **kwds)
(copy is False and self._point_to_index is None)): else:
def groups(self): r""" Return the groups of the Group-Divisible Design.
EXAMPLES::
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign sage: TD = designs.transversal_design(4,10) sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD Group Divisible Design on 40 points of type 10^4 sage: GDD.groups() [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35, 36, 37, 38, 39]]
TESTS:
Non-integer ground set::
sage: TD=designs.transversal_design(5,5) sage: TD.relabel({i:chr(97+i) for i in range(25)}) sage: TD.groups() [['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']] """ else:
def __repr__(self): r""" Returns a string that describes self
EXAMPLES::
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign sage: TD = designs.transversal_design(4,10) sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD Group Divisible Design on 40 points of type 10^4 """
for s in sorted(set(group_sizes))]
gdd_type = "1^0"
|