passagemath-graphs 10.5.43__cp39-cp39-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 (258) hide show
  1. passagemath_graphs-10.5.43.dist-info/METADATA +293 -0
  2. passagemath_graphs-10.5.43.dist-info/RECORD +258 -0
  3. passagemath_graphs-10.5.43.dist-info/WHEEL +5 -0
  4. passagemath_graphs-10.5.43.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 +2552 -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 +125 -0
  15. sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
  16. sage/combinat/cluster_algebra_quiver/mutation_type.py +1556 -0
  17. sage/combinat/cluster_algebra_quiver/quiver.py +2262 -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 +534 -0
  25. sage/combinat/designs/database.py +5614 -0
  26. sage/combinat/designs/design_catalog.py +122 -0
  27. sage/combinat/designs/designs_pyx.cpython-39-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-39-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-39-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 +548 -0
  40. sage/combinat/designs/orthogonal_arrays.py +2243 -0
  41. sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
  42. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-39-aarch64-linux-gnu.so +0 -0
  43. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +966 -0
  44. sage/combinat/designs/resolvable_bibd.py +781 -0
  45. sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
  46. sage/combinat/designs/subhypergraph_search.cpython-39-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/cartesian_product.py +493 -0
  57. sage/combinat/posets/d_complete.py +182 -0
  58. sage/combinat/posets/elements.py +273 -0
  59. sage/combinat/posets/forest.py +30 -0
  60. sage/combinat/posets/hasse_cython.cpython-39-aarch64-linux-gnu.so +0 -0
  61. sage/combinat/posets/hasse_cython.pyx +174 -0
  62. sage/combinat/posets/hasse_diagram.py +3678 -0
  63. sage/combinat/posets/incidence_algebras.py +796 -0
  64. sage/combinat/posets/lattices.py +5119 -0
  65. sage/combinat/posets/linear_extension_iterator.cpython-39-aarch64-linux-gnu.so +0 -0
  66. sage/combinat/posets/linear_extension_iterator.pyx +292 -0
  67. sage/combinat/posets/linear_extensions.py +1039 -0
  68. sage/combinat/posets/mobile.py +275 -0
  69. sage/combinat/posets/moebius_algebra.py +776 -0
  70. sage/combinat/posets/poset_examples.py +2131 -0
  71. sage/combinat/posets/posets.py +9169 -0
  72. sage/combinat/rooted_tree.py +1070 -0
  73. sage/combinat/shard_order.py +239 -0
  74. sage/combinat/tamari_lattices.py +384 -0
  75. sage/combinat/yang_baxter_graph.py +923 -0
  76. sage/databases/all__sagemath_graphs.py +1 -0
  77. sage/databases/knotinfo_db.py +1230 -0
  78. sage/ext_data/all__sagemath_graphs.py +1 -0
  79. sage/ext_data/graphs/graph_plot_js.html +330 -0
  80. sage/ext_data/kenzo/CP2.txt +45 -0
  81. sage/ext_data/kenzo/CP3.txt +349 -0
  82. sage/ext_data/kenzo/CP4.txt +4774 -0
  83. sage/ext_data/kenzo/README.txt +49 -0
  84. sage/ext_data/kenzo/S4.txt +20 -0
  85. sage/graphs/all.py +42 -0
  86. sage/graphs/asteroidal_triples.cpython-39-aarch64-linux-gnu.so +0 -0
  87. sage/graphs/asteroidal_triples.pyx +299 -0
  88. sage/graphs/base/all.py +1 -0
  89. sage/graphs/base/boost_graph.cpython-39-aarch64-linux-gnu.so +0 -0
  90. sage/graphs/base/boost_graph.pxd +106 -0
  91. sage/graphs/base/boost_graph.pyx +3045 -0
  92. sage/graphs/base/c_graph.cpython-39-aarch64-linux-gnu.so +0 -0
  93. sage/graphs/base/c_graph.pxd +106 -0
  94. sage/graphs/base/c_graph.pyx +5096 -0
  95. sage/graphs/base/dense_graph.cpython-39-aarch64-linux-gnu.so +0 -0
  96. sage/graphs/base/dense_graph.pxd +26 -0
  97. sage/graphs/base/dense_graph.pyx +757 -0
  98. sage/graphs/base/graph_backends.cpython-39-aarch64-linux-gnu.so +0 -0
  99. sage/graphs/base/graph_backends.pxd +5 -0
  100. sage/graphs/base/graph_backends.pyx +797 -0
  101. sage/graphs/base/overview.py +85 -0
  102. sage/graphs/base/sparse_graph.cpython-39-aarch64-linux-gnu.so +0 -0
  103. sage/graphs/base/sparse_graph.pxd +90 -0
  104. sage/graphs/base/sparse_graph.pyx +1653 -0
  105. sage/graphs/base/static_dense_graph.cpython-39-aarch64-linux-gnu.so +0 -0
  106. sage/graphs/base/static_dense_graph.pxd +5 -0
  107. sage/graphs/base/static_dense_graph.pyx +1032 -0
  108. sage/graphs/base/static_sparse_backend.cpython-39-aarch64-linux-gnu.so +0 -0
  109. sage/graphs/base/static_sparse_backend.pxd +27 -0
  110. sage/graphs/base/static_sparse_backend.pyx +1580 -0
  111. sage/graphs/base/static_sparse_graph.cpython-39-aarch64-linux-gnu.so +0 -0
  112. sage/graphs/base/static_sparse_graph.pxd +37 -0
  113. sage/graphs/base/static_sparse_graph.pyx +1304 -0
  114. sage/graphs/bipartite_graph.py +2709 -0
  115. sage/graphs/centrality.cpython-39-aarch64-linux-gnu.so +0 -0
  116. sage/graphs/centrality.pyx +965 -0
  117. sage/graphs/cographs.py +519 -0
  118. sage/graphs/comparability.cpython-39-aarch64-linux-gnu.so +0 -0
  119. sage/graphs/comparability.pyx +813 -0
  120. sage/graphs/connectivity.cpython-39-aarch64-linux-gnu.so +0 -0
  121. sage/graphs/connectivity.pxd +157 -0
  122. sage/graphs/connectivity.pyx +4813 -0
  123. sage/graphs/convexity_properties.cpython-39-aarch64-linux-gnu.so +0 -0
  124. sage/graphs/convexity_properties.pxd +16 -0
  125. sage/graphs/convexity_properties.pyx +827 -0
  126. sage/graphs/digraph.py +4410 -0
  127. sage/graphs/digraph_generators.py +1921 -0
  128. sage/graphs/distances_all_pairs.cpython-39-aarch64-linux-gnu.so +0 -0
  129. sage/graphs/distances_all_pairs.pxd +12 -0
  130. sage/graphs/distances_all_pairs.pyx +2938 -0
  131. sage/graphs/domination.py +1363 -0
  132. sage/graphs/dot2tex_utils.py +100 -0
  133. sage/graphs/edge_connectivity.cpython-39-aarch64-linux-gnu.so +0 -0
  134. sage/graphs/edge_connectivity.pyx +1215 -0
  135. sage/graphs/generators/all.py +1 -0
  136. sage/graphs/generators/basic.py +1769 -0
  137. sage/graphs/generators/chessboard.py +538 -0
  138. sage/graphs/generators/classical_geometries.py +1611 -0
  139. sage/graphs/generators/degree_sequence.py +235 -0
  140. sage/graphs/generators/distance_regular.cpython-39-aarch64-linux-gnu.so +0 -0
  141. sage/graphs/generators/distance_regular.pyx +2846 -0
  142. sage/graphs/generators/families.py +4749 -0
  143. sage/graphs/generators/intersection.py +565 -0
  144. sage/graphs/generators/platonic_solids.py +262 -0
  145. sage/graphs/generators/random.py +2623 -0
  146. sage/graphs/generators/smallgraphs.py +5741 -0
  147. sage/graphs/generators/world_map.py +724 -0
  148. sage/graphs/generic_graph.py +26395 -0
  149. sage/graphs/generic_graph_pyx.cpython-39-aarch64-linux-gnu.so +0 -0
  150. sage/graphs/generic_graph_pyx.pxd +34 -0
  151. sage/graphs/generic_graph_pyx.pyx +1626 -0
  152. sage/graphs/genus.cpython-39-aarch64-linux-gnu.so +0 -0
  153. sage/graphs/genus.pyx +623 -0
  154. sage/graphs/graph.py +9362 -0
  155. sage/graphs/graph_coloring.cpython-39-aarch64-linux-gnu.so +0 -0
  156. sage/graphs/graph_coloring.pyx +2284 -0
  157. sage/graphs/graph_database.py +1122 -0
  158. sage/graphs/graph_decompositions/all.py +1 -0
  159. sage/graphs/graph_decompositions/bandwidth.cpython-39-aarch64-linux-gnu.so +0 -0
  160. sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
  161. sage/graphs/graph_decompositions/clique_separators.cpython-39-aarch64-linux-gnu.so +0 -0
  162. sage/graphs/graph_decompositions/clique_separators.pyx +595 -0
  163. sage/graphs/graph_decompositions/cutwidth.cpython-39-aarch64-linux-gnu.so +0 -0
  164. sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
  165. sage/graphs/graph_decompositions/fast_digraph.cpython-39-aarch64-linux-gnu.so +0 -0
  166. sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
  167. sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
  168. sage/graphs/graph_decompositions/graph_products.cpython-39-aarch64-linux-gnu.so +0 -0
  169. sage/graphs/graph_decompositions/graph_products.pyx +462 -0
  170. sage/graphs/graph_decompositions/modular_decomposition.cpython-39-aarch64-linux-gnu.so +0 -0
  171. sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
  172. sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
  173. sage/graphs/graph_decompositions/slice_decomposition.cpython-39-aarch64-linux-gnu.so +0 -0
  174. sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
  175. sage/graphs/graph_decompositions/slice_decomposition.pyx +1080 -0
  176. sage/graphs/graph_decompositions/tree_decomposition.cpython-39-aarch64-linux-gnu.so +0 -0
  177. sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
  178. sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
  179. sage/graphs/graph_decompositions/vertex_separation.cpython-39-aarch64-linux-gnu.so +0 -0
  180. sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
  181. sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
  182. sage/graphs/graph_editor.py +82 -0
  183. sage/graphs/graph_generators.py +3301 -0
  184. sage/graphs/graph_generators_pyx.cpython-39-aarch64-linux-gnu.so +0 -0
  185. sage/graphs/graph_generators_pyx.pyx +95 -0
  186. sage/graphs/graph_input.py +812 -0
  187. sage/graphs/graph_latex.py +2064 -0
  188. sage/graphs/graph_list.py +367 -0
  189. sage/graphs/graph_plot.py +1749 -0
  190. sage/graphs/graph_plot_js.py +338 -0
  191. sage/graphs/hyperbolicity.cpython-39-aarch64-linux-gnu.so +0 -0
  192. sage/graphs/hyperbolicity.pyx +1702 -0
  193. sage/graphs/hypergraph_generators.py +364 -0
  194. sage/graphs/independent_sets.cpython-39-aarch64-linux-gnu.so +0 -0
  195. sage/graphs/independent_sets.pxd +13 -0
  196. sage/graphs/independent_sets.pyx +402 -0
  197. sage/graphs/isgci.py +1033 -0
  198. sage/graphs/isoperimetric_inequalities.cpython-39-aarch64-linux-gnu.so +0 -0
  199. sage/graphs/isoperimetric_inequalities.pyx +453 -0
  200. sage/graphs/line_graph.cpython-39-aarch64-linux-gnu.so +0 -0
  201. sage/graphs/line_graph.pyx +627 -0
  202. sage/graphs/lovasz_theta.py +77 -0
  203. sage/graphs/matching.py +1633 -0
  204. sage/graphs/matching_covered_graph.py +3566 -0
  205. sage/graphs/orientations.py +1504 -0
  206. sage/graphs/partial_cube.py +459 -0
  207. sage/graphs/path_enumeration.cpython-39-aarch64-linux-gnu.so +0 -0
  208. sage/graphs/path_enumeration.pyx +2040 -0
  209. sage/graphs/pq_trees.py +1129 -0
  210. sage/graphs/print_graphs.py +201 -0
  211. sage/graphs/schnyder.py +865 -0
  212. sage/graphs/spanning_tree.cpython-39-aarch64-linux-gnu.so +0 -0
  213. sage/graphs/spanning_tree.pyx +1457 -0
  214. sage/graphs/strongly_regular_db.cpython-39-aarch64-linux-gnu.so +0 -0
  215. sage/graphs/strongly_regular_db.pyx +3340 -0
  216. sage/graphs/traversals.cpython-39-aarch64-linux-gnu.so +0 -0
  217. sage/graphs/traversals.pxd +9 -0
  218. sage/graphs/traversals.pyx +1871 -0
  219. sage/graphs/trees.cpython-39-aarch64-linux-gnu.so +0 -0
  220. sage/graphs/trees.pxd +15 -0
  221. sage/graphs/trees.pyx +310 -0
  222. sage/graphs/tutte_polynomial.py +713 -0
  223. sage/graphs/views.cpython-39-aarch64-linux-gnu.so +0 -0
  224. sage/graphs/views.pyx +794 -0
  225. sage/graphs/weakly_chordal.cpython-39-aarch64-linux-gnu.so +0 -0
  226. sage/graphs/weakly_chordal.pyx +562 -0
  227. sage/groups/all__sagemath_graphs.py +1 -0
  228. sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
  229. sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
  230. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-39-aarch64-linux-gnu.so +0 -0
  231. sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
  232. sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
  233. sage/knots/all.py +6 -0
  234. sage/knots/free_knotinfo_monoid.py +507 -0
  235. sage/knots/gauss_code.py +291 -0
  236. sage/knots/knot.py +682 -0
  237. sage/knots/knot_table.py +284 -0
  238. sage/knots/knotinfo.py +2880 -0
  239. sage/knots/link.py +4682 -0
  240. sage/sandpiles/all.py +13 -0
  241. sage/sandpiles/examples.py +225 -0
  242. sage/sandpiles/sandpile.py +6365 -0
  243. sage/topology/all.py +22 -0
  244. sage/topology/cell_complex.py +1214 -0
  245. sage/topology/cubical_complex.py +1977 -0
  246. sage/topology/delta_complex.py +1806 -0
  247. sage/topology/filtered_simplicial_complex.py +744 -0
  248. sage/topology/moment_angle_complex.py +823 -0
  249. sage/topology/simplicial_complex.py +5161 -0
  250. sage/topology/simplicial_complex_catalog.py +86 -0
  251. sage/topology/simplicial_complex_examples.py +1692 -0
  252. sage/topology/simplicial_complex_homset.py +205 -0
  253. sage/topology/simplicial_complex_morphism.py +836 -0
  254. sage/topology/simplicial_set.py +4102 -0
  255. sage/topology/simplicial_set_catalog.py +55 -0
  256. sage/topology/simplicial_set_constructions.py +2954 -0
  257. sage/topology/simplicial_set_examples.py +865 -0
  258. sage/topology/simplicial_set_morphism.py +1464 -0
