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.
Files changed (260) hide show
  1. passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
  2. passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
  3. passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
  4. passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
  5. passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
  6. passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
  7. passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
  8. sage/all__sagemath_graphs.py +39 -0
  9. sage/combinat/abstract_tree.py +2723 -0
  10. sage/combinat/all__sagemath_graphs.py +34 -0
  11. sage/combinat/binary_tree.py +5306 -0
  12. sage/combinat/cluster_algebra_quiver/all.py +22 -0
  13. sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
  14. sage/combinat/cluster_algebra_quiver/interact.py +124 -0
  15. sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
  16. sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
  17. sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
  18. sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
  19. sage/combinat/designs/MOLS_handbook_data.py +570 -0
  20. sage/combinat/designs/all.py +58 -0
  21. sage/combinat/designs/bibd.py +1655 -0
  22. sage/combinat/designs/block_design.py +1071 -0
  23. sage/combinat/designs/covering_array.py +269 -0
  24. sage/combinat/designs/covering_design.py +530 -0
  25. sage/combinat/designs/database.py +5615 -0
  26. sage/combinat/designs/design_catalog.py +122 -0
  27. sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  28. sage/combinat/designs/designs_pyx.pxd +21 -0
  29. sage/combinat/designs/designs_pyx.pyx +993 -0
  30. sage/combinat/designs/difference_family.py +3951 -0
  31. sage/combinat/designs/difference_matrices.py +279 -0
  32. sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  33. sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
  34. sage/combinat/designs/ext_rep.py +1064 -0
  35. sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
  36. sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
  37. sage/combinat/designs/group_divisible_designs.py +361 -0
  38. sage/combinat/designs/incidence_structures.py +2357 -0
  39. sage/combinat/designs/latin_squares.py +581 -0
  40. sage/combinat/designs/orthogonal_arrays.py +2244 -0
  41. sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
  42. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
  44. sage/combinat/designs/resolvable_bibd.py +815 -0
  45. sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
  46. sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
  47. sage/combinat/designs/subhypergraph_search.pyx +530 -0
  48. sage/combinat/designs/twographs.py +306 -0
  49. sage/combinat/finite_state_machine.py +14874 -0
  50. sage/combinat/finite_state_machine_generators.py +2006 -0
  51. sage/combinat/graph_path.py +448 -0
  52. sage/combinat/interval_posets.py +3908 -0
  53. sage/combinat/nu_tamari_lattice.py +269 -0
  54. sage/combinat/ordered_tree.py +1446 -0
  55. sage/combinat/posets/all.py +46 -0
  56. sage/combinat/posets/bubble_shuffle.py +247 -0
  57. sage/combinat/posets/cartesian_product.py +493 -0
  58. sage/combinat/posets/d_complete.py +182 -0
  59. sage/combinat/posets/elements.py +273 -0
  60. sage/combinat/posets/forest.py +30 -0
  61. sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
  62. sage/combinat/posets/hasse_cython.pyx +174 -0
  63. sage/combinat/posets/hasse_diagram.py +3672 -0
  64. sage/combinat/posets/hochschild_lattice.py +158 -0
  65. sage/combinat/posets/incidence_algebras.py +794 -0
  66. sage/combinat/posets/lattices.py +5117 -0
  67. sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
  68. sage/combinat/posets/linear_extension_iterator.pyx +292 -0
  69. sage/combinat/posets/linear_extensions.py +1037 -0
  70. sage/combinat/posets/mobile.py +275 -0
  71. sage/combinat/posets/moebius_algebra.py +776 -0
  72. sage/combinat/posets/poset_examples.py +2178 -0
  73. sage/combinat/posets/posets.py +9360 -0
  74. sage/combinat/rooted_tree.py +1070 -0
  75. sage/combinat/shard_order.py +239 -0
  76. sage/combinat/tamari_lattices.py +384 -0
  77. sage/combinat/yang_baxter_graph.py +923 -0
  78. sage/databases/all__sagemath_graphs.py +1 -0
  79. sage/databases/knotinfo_db.py +1231 -0
  80. sage/ext_data/all__sagemath_graphs.py +1 -0
  81. sage/ext_data/graphs/graph_plot_js.html +330 -0
  82. sage/ext_data/kenzo/CP2.txt +45 -0
  83. sage/ext_data/kenzo/CP3.txt +349 -0
  84. sage/ext_data/kenzo/CP4.txt +4774 -0
  85. sage/ext_data/kenzo/README.txt +49 -0
  86. sage/ext_data/kenzo/S4.txt +20 -0
  87. sage/graphs/all.py +42 -0
  88. sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
  89. sage/graphs/asteroidal_triples.pyx +320 -0
  90. sage/graphs/base/all.py +1 -0
  91. sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  92. sage/graphs/base/boost_graph.pxd +106 -0
  93. sage/graphs/base/boost_graph.pyx +3045 -0
  94. sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  95. sage/graphs/base/c_graph.pxd +106 -0
  96. sage/graphs/base/c_graph.pyx +5096 -0
  97. sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sage/graphs/base/dense_graph.pxd +28 -0
  99. sage/graphs/base/dense_graph.pyx +801 -0
  100. sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
  101. sage/graphs/base/graph_backends.pxd +5 -0
  102. sage/graphs/base/graph_backends.pyx +797 -0
  103. sage/graphs/base/overview.py +85 -0
  104. sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  105. sage/graphs/base/sparse_graph.pxd +90 -0
  106. sage/graphs/base/sparse_graph.pyx +1653 -0
  107. sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  108. sage/graphs/base/static_dense_graph.pxd +5 -0
  109. sage/graphs/base/static_dense_graph.pyx +1032 -0
  110. sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sage/graphs/base/static_sparse_backend.pxd +27 -0
  112. sage/graphs/base/static_sparse_backend.pyx +1583 -0
  113. sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  114. sage/graphs/base/static_sparse_graph.pxd +37 -0
  115. sage/graphs/base/static_sparse_graph.pyx +1375 -0
  116. sage/graphs/bipartite_graph.py +2732 -0
  117. sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
  118. sage/graphs/centrality.pyx +1038 -0
  119. sage/graphs/cographs.py +519 -0
  120. sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
  121. sage/graphs/comparability.pyx +851 -0
  122. sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  123. sage/graphs/connectivity.pxd +157 -0
  124. sage/graphs/connectivity.pyx +4813 -0
  125. sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
  126. sage/graphs/convexity_properties.pxd +16 -0
  127. sage/graphs/convexity_properties.pyx +870 -0
  128. sage/graphs/digraph.py +4754 -0
  129. sage/graphs/digraph_generators.py +1993 -0
  130. sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
  131. sage/graphs/distances_all_pairs.pxd +12 -0
  132. sage/graphs/distances_all_pairs.pyx +2938 -0
  133. sage/graphs/domination.py +1363 -0
  134. sage/graphs/dot2tex_utils.py +100 -0
  135. sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  136. sage/graphs/edge_connectivity.pyx +1215 -0
  137. sage/graphs/generators/all.py +1 -0
  138. sage/graphs/generators/basic.py +1769 -0
  139. sage/graphs/generators/chessboard.py +538 -0
  140. sage/graphs/generators/classical_geometries.py +1611 -0
  141. sage/graphs/generators/degree_sequence.py +235 -0
  142. sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
  143. sage/graphs/generators/distance_regular.pyx +2846 -0
  144. sage/graphs/generators/families.py +4759 -0
  145. sage/graphs/generators/intersection.py +565 -0
  146. sage/graphs/generators/platonic_solids.py +262 -0
  147. sage/graphs/generators/random.py +2623 -0
  148. sage/graphs/generators/smallgraphs.py +5741 -0
  149. sage/graphs/generators/world_map.py +724 -0
  150. sage/graphs/generic_graph.py +26867 -0
  151. sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  152. sage/graphs/generic_graph_pyx.pxd +34 -0
  153. sage/graphs/generic_graph_pyx.pyx +1673 -0
  154. sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
  155. sage/graphs/genus.pyx +622 -0
  156. sage/graphs/graph.py +9645 -0
  157. sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sage/graphs/graph_coloring.pyx +2284 -0
  159. sage/graphs/graph_database.py +1177 -0
  160. sage/graphs/graph_decompositions/all.py +1 -0
  161. sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  162. sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
  163. sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
  164. sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
  165. sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  166. sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
  167. sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
  168. sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
  169. sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
  170. sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
  171. sage/graphs/graph_decompositions/graph_products.pyx +508 -0
  172. sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  173. sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
  174. sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
  175. sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  176. sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
  177. sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
  178. sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  179. sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
  180. sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
  181. sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
  182. sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
  183. sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
  184. sage/graphs/graph_editor.py +82 -0
  185. sage/graphs/graph_generators.py +3314 -0
  186. sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  187. sage/graphs/graph_generators_pyx.pyx +95 -0
  188. sage/graphs/graph_input.py +812 -0
  189. sage/graphs/graph_latex.py +2064 -0
  190. sage/graphs/graph_list.py +410 -0
  191. sage/graphs/graph_plot.py +1756 -0
  192. sage/graphs/graph_plot_js.py +338 -0
  193. sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
  194. sage/graphs/hyperbolicity.pyx +1704 -0
  195. sage/graphs/hypergraph_generators.py +364 -0
  196. sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sage/graphs/independent_sets.pxd +13 -0
  198. sage/graphs/independent_sets.pyx +402 -0
  199. sage/graphs/isgci.py +1033 -0
  200. sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
  201. sage/graphs/isoperimetric_inequalities.pyx +489 -0
  202. sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  203. sage/graphs/line_graph.pyx +743 -0
  204. sage/graphs/lovasz_theta.py +77 -0
  205. sage/graphs/matching.py +1633 -0
  206. sage/graphs/matching_covered_graph.py +3590 -0
  207. sage/graphs/orientations.py +1489 -0
  208. sage/graphs/partial_cube.py +459 -0
  209. sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
  210. sage/graphs/path_enumeration.pyx +2040 -0
  211. sage/graphs/pq_trees.py +1129 -0
  212. sage/graphs/print_graphs.py +201 -0
  213. sage/graphs/schnyder.py +865 -0
  214. sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
  215. sage/graphs/spanning_tree.pyx +1457 -0
  216. sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
  217. sage/graphs/strongly_regular_db.pyx +3340 -0
  218. sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
  219. sage/graphs/traversals.pxd +9 -0
  220. sage/graphs/traversals.pyx +1872 -0
  221. sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sage/graphs/trees.pxd +15 -0
  223. sage/graphs/trees.pyx +310 -0
  224. sage/graphs/tutte_polynomial.py +713 -0
  225. sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
  226. sage/graphs/views.pyx +794 -0
  227. sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
  228. sage/graphs/weakly_chordal.pyx +604 -0
  229. sage/groups/all__sagemath_graphs.py +1 -0
  230. sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
  231. sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
  232. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
  233. sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
  234. sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
  235. sage/knots/all.py +6 -0
  236. sage/knots/free_knotinfo_monoid.py +507 -0
  237. sage/knots/gauss_code.py +291 -0
  238. sage/knots/knot.py +682 -0
  239. sage/knots/knot_table.py +284 -0
  240. sage/knots/knotinfo.py +2900 -0
  241. sage/knots/link.py +4715 -0
  242. sage/sandpiles/all.py +13 -0
  243. sage/sandpiles/examples.py +225 -0
  244. sage/sandpiles/sandpile.py +6365 -0
  245. sage/topology/all.py +22 -0
  246. sage/topology/cell_complex.py +1214 -0
  247. sage/topology/cubical_complex.py +1976 -0
  248. sage/topology/delta_complex.py +1806 -0
  249. sage/topology/filtered_simplicial_complex.py +744 -0
  250. sage/topology/moment_angle_complex.py +823 -0
  251. sage/topology/simplicial_complex.py +5160 -0
  252. sage/topology/simplicial_complex_catalog.py +92 -0
  253. sage/topology/simplicial_complex_examples.py +1680 -0
  254. sage/topology/simplicial_complex_homset.py +205 -0
  255. sage/topology/simplicial_complex_morphism.py +836 -0
  256. sage/topology/simplicial_set.py +4102 -0
  257. sage/topology/simplicial_set_catalog.py +55 -0
  258. sage/topology/simplicial_set_constructions.py +2954 -0
  259. sage/topology/simplicial_set_examples.py +865 -0
  260. sage/topology/simplicial_set_morphism.py +1464 -0
@@ -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)