passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
- passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
- passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
- passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
- passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_graphs.py +39 -0
- sage/combinat/abstract_tree.py +2723 -0
- sage/combinat/all__sagemath_graphs.py +34 -0
- sage/combinat/binary_tree.py +5306 -0
- sage/combinat/cluster_algebra_quiver/all.py +22 -0
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
- sage/combinat/cluster_algebra_quiver/interact.py +124 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
- sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
- sage/combinat/designs/MOLS_handbook_data.py +570 -0
- sage/combinat/designs/all.py +58 -0
- sage/combinat/designs/bibd.py +1655 -0
- sage/combinat/designs/block_design.py +1071 -0
- sage/combinat/designs/covering_array.py +269 -0
- sage/combinat/designs/covering_design.py +530 -0
- sage/combinat/designs/database.py +5615 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/designs_pyx.pxd +21 -0
- sage/combinat/designs/designs_pyx.pyx +993 -0
- sage/combinat/designs/difference_family.py +3951 -0
- sage/combinat/designs/difference_matrices.py +279 -0
- sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
- sage/combinat/designs/ext_rep.py +1064 -0
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
- sage/combinat/designs/group_divisible_designs.py +361 -0
- sage/combinat/designs/incidence_structures.py +2357 -0
- sage/combinat/designs/latin_squares.py +581 -0
- sage/combinat/designs/orthogonal_arrays.py +2244 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
- sage/combinat/designs/resolvable_bibd.py +815 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +530 -0
- sage/combinat/designs/twographs.py +306 -0
- sage/combinat/finite_state_machine.py +14874 -0
- sage/combinat/finite_state_machine_generators.py +2006 -0
- sage/combinat/graph_path.py +448 -0
- sage/combinat/interval_posets.py +3908 -0
- sage/combinat/nu_tamari_lattice.py +269 -0
- sage/combinat/ordered_tree.py +1446 -0
- sage/combinat/posets/all.py +46 -0
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/cartesian_product.py +493 -0
- sage/combinat/posets/d_complete.py +182 -0
- sage/combinat/posets/elements.py +273 -0
- sage/combinat/posets/forest.py +30 -0
- sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3672 -0
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +794 -0
- sage/combinat/posets/lattices.py +5117 -0
- sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1037 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2178 -0
- sage/combinat/posets/posets.py +9360 -0
- sage/combinat/rooted_tree.py +1070 -0
- sage/combinat/shard_order.py +239 -0
- sage/combinat/tamari_lattices.py +384 -0
- sage/combinat/yang_baxter_graph.py +923 -0
- sage/databases/all__sagemath_graphs.py +1 -0
- sage/databases/knotinfo_db.py +1231 -0
- sage/ext_data/all__sagemath_graphs.py +1 -0
- sage/ext_data/graphs/graph_plot_js.html +330 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/all.py +42 -0
- sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +320 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/boost_graph.pxd +106 -0
- sage/graphs/base/boost_graph.pyx +3045 -0
- sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/c_graph.pxd +106 -0
- sage/graphs/base/c_graph.pyx +5096 -0
- sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +28 -0
- sage/graphs/base/dense_graph.pyx +801 -0
- sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/graph_backends.pxd +5 -0
- sage/graphs/base/graph_backends.pyx +797 -0
- sage/graphs/base/overview.py +85 -0
- sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/sparse_graph.pxd +90 -0
- sage/graphs/base/sparse_graph.pyx +1653 -0
- sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_dense_graph.pxd +5 -0
- sage/graphs/base/static_dense_graph.pyx +1032 -0
- sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1583 -0
- sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1375 -0
- sage/graphs/bipartite_graph.py +2732 -0
- sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +1038 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +851 -0
- sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +870 -0
- sage/graphs/digraph.py +4754 -0
- sage/graphs/digraph_generators.py +1993 -0
- sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/distances_all_pairs.pxd +12 -0
- sage/graphs/distances_all_pairs.pyx +2938 -0
- sage/graphs/domination.py +1363 -0
- sage/graphs/dot2tex_utils.py +100 -0
- sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/edge_connectivity.pyx +1215 -0
- sage/graphs/generators/all.py +1 -0
- sage/graphs/generators/basic.py +1769 -0
- sage/graphs/generators/chessboard.py +538 -0
- sage/graphs/generators/classical_geometries.py +1611 -0
- sage/graphs/generators/degree_sequence.py +235 -0
- sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4759 -0
- sage/graphs/generators/intersection.py +565 -0
- sage/graphs/generators/platonic_solids.py +262 -0
- sage/graphs/generators/random.py +2623 -0
- sage/graphs/generators/smallgraphs.py +5741 -0
- sage/graphs/generators/world_map.py +724 -0
- sage/graphs/generic_graph.py +26867 -0
- sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1673 -0
- sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +622 -0
- sage/graphs/graph.py +9645 -0
- sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1177 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
- sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +508 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
- sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
- sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
- sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
- sage/graphs/graph_editor.py +82 -0
- sage/graphs/graph_generators.py +3314 -0
- sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +95 -0
- sage/graphs/graph_input.py +812 -0
- sage/graphs/graph_latex.py +2064 -0
- sage/graphs/graph_list.py +410 -0
- sage/graphs/graph_plot.py +1756 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1704 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/independent_sets.pxd +13 -0
- sage/graphs/independent_sets.pyx +402 -0
- sage/graphs/isgci.py +1033 -0
- sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +489 -0
- sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +743 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3590 -0
- sage/graphs/orientations.py +1489 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/path_enumeration.pyx +2040 -0
- sage/graphs/pq_trees.py +1129 -0
- sage/graphs/print_graphs.py +201 -0
- sage/graphs/schnyder.py +865 -0
- sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1872 -0
- sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/trees.pxd +15 -0
- sage/graphs/trees.pyx +310 -0
- sage/graphs/tutte_polynomial.py +713 -0
- sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +604 -0
- sage/groups/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
- sage/knots/all.py +6 -0
- sage/knots/free_knotinfo_monoid.py +507 -0
- sage/knots/gauss_code.py +291 -0
- sage/knots/knot.py +682 -0
- sage/knots/knot_table.py +284 -0
- sage/knots/knotinfo.py +2900 -0
- sage/knots/link.py +4715 -0
- sage/sandpiles/all.py +13 -0
- sage/sandpiles/examples.py +225 -0
- sage/sandpiles/sandpile.py +6365 -0
- sage/topology/all.py +22 -0
- sage/topology/cell_complex.py +1214 -0
- sage/topology/cubical_complex.py +1976 -0
- sage/topology/delta_complex.py +1806 -0
- sage/topology/filtered_simplicial_complex.py +744 -0
- sage/topology/moment_angle_complex.py +823 -0
- sage/topology/simplicial_complex.py +5160 -0
- sage/topology/simplicial_complex_catalog.py +92 -0
- sage/topology/simplicial_complex_examples.py +1680 -0
- sage/topology/simplicial_complex_homset.py +205 -0
- sage/topology/simplicial_complex_morphism.py +836 -0
- sage/topology/simplicial_set.py +4102 -0
- sage/topology/simplicial_set_catalog.py +55 -0
- sage/topology/simplicial_set_constructions.py +2954 -0
- sage/topology/simplicial_set_examples.py +865 -0
- sage/topology/simplicial_set_morphism.py +1464 -0
Binary file
|
@@ -0,0 +1,339 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.libs.gap
|
3
|
+
r"""
|
4
|
+
Database of generalised quadrangles with spread
|
5
|
+
|
6
|
+
This module implements some construction of generalised quadrangles
|
7
|
+
with spread.
|
8
|
+
|
9
|
+
EXAMPLES::
|
10
|
+
|
11
|
+
sage: GQ, S = designs.generalised_quadrangle_with_spread(4, 16, check=False)
|
12
|
+
sage: GQ
|
13
|
+
Incidence structure with 325 points and 1105 blocks
|
14
|
+
sage: GQ2, O = designs.generalised_quadrangle_hermitian_with_ovoid(4)
|
15
|
+
sage: GQ2
|
16
|
+
Incidence structure with 1105 points and 325 blocks
|
17
|
+
sage: GQ3 = GQ.dual()
|
18
|
+
sage: set(GQ3._points) == set(GQ2._points)
|
19
|
+
True
|
20
|
+
sage: GQ2.is_isomorphic(GQ3) # long time
|
21
|
+
True
|
22
|
+
|
23
|
+
REFERENCES:
|
24
|
+
|
25
|
+
- [PT2009]_
|
26
|
+
|
27
|
+
- [TP1994]_
|
28
|
+
|
29
|
+
- :wikipedia:`Generalized_quadrangle`
|
30
|
+
|
31
|
+
AUTHORS:
|
32
|
+
|
33
|
+
- Ivo Maffei (2020-07-26): initial version
|
34
|
+
"""
|
35
|
+
|
36
|
+
# ****************************************************************************
|
37
|
+
# Copyright (C) 2020 Ivo Maffei <ivomaffei@gmail.com>
|
38
|
+
#
|
39
|
+
# This program is free software: you can redistribute it and/or modify
|
40
|
+
# it under the terms of the GNU General Public License as published by
|
41
|
+
# the Free Software Foundation, either version 2 of the License, or
|
42
|
+
# (at your option) any later version.
|
43
|
+
# https://www.gnu.org/licenses/
|
44
|
+
# ****************************************************************************
|
45
|
+
|
46
|
+
|
47
|
+
def generalised_quadrangle_with_spread(const int s, const int t,
|
48
|
+
existence=False, check=True):
|
49
|
+
r"""
|
50
|
+
Construct a generalised quadrangle GQ of order `(s,t)` with a spread S.
|
51
|
+
|
52
|
+
INPUT:
|
53
|
+
|
54
|
+
- ``s``, ``t`` -- integers; order of the generalised quadrangle
|
55
|
+
|
56
|
+
- ``existence`` -- boolean;
|
57
|
+
|
58
|
+
- ``check`` -- boolean; if ``True``, then Sage checks that the object built
|
59
|
+
is correct. (default: ``True``)
|
60
|
+
|
61
|
+
OUTPUT:
|
62
|
+
|
63
|
+
A pair `(GQ, S)` where `GQ` is a :class:`IncidenceStructure` representing
|
64
|
+
the generalised quadrangle and `S` is a list of blocks of `GQ` representing
|
65
|
+
the spread of `GQ`.
|
66
|
+
|
67
|
+
EXAMPLES::
|
68
|
+
|
69
|
+
sage: t = designs.generalised_quadrangle_with_spread(3, 9)
|
70
|
+
sage: t[0]
|
71
|
+
Incidence structure with 112 points and 280 blocks
|
72
|
+
sage: designs.generalised_quadrangle_with_spread(5, 25, existence=True)
|
73
|
+
True
|
74
|
+
sage: (designs.generalised_quadrangle_with_spread(4, 16, check=False))[0]
|
75
|
+
Incidence structure with 325 points and 1105 blocks
|
76
|
+
sage: designs.generalised_quadrangle_with_spread(0, 2, existence=True)
|
77
|
+
False
|
78
|
+
|
79
|
+
REFERENCES:
|
80
|
+
|
81
|
+
For more on generalised quadrangles and their spread see [PT2009]_ or
|
82
|
+
[TP1994]_.
|
83
|
+
|
84
|
+
TESTS::
|
85
|
+
|
86
|
+
sage: GQ, S = designs.generalised_quadrangle_with_spread(2, 4)
|
87
|
+
sage: GQ
|
88
|
+
Incidence structure with 27 points and 45 blocks
|
89
|
+
sage: designs.generalised_quadrangle_with_spread(3, 4)
|
90
|
+
Traceback (most recent call last):
|
91
|
+
...
|
92
|
+
RuntimeError: Sage can't build a GQ of order (3, 4) with a spread
|
93
|
+
sage: designs.generalised_quadrangle_with_spread(3, 4, existence=True)
|
94
|
+
Unknown
|
95
|
+
"""
|
96
|
+
from sage.combinat.designs.incidence_structures import IncidenceStructure
|
97
|
+
from sage.misc.unknown import Unknown
|
98
|
+
from sage.arith.misc import is_prime_power
|
99
|
+
|
100
|
+
if s < 1 or t < 1:
|
101
|
+
if existence:
|
102
|
+
return False
|
103
|
+
raise RuntimeError(f"No GQ of order ({s}, {t}) exists")
|
104
|
+
|
105
|
+
if s == 1 and t == 1: # we have a square
|
106
|
+
if existence:
|
107
|
+
return True
|
108
|
+
D = IncidenceStructure([[0, 1], [1, 2], [2, 3], [3, 0]])
|
109
|
+
return (D, [[0, 1], [2, 3]])
|
110
|
+
|
111
|
+
if is_prime_power(s) and t == s * s:
|
112
|
+
if existence:
|
113
|
+
return True
|
114
|
+
(GQ, S) = dual_GQ_ovoid(*generalised_quadrangle_hermitian_with_ovoid(s))
|
115
|
+
if check:
|
116
|
+
if not is_GQ_with_spread(GQ, S, s=s, t=t):
|
117
|
+
raise RuntimeError("Sage built a wrong GQ with spread")
|
118
|
+
return (GQ, S)
|
119
|
+
|
120
|
+
if existence:
|
121
|
+
return Unknown
|
122
|
+
raise RuntimeError(
|
123
|
+
f"Sage can't build a GQ of order ({s}, {t}) with a spread")
|
124
|
+
|
125
|
+
|
126
|
+
def is_GQ_with_spread(GQ, S, s=None, t=None):
|
127
|
+
r"""
|
128
|
+
Check if GQ is a generalised quadrangle of order `(s,t)` and
|
129
|
+
check that S is a spread of GQ
|
130
|
+
|
131
|
+
INPUT:
|
132
|
+
|
133
|
+
- ``GQ`` -- IncidenceStructure; the incidence structure that is supposed to
|
134
|
+
be a generalised quadrangle
|
135
|
+
|
136
|
+
- ``S`` -- iterable; the spread of ``GQ`` as an
|
137
|
+
iterable of the blocks of ``GQ``
|
138
|
+
|
139
|
+
- ``s``, ``t`` -- integers (optional); if `(s,t)` are given, then we check that
|
140
|
+
``GQ`` has order `(s,t)`
|
141
|
+
|
142
|
+
EXAMPLES::
|
143
|
+
|
144
|
+
sage: from sage.combinat.designs.gen_quadrangles_with_spread import *
|
145
|
+
sage: t = generalised_quadrangle_hermitian_with_ovoid(3)
|
146
|
+
sage: is_GQ_with_spread(*t)
|
147
|
+
Traceback (most recent call last):
|
148
|
+
...
|
149
|
+
TypeError: 'int' object is not iterable
|
150
|
+
sage: t = dual_GQ_ovoid(*t)
|
151
|
+
sage: is_GQ_with_spread(*t)
|
152
|
+
True
|
153
|
+
sage: is_GQ_with_spread(*t, s=3)
|
154
|
+
True
|
155
|
+
|
156
|
+
TESTS::
|
157
|
+
|
158
|
+
sage: from sage.combinat.designs.gen_quadrangles_with_spread import *
|
159
|
+
sage: t = generalised_quadrangle_hermitian_with_ovoid(2)
|
160
|
+
sage: t = dual_GQ_ovoid(*t)
|
161
|
+
sage: is_GQ_with_spread(*t, s=2, t=4)
|
162
|
+
True
|
163
|
+
sage: is_GQ_with_spread(*t, s=2)
|
164
|
+
True
|
165
|
+
sage: is_GQ_with_spread(*t, s=3)
|
166
|
+
False
|
167
|
+
"""
|
168
|
+
res = GQ.is_generalized_quadrangle(parameters=True)
|
169
|
+
if res is False \
|
170
|
+
or (s is not None and s != res[0]) \
|
171
|
+
or (t is not None and t != res[1]):
|
172
|
+
return False
|
173
|
+
|
174
|
+
# check spread
|
175
|
+
return GQ.is_spread(S)
|
176
|
+
|
177
|
+
|
178
|
+
def dual_GQ_ovoid(GQ, O):
|
179
|
+
r"""
|
180
|
+
Compute the dual incidence structure of GQ
|
181
|
+
and return the image of `O` under the dual map
|
182
|
+
|
183
|
+
INPUT:
|
184
|
+
|
185
|
+
- ``GQ`` -- IncidenceStructure; the generalised quadrangle we want
|
186
|
+
the dual of
|
187
|
+
|
188
|
+
- ``O`` -- iterable; the iterable of blocks we want to compute the dual
|
189
|
+
|
190
|
+
OUTPUT: a pair ``(D, S)`` where ``D`` is the dual of ``GQ`` and
|
191
|
+
``S`` is the dual of ``O``
|
192
|
+
|
193
|
+
EXAMPLES::
|
194
|
+
|
195
|
+
sage: from sage.combinat.designs.gen_quadrangles_with_spread import \
|
196
|
+
....: dual_GQ_ovoid
|
197
|
+
sage: t = designs.generalised_quadrangle_hermitian_with_ovoid(3)
|
198
|
+
sage: t[0].is_generalized_quadrangle(parameters=True)
|
199
|
+
(9, 3)
|
200
|
+
sage: t = dual_GQ_ovoid(*t)
|
201
|
+
sage: t[0].is_generalized_quadrangle(parameters=True)
|
202
|
+
(3, 9)
|
203
|
+
sage: all([x in t[0] for x in t[1]])
|
204
|
+
True
|
205
|
+
|
206
|
+
|
207
|
+
TESTS::
|
208
|
+
|
209
|
+
sage: from sage.combinat.designs.gen_quadrangles_with_spread import *
|
210
|
+
sage: t = designs.generalised_quadrangle_hermitian_with_ovoid(2)
|
211
|
+
sage: t = dual_GQ_ovoid(*t)
|
212
|
+
sage: t[0].is_generalized_quadrangle(parameters=True)
|
213
|
+
(2, 4)
|
214
|
+
sage: is_GQ_with_spread(*t)
|
215
|
+
True
|
216
|
+
"""
|
217
|
+
from sage.combinat.designs.incidence_structures import IncidenceStructure
|
218
|
+
|
219
|
+
# GQ.ground_set()[i] becomes newBlocks[i]
|
220
|
+
# GQ.blocks()[i] becomes i
|
221
|
+
newBlocks = [[] for _ in range(GQ.num_points())]
|
222
|
+
pointsToInt = {p: i for i, p in enumerate(GQ.ground_set())}
|
223
|
+
|
224
|
+
for i, b in enumerate(GQ.blocks()):
|
225
|
+
for p in b:
|
226
|
+
newBlocks[pointsToInt[p]].append(i)
|
227
|
+
|
228
|
+
S = [newBlocks[pointsToInt[p]] for p in O]
|
229
|
+
|
230
|
+
D = IncidenceStructure(newBlocks)
|
231
|
+
return (D, S)
|
232
|
+
|
233
|
+
|
234
|
+
def generalised_quadrangle_hermitian_with_ovoid(const int q):
|
235
|
+
r"""
|
236
|
+
Construct the generalised quadrangle `H(3,q^2)` with an ovoid.
|
237
|
+
|
238
|
+
The GQ has order `(q^2,q)`.
|
239
|
+
|
240
|
+
INPUT:
|
241
|
+
|
242
|
+
- ``q`` -- integer; a prime power
|
243
|
+
|
244
|
+
OUTPUT:
|
245
|
+
|
246
|
+
A pair ``(D, O)`` where ``D`` is an IncidenceStructure representing the
|
247
|
+
generalised quadrangle and ``O`` is a list of points of ``D`` which
|
248
|
+
constitute an ovoid of ``D``.
|
249
|
+
|
250
|
+
EXAMPLES::
|
251
|
+
|
252
|
+
sage: t = designs.generalised_quadrangle_hermitian_with_ovoid(4)
|
253
|
+
sage: t[0]
|
254
|
+
Incidence structure with 1105 points and 325 blocks
|
255
|
+
sage: len(t[1])
|
256
|
+
65
|
257
|
+
sage: G = t[0].intersection_graph([1]) # line graph
|
258
|
+
sage: G.is_strongly_regular(True)
|
259
|
+
(325, 68, 3, 17)
|
260
|
+
sage: set(t[0].block_sizes())
|
261
|
+
{17}
|
262
|
+
|
263
|
+
REFERENCES:
|
264
|
+
|
265
|
+
For more on `H(3,q^2)` and the construction implemented here see [PT2009]_
|
266
|
+
or [TP1994]_.
|
267
|
+
|
268
|
+
TESTS::
|
269
|
+
|
270
|
+
sage: from sage.combinat.designs.gen_quadrangles_with_spread import \
|
271
|
+
....: is_GQ_with_spread, dual_GQ_ovoid
|
272
|
+
sage: t = designs.generalised_quadrangle_hermitian_with_ovoid(3)
|
273
|
+
sage: t = dual_GQ_ovoid(*t)
|
274
|
+
sage: is_GQ_with_spread(*t, s=3, t=9)
|
275
|
+
True
|
276
|
+
sage: t = dual_GQ_ovoid(*(
|
277
|
+
....: designs.generalised_quadrangle_hermitian_with_ovoid(2)))
|
278
|
+
sage: t[0]
|
279
|
+
Incidence structure with 27 points and 45 blocks
|
280
|
+
sage: len(t[1])
|
281
|
+
9
|
282
|
+
"""
|
283
|
+
from sage.libs.gap.libgap import libgap
|
284
|
+
from sage.combinat.designs.incidence_structures import IncidenceStructure
|
285
|
+
from sage.arith.misc import is_prime_power
|
286
|
+
|
287
|
+
GU = libgap.GU(4, q)
|
288
|
+
Fq = libgap.GF(q * q)
|
289
|
+
zero = libgap.Zero(Fq)
|
290
|
+
one = libgap.One(Fq)
|
291
|
+
V = libgap.FullRowSpace(Fq, 4)
|
292
|
+
|
293
|
+
e1 = [one, zero, zero, zero] # isotropic point
|
294
|
+
|
295
|
+
points = list(libgap.Orbit(GU, e1, libgap.OnLines)) # all isotropic points
|
296
|
+
pointInt = { x: int(i + 1) for i, x in enumerate(points) }
|
297
|
+
# above we sum 1 because GAP starts at 1
|
298
|
+
|
299
|
+
GUp = libgap.Action(GU, points, libgap.OnLines)
|
300
|
+
|
301
|
+
e2 = [zero, one, zero, zero] # another isotropic point
|
302
|
+
line = V.Subspace([e1, e2]) # totally isotropic line
|
303
|
+
lineAsPoints = [libgap.Elements(libgap.Basis(b))[0]
|
304
|
+
for b in libgap.Elements(line.Subspaces(1))]
|
305
|
+
line = libgap.Set([pointInt[p] for p in lineAsPoints])
|
306
|
+
|
307
|
+
lines = libgap.Orbit(GUp, line, libgap.OnSets) # all isotropic lines
|
308
|
+
lines = [list(map(lambda x: int(x - 1), b)) for b in lines] # convert to int
|
309
|
+
# lines defines the GQ H(3, q^2)
|
310
|
+
|
311
|
+
# to find an ovoid, we embed H(3,q^2) in H(4,q^2)
|
312
|
+
# the embedding is (a,b,c,d) -> (a,b,0,c,d)
|
313
|
+
# then we find a point in the latter and not in the former
|
314
|
+
# this point will be collinear (in H(3,q^2)) to all points in an ovoid
|
315
|
+
if q % 2 == 1:
|
316
|
+
p, _ = is_prime_power(q, get_data=True)
|
317
|
+
a = (p - 1) // 2
|
318
|
+
aGap = zero
|
319
|
+
for i in range(a):
|
320
|
+
aGap += one
|
321
|
+
p = [zero, one, one, aGap, zero]
|
322
|
+
else:
|
323
|
+
a = libgap.PrimitiveRoot(Fq)**(q-1)
|
324
|
+
p = [zero, one, a+one, a, zero]
|
325
|
+
|
326
|
+
J = [[0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0],
|
327
|
+
[0, 1, 0, 0, 0], [1, 0, 0, 0, 0]]
|
328
|
+
J = libgap(J) # matrix of the invariant form of GU(5,q)
|
329
|
+
|
330
|
+
# p' is collinear to p iff p'Jp^q = 0
|
331
|
+
# note that p'Jp^q = bx^q + c where p' = (a,b,0,c,d) and p = (0,1,y,x,0)
|
332
|
+
ovoid = []
|
333
|
+
xq = p[3]**q
|
334
|
+
for p2 in points:
|
335
|
+
if p2[1]*xq + p2[2] == zero: # p collinear to p2
|
336
|
+
ovoid.append(pointInt[p2] - 1)
|
337
|
+
|
338
|
+
D = IncidenceStructure(lines)
|
339
|
+
return (D, ovoid)
|
@@ -0,0 +1,361 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.rings.finite_rings
|
3
|
+
r"""
|
4
|
+
Group-divisible designs (GDD)
|
5
|
+
|
6
|
+
This module gathers everything related to Group-Divisible Designs. The
|
7
|
+
constructions defined here can be accessed through ``designs.<tab>``::
|
8
|
+
|
9
|
+
sage: designs.group_divisible_design(14,{4},{2})
|
10
|
+
Group Divisible Design on 14 points of type 2^7
|
11
|
+
|
12
|
+
The main function implemented here is :meth:`group_divisible_design` (which
|
13
|
+
calls all others) and the main class is :class:`GroupDivisibleDesign`. The
|
14
|
+
following functions are available:
|
15
|
+
|
16
|
+
.. csv-table::
|
17
|
+
:class: contentstable
|
18
|
+
:widths: 30, 70
|
19
|
+
:delim: |
|
20
|
+
|
21
|
+
:func:`group_divisible_design` | Return a `(v,K,G)`-Group Divisible Design.
|
22
|
+
:func:`GDD_4_2` | Return a `(2q,\{4\},\{2\})`-GDD for `q` a prime power with `q\equiv 1\pmod{6}`.
|
23
|
+
|
24
|
+
Functions
|
25
|
+
---------
|
26
|
+
"""
|
27
|
+
|
28
|
+
# ****************************************************************************
|
29
|
+
# This program is free software: you can redistribute it and/or modify
|
30
|
+
# it under the terms of the GNU General Public License as published by
|
31
|
+
# the Free Software Foundation, either version 2 of the License, or
|
32
|
+
# (at your option) any later version.
|
33
|
+
# https://www.gnu.org/licenses/
|
34
|
+
# ****************************************************************************
|
35
|
+
|
36
|
+
from sage.arith.misc import is_prime_power
|
37
|
+
from sage.misc.unknown import Unknown
|
38
|
+
from .incidence_structures import IncidenceStructure
|
39
|
+
|
40
|
+
|
41
|
+
def group_divisible_design(v, K, G, existence=False, check=False):
|
42
|
+
r"""
|
43
|
+
Return a `(v,K,G)`-Group Divisible Design.
|
44
|
+
|
45
|
+
A `(v,K,G)`-GDD is a pair `(\mathcal G, \mathcal B)` where:
|
46
|
+
|
47
|
+
- `\mathcal G` is a partition of `X=\bigcup \mathcal G` where `|X|=v`
|
48
|
+
|
49
|
+
- `\forall S\in \mathcal G, |S| \in G`
|
50
|
+
|
51
|
+
- `\forall S\in \mathcal B, |S| \in K`
|
52
|
+
|
53
|
+
- `\mathcal G\cup \mathcal B` is a `(v,K\cup G)`-PBD
|
54
|
+
|
55
|
+
For more information, see the documentation of
|
56
|
+
:class:`~sage.combinat.designs.incidence_structures.GroupDivisibleDesign` or
|
57
|
+
:class:`~sage.combinat.designs.bibd.PairwiseBalancedDesign`.
|
58
|
+
|
59
|
+
INPUT:
|
60
|
+
|
61
|
+
- ``v`` -- integer
|
62
|
+
|
63
|
+
- ``K``, ``G`` -- sets of integers
|
64
|
+
|
65
|
+
- ``existence`` -- boolean; instead of building the design, return:
|
66
|
+
|
67
|
+
- ``True`` -- meaning that Sage knows how to build the design
|
68
|
+
|
69
|
+
- ``Unknown`` -- meaning that Sage does not know how to build the
|
70
|
+
design, but that the design may exist (see :mod:`sage.misc.unknown`)
|
71
|
+
|
72
|
+
- ``False`` -- meaning that the design does not exist
|
73
|
+
|
74
|
+
- ``check`` -- boolean (default: ``True``); whether to check that output is
|
75
|
+
correct before returning it. As this is expected to be useless, you may
|
76
|
+
want to disable it whenever you want speed.
|
77
|
+
|
78
|
+
.. NOTE::
|
79
|
+
|
80
|
+
The GDD returned by this function are defined on ``range(v)``, and its
|
81
|
+
groups are sets of consecutive integers.
|
82
|
+
|
83
|
+
EXAMPLES::
|
84
|
+
|
85
|
+
sage: designs.group_divisible_design(14,{4},{2})
|
86
|
+
Group Divisible Design on 14 points of type 2^7
|
87
|
+
"""
|
88
|
+
G = list(set(G))
|
89
|
+
K = list(set(K))
|
90
|
+
|
91
|
+
blocks = None
|
92
|
+
|
93
|
+
# from a (v+1,k,1)-BIBD
|
94
|
+
if len(G) == 1 == len(K) and G[0] + 1 in K:
|
95
|
+
from .bibd import balanced_incomplete_block_design
|
96
|
+
k = K[0]
|
97
|
+
if existence:
|
98
|
+
return balanced_incomplete_block_design(v + 1, k, existence=True)
|
99
|
+
BIBD = balanced_incomplete_block_design(v + 1, k)
|
100
|
+
groups = [[x for x in S if x != v] for S in BIBD if v in S]
|
101
|
+
d = {p: i for i, p in enumerate(sum(groups, []))}
|
102
|
+
d[v] = v
|
103
|
+
BIBD.relabel(d)
|
104
|
+
groups = [list(range((k - 1) * i, (k - 1) * (i + 1)))
|
105
|
+
for i in range(v // (k - 1))]
|
106
|
+
blocks = [S for S in BIBD if v not in S]
|
107
|
+
|
108
|
+
# (v,{4},{2})-GDD
|
109
|
+
elif (v % 2 == 0 and K == [4] and
|
110
|
+
G == [2] and GDD_4_2(v // 2, existence=True)):
|
111
|
+
if existence:
|
112
|
+
return True
|
113
|
+
return GDD_4_2(v // 2, check=check)
|
114
|
+
|
115
|
+
# From a TD(k,g)
|
116
|
+
elif len(G) == 1 == len(K) and K[0] * G[0] == v:
|
117
|
+
from .orthogonal_arrays import transversal_design
|
118
|
+
return transversal_design(k=K[0], n=G[0], existence=existence)
|
119
|
+
|
120
|
+
if blocks:
|
121
|
+
return GroupDivisibleDesign(v,
|
122
|
+
groups=groups,
|
123
|
+
blocks=blocks,
|
124
|
+
G=G,
|
125
|
+
K=K,
|
126
|
+
check=check,
|
127
|
+
copy=True)
|
128
|
+
|
129
|
+
if existence:
|
130
|
+
return Unknown
|
131
|
+
raise NotImplementedError
|
132
|
+
|
133
|
+
|
134
|
+
def GDD_4_2(q, existence=False, check=True):
|
135
|
+
r"""
|
136
|
+
Return a `(2q,\{4\},\{2\})`-GDD for `q` a prime power with `q\equiv 1\pmod{6}`.
|
137
|
+
|
138
|
+
This method implements Lemma VII.5.17 from [BJL99] (p.495).
|
139
|
+
|
140
|
+
INPUT:
|
141
|
+
|
142
|
+
- ``q`` -- integer
|
143
|
+
|
144
|
+
- ``existence`` -- boolean; instead of building the design, return:
|
145
|
+
|
146
|
+
- ``True`` -- meaning that Sage knows how to build the design
|
147
|
+
|
148
|
+
- ``Unknown`` -- meaning that Sage does not know how to build the
|
149
|
+
design, but that the design may exist (see :mod:`sage.misc.unknown`)
|
150
|
+
|
151
|
+
- ``False`` -- meaning that the design does not exist
|
152
|
+
|
153
|
+
- ``check`` -- boolean (default: ``True``); whether to check that output is
|
154
|
+
correct before returning it. As this is expected to be useless, you may
|
155
|
+
want to disable it whenever you want speed.
|
156
|
+
|
157
|
+
EXAMPLES::
|
158
|
+
|
159
|
+
sage: from sage.combinat.designs.group_divisible_designs import GDD_4_2
|
160
|
+
sage: GDD_4_2(7,existence=True)
|
161
|
+
True
|
162
|
+
sage: GDD_4_2(7)
|
163
|
+
Group Divisible Design on 14 points of type 2^7
|
164
|
+
sage: GDD_4_2(8,existence=True)
|
165
|
+
Unknown
|
166
|
+
sage: GDD_4_2(8)
|
167
|
+
Traceback (most recent call last):
|
168
|
+
...
|
169
|
+
NotImplementedError
|
170
|
+
"""
|
171
|
+
if q <= 1 or q % 6 != 1 or not is_prime_power(q):
|
172
|
+
if existence:
|
173
|
+
return Unknown
|
174
|
+
raise NotImplementedError
|
175
|
+
if existence:
|
176
|
+
return True
|
177
|
+
|
178
|
+
from sage.rings.finite_rings.finite_field_constructor import FiniteField
|
179
|
+
G = FiniteField(q, 'x')
|
180
|
+
w = G.primitive_element()
|
181
|
+
e = w**((q - 1) // 3)
|
182
|
+
|
183
|
+
# A first parallel class is defined. G acts on it, which yields all others.
|
184
|
+
first_class = [[(0, 0), (1, w**i), (1, e * w**i), (1, e * e * w**i)]
|
185
|
+
for i in range((q - 1) // 6)]
|
186
|
+
|
187
|
+
label = {p: i for i, p in enumerate(G)}
|
188
|
+
classes = [[[2 * label[x[1] + g] + (x[0] + j) % 2 for x in S]
|
189
|
+
for S in first_class]
|
190
|
+
for g in G for j in range(2)]
|
191
|
+
|
192
|
+
return GroupDivisibleDesign(2 * q,
|
193
|
+
groups=[[i, i + 1] for i in range(0, 2 * q, 2)],
|
194
|
+
blocks=sum(classes, []),
|
195
|
+
K=[4],
|
196
|
+
G=[2],
|
197
|
+
check=check,
|
198
|
+
copy=False)
|
199
|
+
|
200
|
+
|
201
|
+
class GroupDivisibleDesign(IncidenceStructure):
|
202
|
+
r"""
|
203
|
+
Group Divisible Design (GDD).
|
204
|
+
|
205
|
+
Let `K` and `G` be sets of positive integers and let `\lambda` be a positive
|
206
|
+
integer. A Group Divisible Design of index `\lambda` and order `v` is a
|
207
|
+
triple `(V,\mathcal G,\mathcal B)` where:
|
208
|
+
|
209
|
+
- `V` is a set of cardinality `v`
|
210
|
+
|
211
|
+
- `\mathcal G` is a partition of `V` into groups whose size belongs to `G`
|
212
|
+
|
213
|
+
- `\mathcal B` is a family of subsets of `V` whose size belongs to `K` such
|
214
|
+
that any two points `p_1,p_2\in V` from different groups appear
|
215
|
+
simultaneously in exactly `\lambda` elements of `\mathcal B`. Besides, a
|
216
|
+
group and a block intersect on at most one point.
|
217
|
+
|
218
|
+
If `K=\{k_1,...,k_l\}` and `G` has exactly `m_i` groups of cardinality `k_i`
|
219
|
+
then `G` is said to have type `k_1^{m_1}...k_l^{m_l}`.
|
220
|
+
|
221
|
+
INPUT:
|
222
|
+
|
223
|
+
- ``points`` -- the underlying set. If ``points`` is an integer `v`, then
|
224
|
+
the set is considered to be `\{0, ..., v-1\}`
|
225
|
+
|
226
|
+
- ``groups`` -- the groups of the design. Set to ``None`` for an automatic
|
227
|
+
guess (this triggers ``check=True`` and can thus cost some time)
|
228
|
+
|
229
|
+
- ``blocks`` -- collection of blocks
|
230
|
+
|
231
|
+
- ``G`` -- list of integers of which the sizes of the groups must be
|
232
|
+
elements. Set to ``None`` (automatic guess) by default
|
233
|
+
|
234
|
+
- ``K`` -- list of integers of which the sizes of the blocks must be
|
235
|
+
elements. Set to ``None`` (automatic guess) by default
|
236
|
+
|
237
|
+
- ``lambd`` -- integer (default: `1`); value of `\lambda`
|
238
|
+
|
239
|
+
- ``check`` -- boolean (default: ``True``); whether to check that the design is indeed a `GDD`
|
240
|
+
with the right parameters
|
241
|
+
|
242
|
+
- ``copy`` -- (use with caution) if set to ``False`` then ``blocks`` must be
|
243
|
+
a list of lists of integers. The list will not be copied but will be
|
244
|
+
modified in place (each block is sorted, and the whole list is
|
245
|
+
sorted). Your ``blocks`` object will become the instance's internal data.
|
246
|
+
|
247
|
+
EXAMPLES::
|
248
|
+
|
249
|
+
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign
|
250
|
+
sage: TD = designs.transversal_design(4,10)
|
251
|
+
sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)]
|
252
|
+
sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD
|
253
|
+
Group Divisible Design on 40 points of type 10^4
|
254
|
+
|
255
|
+
With unspecified groups::
|
256
|
+
|
257
|
+
sage: # needs sage.schemes
|
258
|
+
sage: D = designs.transversal_design(4,3).relabel(list('abcdefghiklm'),inplace=False).blocks()
|
259
|
+
sage: GDD = GroupDivisibleDesign('abcdefghiklm',None,D)
|
260
|
+
sage: sorted(GDD.groups())
|
261
|
+
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['k', 'l', 'm']]
|
262
|
+
"""
|
263
|
+
def __init__(self, points, groups, blocks, G=None, K=None, lambd=1,
|
264
|
+
check=True, copy=True, **kwds):
|
265
|
+
r"""
|
266
|
+
Constructor function.
|
267
|
+
|
268
|
+
EXAMPLES::
|
269
|
+
|
270
|
+
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign
|
271
|
+
sage: TD = designs.transversal_design(4,10)
|
272
|
+
sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)]
|
273
|
+
sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD
|
274
|
+
Group Divisible Design on 40 points of type 10^4
|
275
|
+
"""
|
276
|
+
from .designs_pyx import is_group_divisible_design
|
277
|
+
|
278
|
+
self._lambd = lambd
|
279
|
+
|
280
|
+
IncidenceStructure.__init__(self,
|
281
|
+
points,
|
282
|
+
blocks,
|
283
|
+
copy=copy,
|
284
|
+
check=False,
|
285
|
+
**kwds)
|
286
|
+
|
287
|
+
if groups is None or (copy is False and self._point_to_index is None):
|
288
|
+
self._groups = groups
|
289
|
+
elif self._point_to_index is None:
|
290
|
+
self._groups = [g[:] for g in groups]
|
291
|
+
else:
|
292
|
+
self._groups = [[self._point_to_index[x] for x in g] for g in groups]
|
293
|
+
|
294
|
+
if check or groups is None:
|
295
|
+
is_gdd = is_group_divisible_design(self._groups, self._blocks,
|
296
|
+
self.num_points(), G, K,
|
297
|
+
lambd, verbose=1)
|
298
|
+
assert is_gdd
|
299
|
+
if groups is None:
|
300
|
+
self._groups = is_gdd[1]
|
301
|
+
|
302
|
+
def groups(self):
|
303
|
+
r"""
|
304
|
+
Return the groups of the Group-Divisible Design.
|
305
|
+
|
306
|
+
EXAMPLES::
|
307
|
+
|
308
|
+
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign
|
309
|
+
sage: TD = designs.transversal_design(4,10)
|
310
|
+
sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)]
|
311
|
+
sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD
|
312
|
+
Group Divisible Design on 40 points of type 10^4
|
313
|
+
sage: GDD.groups()
|
314
|
+
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
315
|
+
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
|
316
|
+
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
|
317
|
+
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]]
|
318
|
+
|
319
|
+
TESTS:
|
320
|
+
|
321
|
+
Non-integer ground set::
|
322
|
+
|
323
|
+
sage: # needs sage.schemes
|
324
|
+
sage: TD = designs.transversal_design(5,5)
|
325
|
+
sage: TD.relabel({i: chr(97+i) for i in range(25)})
|
326
|
+
sage: TD.groups()
|
327
|
+
[['a', 'b', 'c', 'd', 'e'],
|
328
|
+
['f', 'g', 'h', 'i', 'j'],
|
329
|
+
['k', 'l', 'm', 'n', 'o'],
|
330
|
+
['p', 'q', 'r', 's', 't'],
|
331
|
+
['u', 'v', 'w', 'x', 'y']]
|
332
|
+
"""
|
333
|
+
if self._point_to_index is None:
|
334
|
+
return [list(g) for g in self._groups]
|
335
|
+
else:
|
336
|
+
return [[self._points[i] for i in g] for g in self._groups]
|
337
|
+
|
338
|
+
def __repr__(self):
|
339
|
+
r"""
|
340
|
+
Return a string that describes ``self``.
|
341
|
+
|
342
|
+
EXAMPLES::
|
343
|
+
|
344
|
+
sage: from sage.combinat.designs.group_divisible_designs import GroupDivisibleDesign
|
345
|
+
sage: TD = designs.transversal_design(4,10)
|
346
|
+
sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)]
|
347
|
+
sage: GDD = GroupDivisibleDesign(40,groups,TD); GDD
|
348
|
+
Group Divisible Design on 40 points of type 10^4
|
349
|
+
"""
|
350
|
+
group_sizes = [len(g) for g in self._groups]
|
351
|
+
|
352
|
+
gdd_type = ("{}^{}".format(s, group_sizes.count(s))
|
353
|
+
for s in sorted(set(group_sizes)))
|
354
|
+
gdd_type = ".".join(gdd_type)
|
355
|
+
|
356
|
+
if not gdd_type:
|
357
|
+
gdd_type = "1^0"
|
358
|
+
|
359
|
+
v = self.num_points()
|
360
|
+
|
361
|
+
return "Group Divisible Design on {} points of type {}".format(v, gdd_type)
|