@@ -0,0 +1,548 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ # sage.doctest: needs sage.modules
3
+ r"""
4
+ Mutually orthogonal Latin squares (MOLS)
5
+
6
+ The main function of this module is :func:`mutually_orthogonal_latin_squares`
7
+ and can be can be used to generate MOLS (or check that they exist)::
8
+
9
+ sage: MOLS = designs.mutually_orthogonal_latin_squares(4,8) # needs sage.schemes
10
+
11
+ For more information on MOLS, see the :wikipedia:`Wikipedia entry on MOLS
12
+ <Graeco-Latin_square#Mutually_orthogonal_Latin_squares>`. If you are only
13
+ interested by latin squares, see :mod:`~sage.combinat.matrices.latin`.
14
+
15
+ The functions defined here are
16
+
17
+ .. csv-table::
18
+ :class: contentstable
19
+ :widths: 30, 70
20
+ :delim: |
21
+
22
+ :meth:`mutually_orthogonal_latin_squares` | Return `k` Mutually Orthogonal `n\times n` Latin Squares.
23
+ :meth:`are_mutually_orthogonal_latin_squares` | Check that the list ``l`` of matrices in are MOLS.
24
+ :meth:`latin_square_product` | Return the product of two (or more) latin squares.
25
+ :meth:`MOLS_table` | Print the MOLS table.
26
+
27
+ **Table of MOLS**
28
+
29
+ Sage can produce a table of MOLS similar to the one from the Handbook of
30
+ Combinatorial Designs [DesignHandbook]_ (`available here
31
+ <http://books.google.fr/books?id=S9FA9rq1BgoC&dq=handbook%20combinatorial%20designs%20MOLS%2010000&pg=PA176>`_).
32
+
33
+ ::
34
+
35
+ sage: from sage.combinat.designs.latin_squares import MOLS_table
36
+ sage: MOLS_table(600) # long time
37
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
38
+ ________________________________________________________________________________
39
+ 0| +oo +oo 1 2 3 4 1 6 7 8 2 10 5 12 4 4 15 16 5 18
40
+ 20| 4 5 3 22 7 24 4 26 5 28 4 30 31 5 4 5 8 36 4 5
41
+ 40| 7 40 5 42 5 6 4 46 8 48 6 5 5 52 5 6 7 7 5 58
42
+ 60| 5 60 5 6 63 7 5 66 5 6 6 70 7 72 5 7 6 6 6 78
43
+ 80| 9 80 8 82 6 6 6 6 7 88 6 7 6 6 6 6 7 96 6 8
44
+ 100| 8 100 6 102 7 7 6 106 6 108 6 6 13 112 6 7 6 8 6 6
45
+ 120| 7 120 6 6 6 124 6 126 127 7 6 130 6 7 6 7 7 136 6 138
46
+ 140| 6 7 6 10 10 7 6 7 6 148 6 150 7 8 8 7 6 156 7 6
47
+ 160| 9 7 6 162 6 7 6 166 7 168 6 8 6 172 6 6 14 9 6 178
48
+ 180| 6 180 6 6 7 9 6 10 6 8 6 190 7 192 6 7 6 196 6 198
49
+ 200| 7 7 6 7 6 8 6 8 14 11 10 210 6 7 6 7 7 8 6 10
50
+ 220| 6 12 6 222 13 8 6 226 6 228 6 7 7 232 6 7 6 7 6 238
51
+ 240| 7 240 6 242 6 7 6 12 7 7 6 250 6 12 9 7 255 256 6 12
52
+ 260| 6 8 8 262 7 8 7 10 7 268 7 270 15 16 6 13 10 276 6 9
53
+ 280| 7 280 6 282 6 12 6 7 15 288 6 6 6 292 6 6 7 10 10 12
54
+ 300| 7 7 7 7 15 15 6 306 7 7 7 310 7 312 7 10 7 316 7 10
55
+ 320| 15 15 6 16 8 12 6 7 7 9 6 330 7 8 7 6 7 336 6 7
56
+ 340| 6 10 10 342 7 7 6 346 6 348 8 12 18 352 6 9 7 9 6 358
57
+ 360| 7 360 6 7 7 7 6 366 15 15 7 15 7 372 7 15 7 13 7 378
58
+ 380| 7 12 7 382 15 15 7 15 7 388 7 16 7 7 7 7 8 396 7 7
59
+ 400| 15 400 7 15 11 8 7 15 8 408 7 13 8 12 10 9 18 15 7 418
60
+ 420| 7 420 7 15 7 16 6 7 7 7 6 430 15 432 6 15 6 18 7 438
61
+ 440| 7 15 7 442 7 13 7 11 15 448 7 15 7 7 7 15 7 456 7 16
62
+ 460| 7 460 7 462 15 15 7 466 8 8 7 15 7 15 10 18 7 15 6 478
63
+ 480| 15 15 6 15 8 7 6 486 7 15 6 490 6 16 6 7 15 15 6 498
64
+ 500| 7 8 9 502 7 15 6 15 7 508 6 15 511 18 7 15 8 12 8 15
65
+ 520| 8 520 10 522 12 15 8 16 15 528 7 15 8 12 7 15 8 15 10 15
66
+ 540| 12 540 7 15 18 7 7 546 7 8 7 18 7 7 7 7 7 556 7 12
67
+ 560| 15 7 7 562 7 7 6 7 7 568 6 570 7 7 15 22 8 576 7 7
68
+ 580| 7 8 7 10 7 8 7 586 7 18 17 7 15 592 8 15 7 7 8 598
69
+
70
+ Comparison with the results from the Handbook of Combinatorial Designs (2ed)
71
+ [DesignHandbook]_::
72
+
73
+ sage: MOLS_table(600,compare=True) # long time
74
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
75
+ ________________________________________________________________________________
76
+ 0| + +
77
+ 20|
78
+ 40|
79
+ 60|
80
+ 80|
81
+ 100|
82
+ 120|
83
+ 140|
84
+ 160|
85
+ 180|
86
+ 200| -
87
+ 220|
88
+ 240|
89
+ 260|
90
+ 280|
91
+ 300|
92
+ 320| -
93
+ 340|
94
+ 360| - -
95
+ 380| -
96
+ 400|
97
+ 420| -
98
+ 440|
99
+ 460|
100
+ 480|
101
+ 500| -
102
+ 520|
103
+ 540|
104
+ 560|
105
+ 580|
106
+
107
+ .. TODO::
108
+
109
+ Look at [ColDin01]_.
110
+
111
+ REFERENCES:
112
+
113
+ .. [Stinson2004] Douglas R. Stinson,
114
+ *Combinatorial designs: construction and analysis*,
115
+ Springer, 2004.
116
+
117
+ .. [ColDin01] Charles Colbourn, Jeffrey Dinitz,
118
+ *Mutually orthogonal latin squares: a brief survey of constructions*,
119
+ Volume 95, Issues 1-2, Pages 9-48,
120
+ Journal of Statistical Planning and Inference,
121
+ Springer, 1 May 2001.
122
+
123
+ Functions
124
+ ---------
125
+ """
126
+ from itertools import repeat
127
+ from sage.rings.integer import Integer
128
+ from sage.categories.sets_cat import EmptySetError
129
+ from sage.misc.unknown import Unknown
130
+
131
+
132
+ def are_mutually_orthogonal_latin_squares(l, verbose=False):
133
+ r"""
134
+ Check whether the list of matrices in ``l`` form mutually orthogonal latin
135
+ squares.
136
+
137
+ INPUT:
138
+
139
+ - ``verbose`` -- if ``True`` then print why the list of matrices provided are
140
+ not mutually orthogonal latin squares
141
+
142
+ EXAMPLES::
143
+
144
+ sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares
145
+ sage: m1 = matrix([[0,1,2],[2,0,1],[1,2,0]])
146
+ sage: m2 = matrix([[0,1,2],[1,2,0],[2,0,1]])
147
+ sage: m3 = matrix([[0,1,2],[2,0,1],[1,2,0]])
148
+ sage: are_mutually_orthogonal_latin_squares([m1,m2])
149
+ True
150
+ sage: are_mutually_orthogonal_latin_squares([m1,m3])
151
+ False
152
+ sage: are_mutually_orthogonal_latin_squares([m2,m3])
153
+ True
154
+ sage: are_mutually_orthogonal_latin_squares([m1,m2,m3], verbose=True)
155
+ Squares 0 and 2 are not orthogonal
156
+ False
157
+
158
+ sage: m = designs.mutually_orthogonal_latin_squares(7,8) # needs sage.schemes
159
+ sage: are_mutually_orthogonal_latin_squares(m) # needs sage.schemes
160
+ True
161
+
162
+ TESTS:
163
+
164
+ Not a latin square::
165
+
166
+ sage: m1 = matrix([[0,1,0],[2,0,1],[1,2,0]])
167
+ sage: m2 = matrix([[0,1,2],[1,2,0],[2,0,1]])
168
+ sage: are_mutually_orthogonal_latin_squares([m1,m2], verbose=True)
169
+ Matrix 0 is not row latin
170
+ False
171
+ sage: m1 = matrix([[0,1,2],[1,0,2],[1,2,0]])
172
+ sage: are_mutually_orthogonal_latin_squares([m1,m2], verbose=True)
173
+ Matrix 0 is not column latin
174
+ False
175
+ sage: m1 = matrix([[0,0,0],[1,1,1],[2,2,2]])
176
+ sage: m2 = matrix([[0,1,2],[0,1,2],[0,1,2]])
177
+ sage: are_mutually_orthogonal_latin_squares([m1,m2])
178
+ False
179
+ """
180
+
181
+ if not l:
182
+ raise ValueError("the list must be non empty")
183
+
184
+ n = l[0].ncols()
185
+ k = len(l)
186
+ if any(M.ncols() != n or M.nrows() != n for M in l):
187
+ if verbose:
188
+ print("Not all matrices are square matrices of the same dimensions")
189
+ return False
190
+
191
+ # Check that all matrices are latin squares
192
+ for i,M in enumerate(l):
193
+ if any(len(set(R)) != n for R in M):
194
+ if verbose:
195
+ print("Matrix {} is not row latin".format(i))
196
+ return False
197
+ if any(len(set(R)) != n for R in zip(*M)):
198
+ if verbose:
199
+ print("Matrix {} is not column latin".format(i))
200
+ return False
201
+
202
+ from .designs_pyx import is_orthogonal_array
203
+ return is_orthogonal_array(list(zip(*[[x for R in M for x in R] for M in l])),k,n, verbose=verbose, terminology='MOLS')
204
+
205
+
206
+ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True):
207
+ r"""
208
+ Return `k` Mutually Orthogonal `n\times n` Latin Squares (MOLS).
209
+
210
+ For more information on Mutually Orthogonal Latin Squares, see
211
+ :mod:`~sage.combinat.designs.latin_squares`.
212
+
213
+ INPUT:
214
+
215
+ - ``k`` -- integer; number of MOLS. If ``k`` is ``None`` it is set to the largest
216
+ value available
217
+
218
+ - ``n`` -- integer; size of the latin square
219
+
220
+ - ``partitions`` -- boolean; a Latin Square can be seen as 3 partitions of
221
+ the `n^2` cells of the array into `n` sets of size `n`, respectively:
222
+
223
+ * The partition of rows
224
+ * The partition of columns
225
+ * The partition of number (cells numbered with 0, cells numbered with 1,
226
+ ...)
227
+
228
+ These partitions have the additional property that any two sets from
229
+ different partitions intersect on exactly one element.
230
+
231
+ When ``partitions`` is set to ``True``, this function returns a list of `k+2`
232
+ partitions satisfying this intersection property instead of the `k+2` MOLS
233
+ (though the data is exactly the same in both cases).
234
+
235
+ - ``check`` -- boolean (default: ``True``); whether to check that output is
236
+ correct before returning it. As this is expected to be useless, you may
237
+ want to disable it whenever you want speed.
238
+
239
+ EXAMPLES::
240
+
241
+ sage: designs.mutually_orthogonal_latin_squares(4,5) # needs sage.schemes
242
+ [
243
+ [0 2 4 1 3] [0 3 1 4 2] [0 4 3 2 1] [0 1 2 3 4]
244
+ [4 1 3 0 2] [3 1 4 2 0] [2 1 0 4 3] [4 0 1 2 3]
245
+ [3 0 2 4 1] [1 4 2 0 3] [4 3 2 1 0] [3 4 0 1 2]
246
+ [2 4 1 3 0] [4 2 0 3 1] [1 0 4 3 2] [2 3 4 0 1]
247
+ [1 3 0 2 4], [2 0 3 1 4], [3 2 1 0 4], [1 2 3 4 0]
248
+ ]
249
+
250
+ sage: designs.mutually_orthogonal_latin_squares(3,7) # needs sage.schemes
251
+ [
252
+ [0 2 4 6 1 3 5] [0 3 6 2 5 1 4] [0 4 1 5 2 6 3]
253
+ [6 1 3 5 0 2 4] [5 1 4 0 3 6 2] [4 1 5 2 6 3 0]
254
+ [5 0 2 4 6 1 3] [3 6 2 5 1 4 0] [1 5 2 6 3 0 4]
255
+ [4 6 1 3 5 0 2] [1 4 0 3 6 2 5] [5 2 6 3 0 4 1]
256
+ [3 5 0 2 4 6 1] [6 2 5 1 4 0 3] [2 6 3 0 4 1 5]
257
+ [2 4 6 1 3 5 0] [4 0 3 6 2 5 1] [6 3 0 4 1 5 2]
258
+ [1 3 5 0 2 4 6], [2 5 1 4 0 3 6], [3 0 4 1 5 2 6]
259
+ ]
260
+
261
+ sage: designs.mutually_orthogonal_latin_squares(2,5,partitions=True) # needs sage.schemes
262
+ [[[0, 1, 2, 3, 4],
263
+ [5, 6, 7, 8, 9],
264
+ [10, 11, 12, 13, 14],
265
+ [15, 16, 17, 18, 19],
266
+ [20, 21, 22, 23, 24]],
267
+ [[0, 5, 10, 15, 20],
268
+ [1, 6, 11, 16, 21],
269
+ [2, 7, 12, 17, 22],
270
+ [3, 8, 13, 18, 23],
271
+ [4, 9, 14, 19, 24]],
272
+ [[0, 8, 11, 19, 22],
273
+ [3, 6, 14, 17, 20],
274
+ [1, 9, 12, 15, 23],
275
+ [4, 7, 10, 18, 21],
276
+ [2, 5, 13, 16, 24]],
277
+ [[0, 9, 13, 17, 21],
278
+ [2, 6, 10, 19, 23],
279
+ [4, 8, 12, 16, 20],
280
+ [1, 5, 14, 18, 22],
281
+ [3, 7, 11, 15, 24]]]
282
+
283
+ What is the maximum number of MOLS of size 8 that Sage knows how to build?::
284
+
285
+ sage: designs.orthogonal_arrays.largest_available_k(8)-2 # needs sage.schemes
286
+ 7
287
+
288
+ If you only want to know if Sage is able to build a given set of
289
+ MOLS, query the ``orthogonal_arrays.*`` functions::
290
+
291
+ sage: designs.orthogonal_arrays.is_available(5+2, 5) # 5 MOLS of order 5
292
+ False
293
+ sage: designs.orthogonal_arrays.is_available(4+2,6) # 4 MOLS of order 6 # needs sage.schemes
294
+ False
295
+
296
+ Sage, however, is not able to prove that the second MOLS do not exist::
297
+
298
+ sage: designs.orthogonal_arrays.exists(4+2,6) # 4 MOLS of order 6 # needs sage.schemes
299
+ Unknown
300
+
301
+ If you ask for such a MOLS then you will respectively get an informative
302
+ :exc:`EmptySetError` or :exc:`NotImplementedError`::
303
+
304
+ sage: designs.mutually_orthogonal_latin_squares(5, 5)
305
+ Traceback (most recent call last):
306
+ ...
307
+ EmptySetError: there exist at most n-1 MOLS of size n if n>=2
308
+ sage: designs.mutually_orthogonal_latin_squares(4,6) # needs sage.schemes
309
+ Traceback (most recent call last):
310
+ ...
311
+ NotImplementedError: I don't know how to build 4 MOLS of order 6
312
+
313
+ TESTS:
314
+
315
+ The special case `n=1`::
316
+
317
+ sage: designs.mutually_orthogonal_latin_squares(3, 1)
318
+ [[0], [0], [0]]
319
+
320
+ Wrong input for `k`::
321
+
322
+ sage: designs.mutually_orthogonal_latin_squares(None, 1)
323
+ Traceback (most recent call last):
324
+ ...
325
+ TypeError: k must be a positive integer
326
+
327
+ sage: designs.mutually_orthogonal_latin_squares(-1, 1)
328
+ Traceback (most recent call last):
329
+ ...
330
+ ValueError: k must be positive
331
+
332
+ sage: designs.mutually_orthogonal_latin_squares(2,10)
333
+ [
334
+ [1 8 9 0 2 4 6 3 5 7] [1 7 6 5 0 9 8 2 3 4]
335
+ [7 2 8 9 0 3 5 4 6 1] [8 2 1 7 6 0 9 3 4 5]
336
+ [6 1 3 8 9 0 4 5 7 2] [9 8 3 2 1 7 0 4 5 6]
337
+ [5 7 2 4 8 9 0 6 1 3] [0 9 8 4 3 2 1 5 6 7]
338
+ [0 6 1 3 5 8 9 7 2 4] [2 0 9 8 5 4 3 6 7 1]
339
+ [9 0 7 2 4 6 8 1 3 5] [4 3 0 9 8 6 5 7 1 2]
340
+ [8 9 0 1 3 5 7 2 4 6] [6 5 4 0 9 8 7 1 2 3]
341
+ [2 3 4 5 6 7 1 8 9 0] [3 4 5 6 7 1 2 8 0 9]
342
+ [3 4 5 6 7 1 2 0 8 9] [5 6 7 1 2 3 4 0 9 8]
343
+ [4 5 6 7 1 2 3 9 0 8], [7 1 2 3 4 5 6 9 8 0]
344
+ ]
345
+ """
346
+ from sage.combinat.designs.orthogonal_arrays import orthogonal_array
347
+ from sage.matrix.constructor import Matrix
348
+ from .database import MOLS_constructions
349
+
350
+ if k is None:
351
+ raise TypeError('k must be a positive integer')
352
+ try:
353
+ Integer(k)
354
+ except TypeError:
355
+ raise
356
+ if k < 0:
357
+ raise ValueError('k must be positive')
358
+
359
+ if n == 1:
360
+ matrices = [Matrix([[0]])] * k
361
+
362
+ elif k >= n:
363
+ raise EmptySetError("there exist at most n-1 MOLS of size n if n>=2")
364
+
365
+ elif n in MOLS_constructions and k <= MOLS_constructions[n][0]:
366
+ _, construction = MOLS_constructions[n]
367
+
368
+ matrices = construction()[:k]
369
+
370
+ elif orthogonal_array(k + 2, n, existence=True) is not Unknown:
371
+ # Forwarding non-existence results
372
+ if orthogonal_array(k + 2, n, existence=True):
373
+ pass
374
+ else:
375
+ raise EmptySetError("there does not exist {} MOLS of order {}!".format(k, n))
376
+
377
+ # make sure that the first two columns are "11, 12, ..., 1n, 21, 22, ..."
378
+ OA = sorted(orthogonal_array(k + 2, n, check=False))
379
+
380
+ # We first define matrices as lists of n^2 values
381
+ matrices = [[] for _ in repeat(None, k)]
382
+ for L in OA:
383
+ for i in range(2, k + 2):
384
+ matrices[i-2].append(L[i])
385
+
386
+ # The real matrices
387
+ matrices = [[M[i*n:(i+1)*n] for i in range(n)] for M in matrices]
388
+ matrices = [Matrix(M) for M in matrices]
389
+
390
+ else:
391
+ raise NotImplementedError("I don't know how to build {} MOLS of order {}".format(k, n))
392
+
393
+ if check:
394
+ assert are_mutually_orthogonal_latin_squares(matrices)
395
+
396
+ # partitions have been requested but have not been computed yet
397
+ if partitions is True:
398
+ partitions = [[[i*n+j for j in range(n)] for i in range(n)],
399
+ [[j*n+i for j in range(n)] for i in range(n)]]
400
+ for m in matrices:
401
+ partition = [[] for _ in repeat(None, n)]
402
+ for i in range(n):
403
+ for j in range(n):
404
+ partition[m[i,j]].append(i*n+j)
405
+ partitions.append(partition)
406
+
407
+ if partitions:
408
+ return partitions
409
+ else:
410
+ return matrices
411
+
412
+
413
+ def latin_square_product(M, N, *others):
414
+ r"""
415
+ Return the product of two (or more) latin squares.
416
+
417
+ Given two Latin Squares `M,N` of respective sizes `m,n`, the direct product
418
+ `M\times N` of size `mn` is defined by `(M\times
419
+ N)((i_1,i_2),(j_1,j_2))=(M(i_1,j_1),N(i_2,j_2))` where `i_1,j_1\in [m],
420
+ i_2,j_2\in [n]`
421
+
422
+ Each pair of values `(i,j)\in [m]\times [n]` is then relabeled to `in+j`.
423
+
424
+ This is Lemma 6.25 of [Stinson2004]_.
425
+
426
+ INPUT:
427
+
428
+ - ``M``, ``N``, ``*others`` -- an arbitrary number of latin squares
429
+ (greater than or equal to 2)
430
+
431
+ EXAMPLES::
432
+
433
+ sage: from sage.combinat.designs.latin_squares import latin_square_product
434
+ sage: m=designs.mutually_orthogonal_latin_squares(3,4)[0] # needs sage.schemes
435
+ sage: latin_square_product(m,m,m) # needs sage.schemes
436
+ 64 x 64 sparse matrix over Integer Ring (use the '.str()' method to see the entries)
437
+ """
438
+ from sage.matrix.constructor import Matrix
439
+ m = M.nrows()
440
+ n = N.nrows()
441
+
442
+ D = {((i,j),(ii,jj)):(M[i,ii],N[j,jj])
443
+ for i in range(m)
444
+ for ii in range(m)
445
+ for j in range(n)
446
+ for jj in range(n)}
447
+
448
+ L = lambda i_j: i_j[0] * n + i_j[1]
449
+ D = {(L(c[0]), L(c[1])): L(v) for c, v in D.items()}
450
+ P = Matrix(D)
451
+
452
+ if others:
453
+ return latin_square_product(P, others[0], *others[1:])
454
+ else:
455
+ return P
456
+
457
+
458
+ def MOLS_table(start, stop=None, compare=False, width=None):
459
+ r"""
460
+ Print the MOLS table that Sage can produce.
461
+
462
+ INPUT:
463
+
464
+ - ``start``, ``stop`` -- integers; print the table of MOLS for value of
465
+ `n` such that ``start<=n<stop``. If only one integer is given as input,
466
+ it is interpreted as the value of ``stop`` with ``start=0`` (same
467
+ behaviour as ``range``).
468
+
469
+ - ``compare`` -- boolean; if sets to ``True`` the MOLS displays
470
+ with `+` and `-` entries its difference with the table from the
471
+ Handbook of Combinatorial Designs (2ed).
472
+
473
+ - ``width`` -- integer; the width of each column of the table. By default,
474
+ it is computed from range of values determined by the parameters ``start``
475
+ and ``stop``.
476
+
477
+ EXAMPLES::
478
+
479
+ sage: # needs sage.schemes
480
+ sage: from sage.combinat.designs.latin_squares import MOLS_table
481
+ sage: MOLS_table(100)
482
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
483
+ ________________________________________________________________________________
484
+ 0| +oo +oo 1 2 3 4 1 6 7 8 2 10 5 12 4 4 15 16 5 18
485
+ 20| 4 5 3 22 7 24 4 26 5 28 4 30 31 5 4 5 8 36 4 5
486
+ 40| 7 40 5 42 5 6 4 46 8 48 6 5 5 52 5 6 7 7 5 58
487
+ 60| 5 60 5 6 63 7 5 66 5 6 6 70 7 72 5 7 6 6 6 78
488
+ 80| 9 80 8 82 6 6 6 6 7 88 6 7 6 6 6 6 7 96 6 8
489
+ sage: MOLS_table(100, width=4)
490
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
491
+ ____________________________________________________________________________________________________
492
+ 0| +oo +oo 1 2 3 4 1 6 7 8 2 10 5 12 4 4 15 16 5 18
493
+ 20| 4 5 3 22 7 24 4 26 5 28 4 30 31 5 4 5 8 36 4 5
494
+ 40| 7 40 5 42 5 6 4 46 8 48 6 5 5 52 5 6 7 7 5 58
495
+ 60| 5 60 5 6 63 7 5 66 5 6 6 70 7 72 5 7 6 6 6 78
496
+ 80| 9 80 8 82 6 6 6 6 7 88 6 7 6 6 6 6 7 96 6 8
497
+ sage: MOLS_table(100, compare=True)
498
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
499
+ ________________________________________________________________________________
500
+ 0| + +
501
+ 20|
502
+ 40|
503
+ 60|
504
+ 80|
505
+ sage: MOLS_table(50, 100, compare=True)
506
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
507
+ ________________________________________________________________________________
508
+ 40|
509
+ 60|
510
+ 80|
511
+ """
512
+ from .orthogonal_arrays import largest_available_k
513
+ if stop is None:
514
+ start,stop = 0,start
515
+ # make start and stop be congruent to 0 mod 20
516
+ start = start - (start % 20)
517
+ stop = stop-1
518
+ stop = stop + (20-(stop % 20))
519
+ assert start % 20 == 0 and stop % 20 == 0
520
+ if stop <= start:
521
+ return
522
+
523
+ # choose an appropriate width (needs to be >= 3 because "+oo" should fit)
524
+ if width is None:
525
+ width = max(3, Integer(stop-1).ndigits(10))
526
+
527
+ print(" " * (width + 2) + " ".join("{i:>{width}}".format(i=i,width=width)
528
+ for i in range(20)))
529
+ print(" " * (width + 1) + "_" * ((width + 1) * 20), end="")
530
+ for i in range(start,stop):
531
+ if i % 20 == 0:
532
+ print("\n{:>{width}}|".format(i, width=width), end="")
533
+ k = largest_available_k(i)-2
534
+ if compare:
535
+ from . import MOLS_handbook_data
536
+ lower_bound = MOLS_handbook_data.lower_bound(i)
537
+ if i < 2 or lower_bound == k:
538
+ c = ""
539
+ elif lower_bound < k:
540
+ c = "+"
541
+ else:
542
+ c = "-"
543
+ else:
544
+ if i < 2:
545
+ c = "+oo"
546
+ else:
547
+ c = k
548
+ print(' {:>{width}}'.format(c, width=width), end="")