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,923 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ r"""
3
+ Yang-Baxter Graphs
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2009 Franco Saliola <saliola@gmail.com>
7
+ #
8
+ # Distributed under the terms of the GNU General Public License (GPL)
9
+ #
10
+ # This code is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # General Public License for more details.
14
+ #
15
+ # The full text of the GPL is available at:
16
+ #
17
+ # https://www.gnu.org/licenses/
18
+ # ****************************************************************************
19
+ from copy import copy
20
+
21
+ from sage.graphs.digraph import DiGraph
22
+ from sage.structure.sage_object import SageObject
23
+ from sage.misc.lazy_attribute import lazy_attribute
24
+ from sage.misc.lazy_import import lazy_import
25
+ from sage.combinat.permutation import Permutation
26
+
27
+ lazy_import('sage.combinat.partition', 'Partition')
28
+
29
+
30
+ def YangBaxterGraph(partition=None, root=None, operators=None):
31
+ r"""
32
+ Construct the Yang-Baxter graph from ``root`` by repeated application of
33
+ ``operators``, or the Yang-Baxter graph associated to ``partition``.
34
+
35
+ INPUT:
36
+
37
+ The user needs to provide either ``partition`` or both ``root`` and
38
+ ``operators``, where
39
+
40
+ - ``partition`` -- a partition of a positive integer
41
+
42
+ - ``root`` -- the root vertex
43
+
44
+ - ``operator`` -- a function that maps vertices `u` to a list of
45
+ tuples of the form `(v, l)` where `v` is a successor of `u` and `l` is
46
+ the label of the edge from `u` to `v`.
47
+
48
+ OUTPUT: either:
49
+
50
+ - :class:`YangBaxterGraph_partition` -- if partition is defined
51
+ - :class:`YangBaxterGraph_generic` -- if partition is ``None``
52
+
53
+ EXAMPLES:
54
+
55
+ The Yang-Baxter graph defined by a partition `[p_1,\dots,p_k]` is
56
+ the labelled directed graph with vertex set obtained by
57
+ bubble-sorting `(p_k-1,p_k-2,\dots,0,\dots,p_1-1,p_1-2,\dots,0)`;
58
+ there is an arrow from `u` to `v` labelled by `i` if `v` is
59
+ obtained by swapping the `i`-th and `(i+1)`-th elements of `u`.
60
+ For example, if the partition is `[3,1]`, then we begin with
61
+ `(0,2,1,0)` and generate all tuples obtained from it by swapping
62
+ two adjacent entries if they are increasing::
63
+
64
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
65
+ sage: bubbleswaps = [SwapIncreasingOperator(i) for i in range(3)]
66
+ sage: Y = YangBaxterGraph(root=(0,2,1,0), operators=bubbleswaps); Y
67
+ Yang-Baxter graph with root vertex (0, 2, 1, 0)
68
+ sage: Y.vertices(sort=True)
69
+ [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)]
70
+
71
+ The ``partition`` keyword is a shorthand for the above construction::
72
+
73
+ sage: Y = YangBaxterGraph(partition=[3,1]); Y # needs sage.combinat
74
+ Yang-Baxter graph of [3, 1], with top vertex (0, 2, 1, 0)
75
+ sage: Y.vertices(sort=True)
76
+ [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)]
77
+
78
+ The permutahedron can be realized as a Yang-Baxter graph::
79
+
80
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
81
+ sage: swappers = [SwapIncreasingOperator(i) for i in range(3)]
82
+ sage: Y = YangBaxterGraph(root=(1,2,3,4), operators=swappers); Y
83
+ Yang-Baxter graph with root vertex (1, 2, 3, 4)
84
+ sage: Y.plot() # needs sage.plot
85
+ Graphics object consisting of 97 graphics primitives
86
+
87
+ The Cayley graph of a finite group can be realized as a Yang-Baxter graph::
88
+
89
+ sage: # needs sage.groups
90
+ sage: def left_multiplication_by(g):
91
+ ....: return lambda h: h*g
92
+ sage: G = CyclicPermutationGroup(4)
93
+ sage: operators = [ left_multiplication_by(gen) for gen in G.gens() ]
94
+ sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y
95
+ Yang-Baxter graph with root vertex ()
96
+ sage: Y.plot(edge_labels=False) # needs sage.plot
97
+ Graphics object consisting of 9 graphics primitives
98
+
99
+ sage: # needs sage.groups
100
+ sage: G = SymmetricGroup(4)
101
+ sage: operators = [left_multiplication_by(gen) for gen in G.gens()]
102
+ sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y
103
+ Yang-Baxter graph with root vertex ()
104
+ sage: Y.plot(edge_labels=False) # needs sage.plot
105
+ Graphics object consisting of 96 graphics primitives
106
+
107
+ AUTHORS:
108
+
109
+ - Franco Saliola (2009-04-23)
110
+ """
111
+ if partition is None:
112
+ return YangBaxterGraph_generic(root=root, operators=operators)
113
+ return YangBaxterGraph_partition(partition=Partition(partition))
114
+
115
+ # *********** General class for Yang-Baxter Graphs ***********
116
+
117
+
118
+ class YangBaxterGraph_generic(SageObject):
119
+ def __init__(self, root, operators):
120
+ r"""
121
+ A class to model the Yang-Baxter graph defined by ``root`` and
122
+ ``operators``.
123
+
124
+ INPUT:
125
+
126
+ - ``root`` -- the root vertex of the graph
127
+
128
+ - ``operators`` -- list of callables that map vertices to (new)
129
+ vertices
130
+
131
+ .. NOTE::
132
+
133
+ This is a lazy implementation: the digraph is only computed
134
+ when it is needed.
135
+
136
+ EXAMPLES::
137
+
138
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
139
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
140
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops); Y
141
+ Yang-Baxter graph with root vertex (1, 0, 2, 1, 0)
142
+ sage: loads(dumps(Y)) == Y
143
+ True
144
+
145
+ AUTHORS:
146
+
147
+ - Franco Saliola (2009-04-23)
148
+ """
149
+ self._root = root
150
+ self._operators = operators
151
+
152
+ def _successors(self, u):
153
+ r"""
154
+ Return an iterator of tuples for the form ``(op(u), op)``, where ``op``
155
+ is one of the operators defining ``self``.
156
+
157
+ EXAMPLES::
158
+
159
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
160
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
161
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
162
+ sage: list(Y._successors((1,0,2,1,0)))
163
+ [((1, 2, 0, 1, 0), Swap-if-increasing at position 1)]
164
+ """
165
+ for op in self._operators:
166
+ v = op(u)
167
+ if v != u:
168
+ yield (v, op)
169
+
170
+ def __repr__(self) -> str:
171
+ r"""
172
+ EXAMPLES::
173
+
174
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
175
+ sage: ops = [SwapIncreasingOperator(i) for i in range(2)]
176
+ sage: Y = YangBaxterGraph(root=(1,2,3), operators=ops)
177
+ sage: Y.__repr__()
178
+ 'Yang-Baxter graph with root vertex (1, 2, 3)'
179
+ """
180
+ return f"Yang-Baxter graph with root vertex {self._root}"
181
+
182
+ @lazy_attribute
183
+ def _digraph(self):
184
+ r"""
185
+ Construct the underlying digraph and store the result as an
186
+ attribute.
187
+
188
+ EXAMPLES::
189
+
190
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
191
+ sage: ops = [SwapIncreasingOperator(i) for i in range(2)]
192
+ sage: Y = YangBaxterGraph(root=(1,2,3), operators=ops)
193
+ sage: Y._digraph
194
+ Digraph on 6 vertices
195
+ """
196
+ digraph = DiGraph()
197
+ digraph.add_vertex(self._root)
198
+ queue = [self._root]
199
+ while queue:
200
+ u = queue.pop()
201
+ for v, l in self._successors(u):
202
+ if v not in digraph:
203
+ queue.append(v)
204
+ digraph.add_edge(u, v, l)
205
+ return digraph
206
+
207
+ def __hash__(self) -> int:
208
+ r"""
209
+ TESTS::
210
+
211
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
212
+ sage: ops = [SwapIncreasingOperator(i) for i in range(2)]
213
+ sage: Y = YangBaxterGraph(root=(1,2,3), operators=ops)
214
+ sage: H = hash(Y)
215
+ """
216
+ # TODO: this is ugly but unavoidable: the Yang Baxter graphs are being
217
+ # used in containers but are mutable.
218
+ return hash(self._digraph.copy(immutable=True))
219
+
220
+ def __eq__(self, other) -> bool:
221
+ r"""
222
+ EXAMPLES::
223
+
224
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
225
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
226
+ sage: Y1 = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
227
+ sage: Y2 = YangBaxterGraph(root=(2,0,2,1,0), operators=ops)
228
+ sage: Y3 = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
229
+ sage: Y1.__eq__(Y2)
230
+ False
231
+ sage: Y2.__eq__(Y2)
232
+ True
233
+ sage: Y1.__eq__(Y1)
234
+ True
235
+ sage: Y3.__eq__(Y1)
236
+ True
237
+ sage: Y3.__eq__(Y2)
238
+ False
239
+ """
240
+ return isinstance(other, YangBaxterGraph_generic) and self._digraph == other._digraph
241
+
242
+ def __ne__(self, other) -> bool:
243
+ r"""
244
+ Test non-equality.
245
+
246
+ EXAMPLES::
247
+
248
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
249
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
250
+ sage: Y1 = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
251
+ sage: Y2 = YangBaxterGraph(root=(2,0,2,1,0), operators=ops)
252
+ sage: Y3 = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
253
+ sage: Y1.__ne__(Y2)
254
+ True
255
+ sage: Y2.__ne__(Y2)
256
+ False
257
+ sage: Y1.__ne__(Y1)
258
+ False
259
+ sage: Y3.__ne__(Y1)
260
+ False
261
+ sage: Y3.__ne__(Y2)
262
+ True
263
+ """
264
+ return not self == other
265
+
266
+ def __iter__(self):
267
+ r"""
268
+ Return an iterator of the vertices in ``self``.
269
+
270
+ EXAMPLES::
271
+
272
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
273
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
274
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
275
+ sage: sorted(set(Y))
276
+ [(1, 0, 2, 1, 0), (1, 2, 0, 1, 0), (1, 2, 1, 0, 0), (2, 1, 0, 1, 0), (2, 1, 1, 0, 0)]
277
+ """
278
+ return self._digraph.vertex_iterator()
279
+
280
+ def __len__(self):
281
+ r"""
282
+ Return the number of vertices in ``self``.
283
+
284
+ EXAMPLES::
285
+
286
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
287
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
288
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
289
+ sage: Y.__len__()
290
+ 5
291
+ sage: ops = [SwapIncreasingOperator(i) for i in range(5)]
292
+ sage: Y = YangBaxterGraph(root=(0,1,0,2,1,0), operators=ops)
293
+ sage: Y.__len__()
294
+ 16
295
+ """
296
+ return self._digraph.num_verts()
297
+
298
+ def __copy__(self):
299
+ r"""
300
+ Return a copy of ``self``.
301
+
302
+ EXAMPLES::
303
+
304
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
305
+ sage: ops = [SwapIncreasingOperator(i) for i in range(3)]
306
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops); Y
307
+ Yang-Baxter graph with root vertex (1, 0, 2, 1, 0)
308
+ sage: B = copy(Y); B
309
+ Yang-Baxter graph with root vertex (1, 0, 2, 1, 0)
310
+ sage: Y is B
311
+ False
312
+ sage: Y == B
313
+ True
314
+ """
315
+ Y = self.__class__(self._root, self._operators)
316
+ Y._digraph = copy(self._digraph)
317
+ return Y
318
+
319
+ def _edges_in_bfs(self):
320
+ r"""
321
+ Return an iterator of the edges of the digraph traversed in a
322
+ breadth-first search of the vertices beginning at ``self.root()``.
323
+
324
+ EXAMPLES::
325
+
326
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
327
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
328
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
329
+ sage: list(Y._edges_in_bfs())
330
+ [((1, 0, 2, 1, 0), (1, 2, 0, 1, 0), Swap-if-increasing at position 1), ((1, 2, 0, 1, 0), (1, 2, 1, 0, 0), Swap-if-increasing at position 2), ((1, 2, 0, 1, 0), (2, 1, 0, 1, 0), Swap-if-increasing at position 0), ((2, 1, 0, 1, 0), (2, 1, 1, 0, 0), Swap-if-increasing at position 2)]
331
+ """
332
+ digraph = self._digraph
333
+ seen = {}
334
+ queue = [self._root]
335
+ seen[self._root] = True
336
+ while queue:
337
+ u = queue.pop()
338
+ l = sorted(digraph.neighbor_out_iterator(u))
339
+ for w in l:
340
+ if w not in seen:
341
+ seen[w] = True
342
+ queue.append(w)
343
+ yield (u, w, digraph.edge_label(u, w))
344
+
345
+ def root(self):
346
+ r"""
347
+ Return the root vertex of ``self``.
348
+
349
+ If ``self`` is the Yang-Baxter graph of the partition
350
+ `[p_1,p_2,\dots,p_k]`, then this is the vertex
351
+ `(p_k-1,p_k-2,\dots,0,\dots,p_1-1,p_1-2,\dots,0)`.
352
+
353
+ EXAMPLES::
354
+
355
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
356
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
357
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
358
+ sage: Y.root()
359
+ (1, 0, 2, 1, 0)
360
+ sage: Y = YangBaxterGraph(root=(0,1,0,2,1,0), operators=ops)
361
+ sage: Y.root()
362
+ (0, 1, 0, 2, 1, 0)
363
+ sage: Y = YangBaxterGraph(root=(1,0,3,2,1,0), operators=ops)
364
+ sage: Y.root()
365
+ (1, 0, 3, 2, 1, 0)
366
+ sage: Y = YangBaxterGraph(partition=[3,2]) # needs sage.combinat
367
+ sage: Y.root() # needs sage.combinat
368
+ (1, 0, 2, 1, 0)
369
+ """
370
+ return self._root
371
+
372
+ def successors(self, v) -> list:
373
+ r"""
374
+ Return the successors of the vertex ``v``.
375
+
376
+ EXAMPLES::
377
+
378
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
379
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
380
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
381
+ sage: Y.successors(Y.root())
382
+ [(1, 2, 0, 1, 0)]
383
+ sage: sorted(Y.successors((1, 2, 0, 1, 0)))
384
+ [(1, 2, 1, 0, 0), (2, 1, 0, 1, 0)]
385
+ """
386
+ return [a for a, _ in self._successors(v)]
387
+
388
+ def plot(self, *args, **kwds):
389
+ r"""
390
+ Plot ``self`` as a digraph.
391
+
392
+ EXAMPLES::
393
+
394
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
395
+ sage: ops = [SwapIncreasingOperator(i) for i in range(4)]
396
+ sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops)
397
+ sage: Y.plot() # needs sage.plot
398
+ Graphics object consisting of 16 graphics primitives
399
+ sage: Y.plot(edge_labels=False) # needs sage.plot
400
+ Graphics object consisting of 11 graphics primitives
401
+ """
402
+ if "edge_labels" not in kwds:
403
+ kwds["edge_labels"] = True
404
+ if "vertex_labels" not in kwds:
405
+ kwds["vertex_labels"] = True
406
+ return self._digraph.plot(*args, **kwds)
407
+
408
+ def vertices(self, sort=False) -> list:
409
+ r"""
410
+ Return the vertices of ``self``.
411
+
412
+ INPUT:
413
+
414
+ - ``sort`` -- boolean (default: ``False``); whether to sort the vertices
415
+
416
+ EXAMPLES::
417
+
418
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
419
+ sage: ops = [SwapIncreasingOperator(i) for i in range(3)]
420
+ sage: Y = YangBaxterGraph(root=(0,2,1,0), operators=ops)
421
+ sage: Y.vertices(sort=True)
422
+ [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)]
423
+ """
424
+ return sorted(self) if sort else list(self)
425
+
426
+ def edges(self):
427
+ r"""
428
+ Return the (labelled) edges of ``self``.
429
+
430
+ EXAMPLES::
431
+
432
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
433
+ sage: ops = [SwapIncreasingOperator(i) for i in range(3)]
434
+ sage: Y = YangBaxterGraph(root=(0,2,1,0), operators=ops)
435
+ sage: Y.edges()
436
+ [((0, 2, 1, 0), (2, 0, 1, 0), Swap-if-increasing at position 0), ((2, 0, 1, 0), (2, 1, 0, 0), Swap-if-increasing at position 1)]
437
+ """
438
+ return self._digraph.edges(sort=True)
439
+
440
+ def vertex_relabelling_dict(self, v, relabel_operator) -> dict:
441
+ r"""
442
+ Return a dictionary pairing vertices ``u`` of ``self`` with
443
+ the object obtained from ``v`` by applying the
444
+ ``relabel_operator`` along a path from the root to ``u``.
445
+
446
+ Note that the root is paired with ``v``.
447
+
448
+ INPUT:
449
+
450
+ - ``v`` -- an object
451
+
452
+ - ``relabel_operator`` -- function mapping a vertex and a label to
453
+ the image of the vertex
454
+
455
+ OUTPUT: dictionary pairing vertices with the corresponding image of ``v``
456
+
457
+ EXAMPLES::
458
+
459
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
460
+ sage: ops = [SwapIncreasingOperator(i) for i in range(3)]
461
+ sage: Y = YangBaxterGraph(root=(0,2,1,0), operators=ops)
462
+ sage: def relabel_operator(op, u):
463
+ ....: i = op.position()
464
+ ....: return u[:i] + u[i:i+2][::-1] + u[i+2:]
465
+ sage: Y.vertex_relabelling_dict((1,2,3,4), relabel_operator)
466
+ {(0, 2, 1, 0): (1, 2, 3, 4),
467
+ (2, 0, 1, 0): (2, 1, 3, 4),
468
+ (2, 1, 0, 0): (2, 3, 1, 4)}
469
+ """
470
+ relabelling = {self._root: v}
471
+ for u, w, i in self._edges_in_bfs():
472
+ relabelling[w] = relabel_operator(i, relabelling[u])
473
+ return relabelling
474
+
475
+ def relabel_vertices(self, v, relabel_operator, inplace=True):
476
+ r"""
477
+ Relabel the vertices ``u`` of ``self`` by the object obtained
478
+ from ``u`` by applying the ``relabel_operator`` to ``v`` along
479
+ a path from ``self.root()`` to ``u``.
480
+
481
+ Note that the ``self.root()`` is paired with ``v``.
482
+
483
+ INPUT:
484
+
485
+ - ``v`` -- tuple, Permutation, etc.
486
+
487
+ - ``inplace`` -- if ``True``, modifies ``self``; otherwise returns a
488
+ modified copy of ``self``
489
+
490
+ EXAMPLES::
491
+
492
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
493
+ sage: ops = [SwapIncreasingOperator(i) for i in range(3)]
494
+ sage: Y = YangBaxterGraph(root=(0,2,1,0), operators=ops)
495
+ sage: def relabel_op(op, u):
496
+ ....: i = op.position()
497
+ ....: return u[:i] + u[i:i+2][::-1] + u[i+2:]
498
+ sage: d = Y.relabel_vertices((1,2,3,4), relabel_op, inplace=False); d
499
+ Yang-Baxter graph with root vertex (1, 2, 3, 4)
500
+ sage: Y.vertices(sort=True)
501
+ [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)]
502
+ sage: e = Y.relabel_vertices((1,2,3,4), relabel_op); e
503
+ sage: Y.vertices(sort=True)
504
+ [(1, 2, 3, 4), (2, 1, 3, 4), (2, 3, 1, 4)]
505
+ """
506
+ relabelling = self.vertex_relabelling_dict(v, relabel_operator)
507
+ Y = self if inplace else copy(self)
508
+ Y._root = relabelling[Y._root]
509
+ Y._digraph.relabel(relabelling, inplace=True)
510
+ if inplace is False:
511
+ return Y
512
+
513
+ def relabel_edges(self, edge_dict, inplace=True):
514
+ r"""
515
+ Relabel the edges of ``self``.
516
+
517
+ INPUT:
518
+
519
+ - ``edge_dict`` -- dictionary keyed by the (unlabelled) edges
520
+
521
+ EXAMPLES::
522
+
523
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
524
+ sage: ops = [SwapIncreasingOperator(i) for i in range(3)]
525
+ sage: Y = YangBaxterGraph(root=(0,2,1,0), operators=ops)
526
+ sage: def relabel_op(op, u):
527
+ ....: i = op.position()
528
+ ....: return u[:i] + u[i:i+2][::-1] + u[i+2:]
529
+ sage: Y.edges()
530
+ [((0, 2, 1, 0), (2, 0, 1, 0), Swap-if-increasing at position 0), ((2, 0, 1, 0), (2, 1, 0, 0), Swap-if-increasing at position 1)]
531
+ sage: d = {((0,2,1,0),(2,0,1,0)):17, ((2,0,1,0),(2,1,0,0)):27}
532
+ sage: Y.relabel_edges(d, inplace=False).edges()
533
+ [((0, 2, 1, 0), (2, 0, 1, 0), 17), ((2, 0, 1, 0), (2, 1, 0, 0), 27)]
534
+ sage: Y.edges()
535
+ [((0, 2, 1, 0), (2, 0, 1, 0), Swap-if-increasing at position 0), ((2, 0, 1, 0), (2, 1, 0, 0), Swap-if-increasing at position 1)]
536
+ sage: Y.relabel_edges(d, inplace=True)
537
+ sage: Y.edges()
538
+ [((0, 2, 1, 0), (2, 0, 1, 0), 17), ((2, 0, 1, 0), (2, 1, 0, 0), 27)]
539
+ """
540
+ Y = self if inplace else copy(self)
541
+ digraph = Y._digraph
542
+ for u, v in digraph.edges(sort=False, labels=False):
543
+ digraph.set_edge_label(u, v, edge_dict[u, v])
544
+ if not inplace:
545
+ return Y
546
+
547
+
548
+ # *********** Yang-Baxter Graphs defined by a partition ***********
549
+
550
+ class YangBaxterGraph_partition(YangBaxterGraph_generic):
551
+ def __init__(self, partition):
552
+ r"""
553
+ A class to model the Yang-Baxter graph of a partition.
554
+
555
+ The Yang-Baxter graph defined by a partition `[p_1,\dots,p_k]`
556
+ is the labelled directed graph with vertex set obtained by
557
+ bubble-sorting `(p_k-1,p_k-2,\dots,0,\dots,p_1-1,p_1-2,\dots,0)`;
558
+ there is an arrow from `u` to `v` labelled by `i` if `v` is
559
+ obtained by swapping the `i`-th and `(i+1)`-th elements of `u`.
560
+
561
+ .. NOTE::
562
+
563
+ This is a lazy implementation: the digraph is only computed
564
+ when it is needed.
565
+
566
+ EXAMPLES::
567
+
568
+ sage: Y = YangBaxterGraph(partition=[3,2,1]); Y # needs sage.combinat
569
+ Yang-Baxter graph of [3, 2, 1], with top vertex (0, 1, 0, 2, 1, 0)
570
+ sage: loads(dumps(Y)) == Y # needs sage.combinat
571
+ True
572
+
573
+ AUTHORS:
574
+
575
+ - Franco Saliola (2009-04-23)
576
+ """
577
+ self._partition = partition
578
+ beta = sorted(self._partition, reverse=True)
579
+ root = sum((tuple(range(b)) for b in beta), ())[::-1]
580
+ operators = [SwapIncreasingOperator(i)
581
+ for i in range(sum(partition) - 1)]
582
+ super().__init__(root, operators)
583
+
584
+ def __repr__(self) -> str:
585
+ r"""
586
+ EXAMPLES::
587
+
588
+ sage: Y = YangBaxterGraph(partition=[3,2]) # needs sage.combinat
589
+ sage: Y.__repr__() # needs sage.combinat
590
+ 'Yang-Baxter graph of [3, 2], with top vertex (1, 0, 2, 1, 0)'
591
+ """
592
+ return f"Yang-Baxter graph of {self._partition}, with top vertex {self._root}"
593
+
594
+ def __copy__(self):
595
+ r"""
596
+ Return a copy of ``self``.
597
+
598
+ EXAMPLES::
599
+
600
+ sage: # needs sage.combinat
601
+ sage: Y = YangBaxterGraph(partition=[3,2]); Y
602
+ Yang-Baxter graph of [3, 2], with top vertex (1, 0, 2, 1, 0)
603
+ sage: B = copy(Y); B
604
+ Yang-Baxter graph of [3, 2], with top vertex (1, 0, 2, 1, 0)
605
+ sage: Y is B
606
+ False
607
+ sage: Y == B
608
+ True
609
+ """
610
+ Y = self.__class__(self._partition)
611
+ Y._digraph = copy(self._digraph)
612
+ return Y
613
+
614
+ @lazy_attribute
615
+ def _digraph(self):
616
+ r"""
617
+ Construct the underlying digraph and store the result as an
618
+ attribute.
619
+
620
+ EXAMPLES::
621
+
622
+ sage: Y = YangBaxterGraph(partition=[2,1]) # needs sage.combinat
623
+ sage: Y._digraph # needs sage.combinat
624
+ Digraph on 2 vertices
625
+ sage: Y.edges() # needs sage.combinat
626
+ [((0, 1, 0), (1, 0, 0), Swap positions 0 and 1)]
627
+ """
628
+ digraph = super()._digraph
629
+ for u, v, op in digraph.edges():
630
+ digraph.set_edge_label(u, v, SwapOperator(op.position()))
631
+ return digraph
632
+
633
+ @lazy_attribute
634
+ def _vertex_ordering(self):
635
+ r"""
636
+ Return a list of the vertices of ``self``, sorted using
637
+ Python's ``sorted`` method.
638
+
639
+ EXAMPLES::
640
+
641
+ sage: Y = YangBaxterGraph(partition=[3,2]) # needs sage.combinat
642
+ sage: Y._vertex_ordering # needs sage.combinat
643
+ [(1, 0, 2, 1, 0), (1, 2, 0, 1, 0), (1, 2, 1, 0, 0), (2, 1, 0, 1, 0), (2, 1, 1, 0, 0)]
644
+ """
645
+ return self._digraph.vertices(sort=True)
646
+
647
+ def __iter__(self):
648
+ r"""
649
+ Iterate over the vertices ``self``.
650
+
651
+ .. NOTE::
652
+
653
+ The vertices are first sorted using Python's ``sorted`` command.
654
+
655
+ EXAMPLES::
656
+
657
+ sage: Y = YangBaxterGraph(partition=[3,2]) # needs sage.combinat
658
+ sage: list(Y.__iter__()) # needs sage.combinat
659
+ [(1, 0, 2, 1, 0), (1, 2, 0, 1, 0), (1, 2, 1, 0, 0), (2, 1, 0, 1, 0), (2, 1, 1, 0, 0)]
660
+ """
661
+ yield from self._vertex_ordering
662
+
663
+ def _swap_operator(self, operator, u):
664
+ r"""
665
+ Return the image of ``u`` under ``operator``.
666
+
667
+ INPUT:
668
+
669
+ - ``i`` -- positive integer between ``1`` and ``len(u)-1``, inclusive
670
+
671
+ - ``u`` -- tuple, list, permutation, etc.
672
+
673
+ EXAMPLES::
674
+
675
+ sage: # needs sage.combinat
676
+ sage: Y = YangBaxterGraph(partition=[3,1])
677
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
678
+ sage: ops = [SwapOperator(i) for i in range(3)]
679
+ sage: [Y._swap_operator(op, (1,2,3,4)) for op in ops]
680
+ [(2, 1, 3, 4), (1, 3, 2, 4), (1, 2, 4, 3)]
681
+ sage: [Y._swap_operator(op, [4,3,2,1]) for op in ops]
682
+ [[3, 4, 2, 1], [4, 2, 3, 1], [4, 3, 1, 2]]
683
+ sage: [Y._swap_operator(op, Permutation([1,2,3,4])) for op in ops]
684
+ [[2, 1, 3, 4], [1, 3, 2, 4], [1, 2, 4, 3]]
685
+ """
686
+ return operator(u)
687
+
688
+ def vertex_relabelling_dict(self, v) -> dict:
689
+ r"""
690
+ Return a dictionary pairing vertices ``u`` of ``self`` with the object
691
+ obtained from ``v`` by applying transpositions corresponding to the
692
+ edges labels along a path from the root to ``u``.
693
+
694
+ Note that the root is paired with ``v``.
695
+
696
+ INPUT:
697
+
698
+ - ``v`` -- an object
699
+
700
+ OUTPUT: dictionary pairing vertices with the corresponding image of ``v``
701
+
702
+ EXAMPLES::
703
+
704
+ sage: Y = YangBaxterGraph(partition=[3,1]) # needs sage.combinat
705
+ sage: Y.vertex_relabelling_dict((1,2,3,4)) # needs sage.combinat
706
+ {(0, 2, 1, 0): (1, 2, 3, 4),
707
+ (2, 0, 1, 0): (2, 1, 3, 4),
708
+ (2, 1, 0, 0): (2, 3, 1, 4)}
709
+ sage: Y.vertex_relabelling_dict((4,3,2,1)) # needs sage.combinat
710
+ {(0, 2, 1, 0): (4, 3, 2, 1),
711
+ (2, 0, 1, 0): (3, 4, 2, 1),
712
+ (2, 1, 0, 0): (3, 2, 4, 1)}
713
+ """
714
+ return super().vertex_relabelling_dict(v, self._swap_operator)
715
+
716
+ def relabel_vertices(self, v, inplace=True):
717
+ r"""
718
+ Relabel the vertices of ``self`` with the object obtained from
719
+ ``v`` by applying the transpositions corresponding to the edge
720
+ labels along some path from the root to the vertex.
721
+
722
+ INPUT:
723
+
724
+ - ``v`` -- tuple, Permutation, etc.
725
+
726
+ - ``inplace`` -- if ``True``, modifies ``self``; otherwise
727
+ returns a modified copy of ``self``
728
+
729
+ EXAMPLES::
730
+
731
+ sage: # needs sage.combinat
732
+ sage: Y = YangBaxterGraph(partition=[3,1]); Y
733
+ Yang-Baxter graph of [3, 1], with top vertex (0, 2, 1, 0)
734
+ sage: d = Y.relabel_vertices((1,2,3,4), inplace=False); d
735
+ Digraph on 3 vertices
736
+ sage: Y.vertices(sort=True)
737
+ [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)]
738
+ sage: e = Y.relabel_vertices((1,2,3,4)); e
739
+ sage: Y.vertices(sort=True)
740
+ [(1, 2, 3, 4), (2, 1, 3, 4), (2, 3, 1, 4)]
741
+ """
742
+ relabelling = self.vertex_relabelling_dict(v)
743
+ if inplace:
744
+ Y = self
745
+ Y._root = relabelling[Y._root]
746
+ Y._digraph.relabel(relabelling, inplace=inplace)
747
+ Y._vertex_ordering = Y._digraph.vertices(sort=True)
748
+ return
749
+
750
+ Y = copy(self)
751
+ Y._root = relabelling[Y._root]
752
+ return Y._digraph.relabel(relabelling, inplace=inplace)
753
+
754
+ # ------------- Some Yang-Baxter operators ------------------
755
+
756
+
757
+ class SwapOperator(SageObject):
758
+ def __init__(self, i):
759
+ r"""
760
+ The operator that swaps the items in positions ``i`` and ``i+1``.
761
+
762
+ EXAMPLES::
763
+
764
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
765
+ sage: s3 = SwapOperator(3)
766
+ sage: s3 == loads(dumps(s3))
767
+ True
768
+ """
769
+ self._position = i
770
+
771
+ def __hash__(self) -> int:
772
+ r"""
773
+ TESTS::
774
+
775
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
776
+ sage: s = [SwapOperator(i) for i in range(3)]
777
+ sage: [hash(t) for t in s]
778
+ [0, 1, 2]
779
+ """
780
+ return hash(self._position)
781
+
782
+ def __eq__(self, other) -> bool:
783
+ r"""
784
+ Compare two swap operators.
785
+
786
+ The comparison is done by comparing the positions.
787
+
788
+ EXAMPLES::
789
+
790
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
791
+ sage: s = [SwapOperator(i) for i in range(3)]
792
+ sage: s[0] == s[0]
793
+ True
794
+ sage: s[1] == s[0]
795
+ False
796
+ """
797
+ if not isinstance(other, SwapOperator):
798
+ return False
799
+ return self._position == other._position
800
+
801
+ def __ne__(self, other) -> bool:
802
+ """
803
+ Check whether ``self`` is not equal to ``other``.
804
+
805
+ EXAMPLES::
806
+
807
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
808
+ sage: s = [SwapOperator(i) for i in range(3)]
809
+ sage: s[0] != s[0]
810
+ False
811
+ sage: s[1] != s[0]
812
+ True
813
+ """
814
+ return not (self == other)
815
+
816
+ def __repr__(self) -> str:
817
+ r"""
818
+ Representation string.
819
+
820
+ EXAMPLES::
821
+
822
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
823
+ sage: s3 = SwapOperator(3)
824
+ sage: s3.__repr__()
825
+ 'Swap positions 3 and 4'
826
+ """
827
+ pos = self._position
828
+ return f"Swap positions {pos} and {pos + 1}"
829
+
830
+ def __str__(self) -> str:
831
+ r"""
832
+ A short str representation (used, for example, in labelling edges of
833
+ graphs).
834
+
835
+ EXAMPLES::
836
+
837
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
838
+ sage: s3 = SwapOperator(3)
839
+ sage: s3.__str__()
840
+ '3'
841
+ """
842
+ return "%s" % self._position
843
+
844
+ def __call__(self, u):
845
+ r"""
846
+ Return the object obtained from swapping the items in positions
847
+ ``i`` and ``i+1`` of ``u``.
848
+
849
+ EXAMPLES::
850
+
851
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
852
+ sage: s3 = SwapOperator(3)
853
+ sage: s3((1,2,3,4,5))
854
+ (1, 2, 3, 5, 4)
855
+ sage: s3([1,2,3,4,5])
856
+ [1, 2, 3, 5, 4]
857
+ """
858
+ i = self._position
859
+ if isinstance(u, Permutation):
860
+ return Permutation(u[:i] + u[i:i + 2][::-1] + u[i + 2:])
861
+ return type(u)(u[:i] + u[i:i + 2][::-1] + u[i + 2:])
862
+
863
+ def position(self):
864
+ r"""
865
+ Return ``i`` where ``self`` is the operator that swaps positions ``i``
866
+ and ``i+1``.
867
+
868
+ EXAMPLES::
869
+
870
+ sage: from sage.combinat.yang_baxter_graph import SwapOperator
871
+ sage: s3 = SwapOperator(3)
872
+ sage: s3.position()
873
+ 3
874
+ """
875
+ return self._position
876
+
877
+
878
+ class SwapIncreasingOperator(SwapOperator):
879
+ def __repr__(self) -> str:
880
+ r"""
881
+ Representation string.
882
+
883
+ EXAMPLES::
884
+
885
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
886
+ sage: s3 = SwapIncreasingOperator(3)
887
+ sage: s3.__repr__()
888
+ 'Swap-if-increasing at position 3'
889
+ """
890
+ return "Swap-if-increasing at position %s" % self._position
891
+
892
+ def __call__(self, u):
893
+ r"""
894
+ Return a copy of ``u`` with ``u[i-1]`` and ``u[i]`` swapped if
895
+ ``u[i-1] > u[i]``; otherwise returns ``u``.
896
+
897
+ INPUT:
898
+
899
+ - ``i`` -- positive integer between ``1`` and ``len(u)-1``, inclusive
900
+
901
+ - ``u`` -- tuple, list, permutation, etc.
902
+
903
+ EXAMPLES::
904
+
905
+ sage: Y = YangBaxterGraph(partition=[2,2]) # needs sage.combinat
906
+ sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator
907
+ sage: operators = [SwapIncreasingOperator(i) for i in range(3)]
908
+ sage: [op((1,2,3,4)) for op in operators]
909
+ [(2, 1, 3, 4), (1, 3, 2, 4), (1, 2, 4, 3)]
910
+ sage: [op([4,3,2,1]) for op in operators]
911
+ [[4, 3, 2, 1], [4, 3, 2, 1], [4, 3, 2, 1]]
912
+ sage: [op(Permutation([1,3,2,4])) for op in operators]
913
+ [[3, 1, 2, 4], [1, 3, 2, 4], [1, 3, 4, 2]]
914
+ """
915
+ i = self._position
916
+ j = i + 1
917
+ if u[i] < u[j]:
918
+ v = list(u)
919
+ v[j], v[i] = v[i], v[j]
920
+ if isinstance(u, Permutation):
921
+ return Permutation(v)
922
+ return type(u)(v)
923
+ return u