passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.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 (400) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  3. passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
  4. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  5. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  6. passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  7. passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
  8. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  9. sage/algebras/all.py +24 -0
  10. sage/algebras/all__sagemath_combinat.py +35 -0
  11. sage/algebras/askey_wilson.py +935 -0
  12. sage/algebras/associated_graded.py +345 -0
  13. sage/algebras/cellular_basis.py +350 -0
  14. sage/algebras/cluster_algebra.py +2766 -0
  15. sage/algebras/down_up_algebra.py +860 -0
  16. sage/algebras/free_algebra.py +1698 -0
  17. sage/algebras/free_algebra_element.py +345 -0
  18. sage/algebras/free_algebra_quotient.py +405 -0
  19. sage/algebras/free_algebra_quotient_element.py +295 -0
  20. sage/algebras/free_zinbiel_algebra.py +885 -0
  21. sage/algebras/hall_algebra.py +783 -0
  22. sage/algebras/hecke_algebras/all.py +4 -0
  23. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  24. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  25. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  28. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  29. sage/algebras/jordan_algebra.py +1773 -0
  30. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  31. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  32. sage/algebras/lie_conformal_algebras/all.py +18 -0
  33. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  34. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  35. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  36. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  37. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  38. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  39. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  40. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  41. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  45. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  46. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  47. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  48. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  49. sage/algebras/nil_coxeter_algebra.py +191 -0
  50. sage/algebras/q_commuting_polynomials.py +673 -0
  51. sage/algebras/q_system.py +608 -0
  52. sage/algebras/quantum_clifford.py +959 -0
  53. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  54. sage/algebras/quantum_groups/all.py +9 -0
  55. sage/algebras/quantum_groups/fock_space.py +2219 -0
  56. sage/algebras/quantum_groups/q_numbers.py +207 -0
  57. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  58. sage/algebras/quantum_groups/representations.py +591 -0
  59. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  60. sage/algebras/quantum_oscillator.py +623 -0
  61. sage/algebras/quaternion_algebra.py +20 -0
  62. sage/algebras/quaternion_algebra_element.py +55 -0
  63. sage/algebras/rational_cherednik_algebra.py +525 -0
  64. sage/algebras/schur_algebra.py +670 -0
  65. sage/algebras/shuffle_algebra.py +1011 -0
  66. sage/algebras/splitting_algebra.py +779 -0
  67. sage/algebras/tensor_algebra.py +709 -0
  68. sage/algebras/yangian.py +1082 -0
  69. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  70. sage/all__sagemath_combinat.py +35 -0
  71. sage/combinat/SJT.py +255 -0
  72. sage/combinat/affine_permutation.py +2405 -0
  73. sage/combinat/algebraic_combinatorics.py +55 -0
  74. sage/combinat/all.py +53 -0
  75. sage/combinat/all__sagemath_combinat.py +195 -0
  76. sage/combinat/alternating_sign_matrix.py +2063 -0
  77. sage/combinat/baxter_permutations.py +346 -0
  78. sage/combinat/bijectionist.py +3220 -0
  79. sage/combinat/binary_recurrence_sequences.py +1180 -0
  80. sage/combinat/blob_algebra.py +685 -0
  81. sage/combinat/catalog_partitions.py +27 -0
  82. sage/combinat/chas/all.py +23 -0
  83. sage/combinat/chas/fsym.py +1180 -0
  84. sage/combinat/chas/wqsym.py +2601 -0
  85. sage/combinat/cluster_complex.py +326 -0
  86. sage/combinat/colored_permutations.py +2039 -0
  87. sage/combinat/colored_permutations_representations.py +964 -0
  88. sage/combinat/composition_signed.py +142 -0
  89. sage/combinat/composition_tableau.py +855 -0
  90. sage/combinat/constellation.py +1729 -0
  91. sage/combinat/core.py +751 -0
  92. sage/combinat/counting.py +12 -0
  93. sage/combinat/crystals/affine.py +742 -0
  94. sage/combinat/crystals/affine_factorization.py +518 -0
  95. sage/combinat/crystals/affinization.py +331 -0
  96. sage/combinat/crystals/alcove_path.py +2013 -0
  97. sage/combinat/crystals/all.py +22 -0
  98. sage/combinat/crystals/bkk_crystals.py +141 -0
  99. sage/combinat/crystals/catalog.py +115 -0
  100. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  101. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  102. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  103. sage/combinat/crystals/crystals.py +257 -0
  104. sage/combinat/crystals/direct_sum.py +260 -0
  105. sage/combinat/crystals/elementary_crystals.py +1251 -0
  106. sage/combinat/crystals/fast_crystals.py +441 -0
  107. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  108. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  109. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  110. sage/combinat/crystals/induced_structure.py +695 -0
  111. sage/combinat/crystals/infinity_crystals.py +730 -0
  112. sage/combinat/crystals/kac_modules.py +863 -0
  113. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  114. sage/combinat/crystals/kyoto_path_model.py +497 -0
  115. sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
  116. sage/combinat/crystals/letters.pxd +79 -0
  117. sage/combinat/crystals/letters.pyx +3056 -0
  118. sage/combinat/crystals/littelmann_path.py +1518 -0
  119. sage/combinat/crystals/monomial_crystals.py +1262 -0
  120. sage/combinat/crystals/multisegments.py +462 -0
  121. sage/combinat/crystals/mv_polytopes.py +467 -0
  122. sage/combinat/crystals/pbw_crystal.py +511 -0
  123. sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
  124. sage/combinat/crystals/pbw_datum.pxd +4 -0
  125. sage/combinat/crystals/pbw_datum.pyx +487 -0
  126. sage/combinat/crystals/polyhedral_realization.py +372 -0
  127. sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/combinat/crystals/spins.pxd +21 -0
  129. sage/combinat/crystals/spins.pyx +756 -0
  130. sage/combinat/crystals/star_crystal.py +290 -0
  131. sage/combinat/crystals/subcrystal.py +464 -0
  132. sage/combinat/crystals/tensor_product.py +1177 -0
  133. sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  135. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  136. sage/combinat/crystals/virtual_crystal.py +420 -0
  137. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  138. sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/combinat/debruijn_sequence.pyx +355 -0
  140. sage/combinat/decorated_permutation.py +270 -0
  141. sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
  142. sage/combinat/degree_sequences.pyx +588 -0
  143. sage/combinat/derangements.py +527 -0
  144. sage/combinat/descent_algebra.py +1008 -0
  145. sage/combinat/diagram.py +1551 -0
  146. sage/combinat/diagram_algebras.py +5886 -0
  147. sage/combinat/dyck_word.py +4349 -0
  148. sage/combinat/e_one_star.py +1623 -0
  149. sage/combinat/enumerated_sets.py +123 -0
  150. sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
  151. sage/combinat/expnums.pyx +148 -0
  152. sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
  153. sage/combinat/fast_vector_partitions.pyx +346 -0
  154. sage/combinat/fqsym.py +1977 -0
  155. sage/combinat/free_dendriform_algebra.py +954 -0
  156. sage/combinat/free_prelie_algebra.py +1141 -0
  157. sage/combinat/fully_commutative_elements.py +1077 -0
  158. sage/combinat/fully_packed_loop.py +1523 -0
  159. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  160. sage/combinat/gray_codes.py +311 -0
  161. sage/combinat/grossman_larson_algebras.py +667 -0
  162. sage/combinat/growth.py +4352 -0
  163. sage/combinat/hall_polynomial.py +188 -0
  164. sage/combinat/hillman_grassl.py +866 -0
  165. sage/combinat/integer_matrices.py +329 -0
  166. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  167. sage/combinat/k_tableau.py +4564 -0
  168. sage/combinat/kazhdan_lusztig.py +215 -0
  169. sage/combinat/key_polynomial.py +885 -0
  170. sage/combinat/knutson_tao_puzzles.py +2286 -0
  171. sage/combinat/lr_tableau.py +311 -0
  172. sage/combinat/matrices/all.py +24 -0
  173. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  174. sage/combinat/matrices/latin.py +2912 -0
  175. sage/combinat/misc.py +401 -0
  176. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  177. sage/combinat/ncsf_qsym/all.py +21 -0
  178. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  179. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  180. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  181. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  182. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  183. sage/combinat/ncsym/all.py +21 -0
  184. sage/combinat/ncsym/bases.py +855 -0
  185. sage/combinat/ncsym/dual.py +593 -0
  186. sage/combinat/ncsym/ncsym.py +2076 -0
  187. sage/combinat/necklace.py +551 -0
  188. sage/combinat/non_decreasing_parking_function.py +634 -0
  189. sage/combinat/nu_dyck_word.py +1474 -0
  190. sage/combinat/output.py +861 -0
  191. sage/combinat/parallelogram_polyomino.py +4326 -0
  192. sage/combinat/parking_functions.py +1602 -0
  193. sage/combinat/partition_algebra.py +1998 -0
  194. sage/combinat/partition_kleshchev.py +1982 -0
  195. sage/combinat/partition_shifting_algebras.py +584 -0
  196. sage/combinat/partition_tuple.py +3114 -0
  197. sage/combinat/path_tableaux/all.py +13 -0
  198. sage/combinat/path_tableaux/catalog.py +29 -0
  199. sage/combinat/path_tableaux/dyck_path.py +380 -0
  200. sage/combinat/path_tableaux/frieze.py +476 -0
  201. sage/combinat/path_tableaux/path_tableau.py +728 -0
  202. sage/combinat/path_tableaux/semistandard.py +510 -0
  203. sage/combinat/perfect_matching.py +779 -0
  204. sage/combinat/plane_partition.py +3300 -0
  205. sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
  206. sage/combinat/q_bernoulli.pyx +128 -0
  207. sage/combinat/quickref.py +81 -0
  208. sage/combinat/recognizable_series.py +2051 -0
  209. sage/combinat/regular_sequence.py +4316 -0
  210. sage/combinat/regular_sequence_bounded.py +543 -0
  211. sage/combinat/restricted_growth.py +81 -0
  212. sage/combinat/ribbon.py +20 -0
  213. sage/combinat/ribbon_shaped_tableau.py +489 -0
  214. sage/combinat/ribbon_tableau.py +1180 -0
  215. sage/combinat/rigged_configurations/all.py +46 -0
  216. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  217. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  218. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  219. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  222. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  223. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  224. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  225. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  226. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  227. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  228. sage/combinat/rigged_configurations/bijection.py +143 -0
  229. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  230. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  231. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  232. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  233. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  234. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  235. sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
  236. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  238. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  240. sage/combinat/rsk.py +3438 -0
  241. sage/combinat/schubert_polynomial.py +508 -0
  242. sage/combinat/set_partition.py +3318 -0
  243. sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  244. sage/combinat/set_partition_iterator.pyx +136 -0
  245. sage/combinat/set_partition_ordered.py +1590 -0
  246. sage/combinat/sf/abreu_nigro.py +346 -0
  247. sage/combinat/sf/all.py +52 -0
  248. sage/combinat/sf/character.py +576 -0
  249. sage/combinat/sf/classical.py +319 -0
  250. sage/combinat/sf/dual.py +996 -0
  251. sage/combinat/sf/elementary.py +549 -0
  252. sage/combinat/sf/hall_littlewood.py +1028 -0
  253. sage/combinat/sf/hecke.py +336 -0
  254. sage/combinat/sf/homogeneous.py +464 -0
  255. sage/combinat/sf/jack.py +1428 -0
  256. sage/combinat/sf/k_dual.py +1458 -0
  257. sage/combinat/sf/kfpoly.py +447 -0
  258. sage/combinat/sf/llt.py +789 -0
  259. sage/combinat/sf/macdonald.py +2019 -0
  260. sage/combinat/sf/monomial.py +525 -0
  261. sage/combinat/sf/multiplicative.py +113 -0
  262. sage/combinat/sf/new_kschur.py +1786 -0
  263. sage/combinat/sf/ns_macdonald.py +964 -0
  264. sage/combinat/sf/orthogonal.py +246 -0
  265. sage/combinat/sf/orthotriang.py +355 -0
  266. sage/combinat/sf/powersum.py +963 -0
  267. sage/combinat/sf/schur.py +880 -0
  268. sage/combinat/sf/sf.py +1653 -0
  269. sage/combinat/sf/sfa.py +7053 -0
  270. sage/combinat/sf/symplectic.py +253 -0
  271. sage/combinat/sf/witt.py +721 -0
  272. sage/combinat/shifted_primed_tableau.py +2735 -0
  273. sage/combinat/shuffle.py +830 -0
  274. sage/combinat/sidon_sets.py +146 -0
  275. sage/combinat/similarity_class_type.py +1721 -0
  276. sage/combinat/sine_gordon.py +618 -0
  277. sage/combinat/six_vertex_model.py +784 -0
  278. sage/combinat/skew_partition.py +2053 -0
  279. sage/combinat/skew_tableau.py +2989 -0
  280. sage/combinat/sloane_functions.py +8935 -0
  281. sage/combinat/specht_module.py +1403 -0
  282. sage/combinat/species/all.py +48 -0
  283. sage/combinat/species/characteristic_species.py +321 -0
  284. sage/combinat/species/composition_species.py +273 -0
  285. sage/combinat/species/cycle_species.py +284 -0
  286. sage/combinat/species/empty_species.py +155 -0
  287. sage/combinat/species/functorial_composition_species.py +148 -0
  288. sage/combinat/species/generating_series.py +673 -0
  289. sage/combinat/species/library.py +148 -0
  290. sage/combinat/species/linear_order_species.py +169 -0
  291. sage/combinat/species/misc.py +83 -0
  292. sage/combinat/species/partition_species.py +290 -0
  293. sage/combinat/species/permutation_species.py +268 -0
  294. sage/combinat/species/product_species.py +423 -0
  295. sage/combinat/species/recursive_species.py +476 -0
  296. sage/combinat/species/set_species.py +192 -0
  297. sage/combinat/species/species.py +820 -0
  298. sage/combinat/species/structure.py +539 -0
  299. sage/combinat/species/subset_species.py +243 -0
  300. sage/combinat/species/sum_species.py +225 -0
  301. sage/combinat/subword.py +564 -0
  302. sage/combinat/subword_complex.py +2122 -0
  303. sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
  304. sage/combinat/subword_complex_c.pyx +119 -0
  305. sage/combinat/super_tableau.py +821 -0
  306. sage/combinat/superpartition.py +1154 -0
  307. sage/combinat/symmetric_group_algebra.py +3774 -0
  308. sage/combinat/symmetric_group_representations.py +1830 -0
  309. sage/combinat/t_sequences.py +877 -0
  310. sage/combinat/tableau.py +9506 -0
  311. sage/combinat/tableau_residues.py +860 -0
  312. sage/combinat/tableau_tuple.py +5353 -0
  313. sage/combinat/tiling.py +2432 -0
  314. sage/combinat/triangles_FHM.py +777 -0
  315. sage/combinat/tutorial.py +1857 -0
  316. sage/combinat/vector_partition.py +337 -0
  317. sage/combinat/words/abstract_word.py +1722 -0
  318. sage/combinat/words/all.py +59 -0
  319. sage/combinat/words/alphabet.py +268 -0
  320. sage/combinat/words/finite_word.py +7201 -0
  321. sage/combinat/words/infinite_word.py +113 -0
  322. sage/combinat/words/lyndon_word.py +652 -0
  323. sage/combinat/words/morphic.py +351 -0
  324. sage/combinat/words/morphism.py +3878 -0
  325. sage/combinat/words/paths.py +2932 -0
  326. sage/combinat/words/shuffle_product.py +278 -0
  327. sage/combinat/words/suffix_trees.py +1873 -0
  328. sage/combinat/words/word.py +769 -0
  329. sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
  330. sage/combinat/words/word_char.pyx +847 -0
  331. sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
  332. sage/combinat/words/word_datatypes.pxd +4 -0
  333. sage/combinat/words/word_datatypes.pyx +1067 -0
  334. sage/combinat/words/word_generators.py +2026 -0
  335. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  336. sage/combinat/words/word_options.py +99 -0
  337. sage/combinat/words/words.py +2396 -0
  338. sage/data_structures/all__sagemath_combinat.py +1 -0
  339. sage/databases/all__sagemath_combinat.py +13 -0
  340. sage/databases/findstat.py +4897 -0
  341. sage/databases/oeis.py +2058 -0
  342. sage/databases/sloane.py +393 -0
  343. sage/dynamics/all__sagemath_combinat.py +14 -0
  344. sage/dynamics/cellular_automata/all.py +7 -0
  345. sage/dynamics/cellular_automata/catalog.py +34 -0
  346. sage/dynamics/cellular_automata/elementary.py +612 -0
  347. sage/dynamics/cellular_automata/glca.py +477 -0
  348. sage/dynamics/cellular_automata/solitons.py +1463 -0
  349. sage/dynamics/finite_dynamical_system.py +1249 -0
  350. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  351. sage/games/all.py +7 -0
  352. sage/games/hexad.py +704 -0
  353. sage/games/quantumino.py +591 -0
  354. sage/games/sudoku.py +889 -0
  355. sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
  356. sage/games/sudoku_backtrack.pyx +189 -0
  357. sage/groups/all__sagemath_combinat.py +1 -0
  358. sage/groups/indexed_free_group.py +489 -0
  359. sage/libs/all__sagemath_combinat.py +6 -0
  360. sage/libs/lrcalc/__init__.py +1 -0
  361. sage/libs/lrcalc/lrcalc.py +525 -0
  362. sage/libs/symmetrica/__init__.py +7 -0
  363. sage/libs/symmetrica/all.py +101 -0
  364. sage/libs/symmetrica/kostka.pxi +168 -0
  365. sage/libs/symmetrica/part.pxi +193 -0
  366. sage/libs/symmetrica/plet.pxi +42 -0
  367. sage/libs/symmetrica/sab.pxi +196 -0
  368. sage/libs/symmetrica/sb.pxi +332 -0
  369. sage/libs/symmetrica/sc.pxi +192 -0
  370. sage/libs/symmetrica/schur.pxi +956 -0
  371. sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
  372. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  373. sage/libs/symmetrica/symmetrica.pyx +39 -0
  374. sage/monoids/all.py +13 -0
  375. sage/monoids/automatic_semigroup.py +1054 -0
  376. sage/monoids/free_abelian_monoid.py +315 -0
  377. sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
  378. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  379. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  380. sage/monoids/free_monoid.py +335 -0
  381. sage/monoids/free_monoid_element.py +431 -0
  382. sage/monoids/hecke_monoid.py +65 -0
  383. sage/monoids/string_monoid.py +817 -0
  384. sage/monoids/string_monoid_element.py +547 -0
  385. sage/monoids/string_ops.py +143 -0
  386. sage/monoids/trace_monoid.py +972 -0
  387. sage/rings/all__sagemath_combinat.py +2 -0
  388. sage/sat/all.py +4 -0
  389. sage/sat/boolean_polynomials.py +405 -0
  390. sage/sat/converters/__init__.py +6 -0
  391. sage/sat/converters/anf2cnf.py +14 -0
  392. sage/sat/converters/polybori.py +611 -0
  393. sage/sat/solvers/__init__.py +5 -0
  394. sage/sat/solvers/cryptominisat.py +287 -0
  395. sage/sat/solvers/dimacs.py +783 -0
  396. sage/sat/solvers/picosat.py +228 -0
  397. sage/sat/solvers/sat_lp.py +156 -0
  398. sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
  399. sage/sat/solvers/satsolver.pxd +3 -0
  400. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,1475 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.graphs sage.modules
3
+ r"""
4
+ Kleber trees
5
+
6
+ A Kleber tree is a tree of weights generated by Kleber's algorithm
7
+ [Kleber1]_. The nodes correspond to the weights in the positive Weyl chamber
8
+ obtained by subtracting a (nonzero) positive root. The edges are labeled by
9
+ the coefficients of the roots of the difference.
10
+
11
+ EXAMPLES::
12
+
13
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
14
+ sage: KleberTree(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]])
15
+ Kleber tree of Cartan type ['A', 3, 1] and B = ((3, 2), (2, 1), (1, 1), (1, 1))
16
+ sage: KleberTree(['D', 4, 1], [[2,2]])
17
+ Kleber tree of Cartan type ['D', 4, 1] and B = ((2, 2),)
18
+
19
+ TESTS::
20
+
21
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
22
+ sage: KT = KleberTree(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]])
23
+ sage: sorted((x.weight.to_vector(), x.up_root.to_vector()) for x in KT.list())
24
+ [((0, 0, 2), (1, 1, 0)),
25
+ ((0, 0, 2), (2, 2, 1)),
26
+ ((0, 1, 0), (0, 0, 1)),
27
+ ((0, 1, 0), (1, 1, 1)),
28
+ ((0, 2, 2), (1, 0, 0)),
29
+ ((1, 0, 3), (1, 1, 0)),
30
+ ((1, 1, 1), (1, 1, 1)),
31
+ ((2, 0, 0), (0, 1, 1)),
32
+ ((2, 1, 2), (0, 0, 0)),
33
+ ((3, 0, 1), (0, 1, 1))]
34
+
35
+ sage: KT = KleberTree(['A', 7, 1], [[3,2], [2,1], [1,1]])
36
+ sage: KT
37
+ Kleber tree of Cartan type ['A', 7, 1] and B = ((3, 2), (2, 1), (1, 1))
38
+ sage: sorted((x.weight.to_vector(), x.up_root.to_vector()) for x in KT.list())
39
+ [((0, 0, 0, 1, 1, 0, 0), (1, 1, 1, 0, 0, 0, 0)),
40
+ ((0, 0, 1, 0, 0, 1, 0), (2, 3, 3, 2, 1, 0, 0)),
41
+ ((0, 0, 3, 0, 0, 0, 0), (1, 1, 0, 0, 0, 0, 0)),
42
+ ((0, 1, 1, 1, 0, 0, 0), (1, 1, 1, 0, 0, 0, 0)),
43
+ ((1, 0, 0, 2, 0, 0, 0), (0, 1, 1, 0, 0, 0, 0)),
44
+ ((1, 0, 1, 0, 1, 0, 0), (1, 2, 2, 1, 0, 0, 0)),
45
+ ((1, 1, 2, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)),
46
+ ((2, 0, 1, 1, 0, 0, 0), (0, 1, 1, 0, 0, 0, 0))]
47
+
48
+ AUTHORS:
49
+
50
+ - Travis Scrimshaw (2011-05-03): initial version
51
+ - Travis Scrimshaw (2013-02-13): added support for virtual trees and improved
52
+ `\LaTeX` output
53
+ """
54
+
55
+ # ****************************************************************************
56
+ # Copyright (C) 2011, 2012 Travis Scrimshaw <tscrim@ucdavis.edu>
57
+ #
58
+ # Distributed under the terms of the GNU General Public License (GPL)
59
+ #
60
+ # This code is distributed in the hope that it will be useful,
61
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
62
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
63
+ # General Public License for more details.
64
+ #
65
+ # The full text of the GPL is available at:
66
+ #
67
+ # https://www.gnu.org/licenses/
68
+ # ****************************************************************************
69
+
70
+ import itertools
71
+
72
+ from sage.misc.lazy_attribute import lazy_attribute
73
+ from sage.misc.cachefunc import cached_method
74
+ from sage.misc.latex import latex
75
+ from sage.misc.lazy_import import lazy_import
76
+ from sage.misc.misc_c import prod
77
+ from sage.arith.misc import binomial
78
+ from sage.features import FeatureNotPresentError
79
+ from sage.rings.integer import Integer
80
+
81
+ from sage.structure.parent import Parent
82
+ from sage.structure.element import Element
83
+ from sage.structure.unique_representation import UniqueRepresentation
84
+ from sage.structure.richcmp import richcmp_not_equal, richcmp
85
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
86
+
87
+ from sage.combinat.root_system.cartan_type import CartanType
88
+
89
+ lazy_import('sage.graphs.digraph', 'DiGraph')
90
+ lazy_import('sage.graphs.dot2tex_utils', 'have_dot2tex')
91
+
92
+ ######################################
93
+ # Latex method for viewing the trees #
94
+ ######################################
95
+
96
+
97
+ def _draw_tree(tree_node, node_label=True, style_point=None, style_node='fill=white', style_line=None,
98
+ hspace=2.5, vspace=-2.5, start=None, rpos=None, node_id=0, node_prefix='T',
99
+ edge_labels=True, use_vector_notation=False):
100
+ r"""
101
+ Return the tikz latex for drawing the Kleber tree.
102
+
103
+ AUTHORS:
104
+
105
+ - Viviane Pons (2013-02-13): Initial version
106
+ - Travis Scrimshaw (2013-03-02): Modified to work with Kleber tree output
107
+
108
+ .. WARNING::
109
+
110
+ Internal latex function.
111
+
112
+ EXAMPLES::
113
+
114
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
115
+ sage: KT = KleberTree(['A',3,1], [[3,2],[1,1]])
116
+ sage: latex(KT) # indirect doctest
117
+ \begin{tikzpicture}
118
+ \node[fill=white] (T0) at (0.000, 0.000){$V_{\omega_{1}+2\omega_{3}}$};
119
+ \node (T00) at (0.000, -2.500){$V_{\omega_{3}}$};
120
+ \draw (T0) to node[sloped,above]{\tiny $\alpha_{1} + \alpha_{2} + \alpha_{3}$} (T00);
121
+ \end{tikzpicture}
122
+ """
123
+ if start is None:
124
+ start = [0., 0.]
125
+ if rpos is None:
126
+ rpos = [0., 0.]
127
+
128
+ if not tree_node.children:
129
+ r = ''
130
+ node_name = node_prefix + str(node_id)
131
+ r = "\\node (%s) at (%.3f, %.3f)" % (node_name, *start)
132
+ if node_label:
133
+ r += "{$%s$};\n" % tree_node._latex_()
134
+ else:
135
+ r += "{};\n"
136
+ rpos[0] = start[0]
137
+ rpos[1] = start[1]
138
+ start[0] += hspace
139
+ return r
140
+
141
+ node_name = node_prefix + str(node_id)
142
+ if style_line is None:
143
+ style_line_str = ''
144
+ else:
145
+ style_line_str = "[%s]" % style_line
146
+ if node_label:
147
+ node_place_str = ''
148
+ else:
149
+ node_place_str = ".center"
150
+
151
+ nb_children = len(tree_node.children)
152
+ half = nb_children // 2
153
+ children_str = ''
154
+ pos = [start[0], start[1]]
155
+ start[1] += vspace
156
+ lines_str = ''
157
+
158
+ # Getting children string
159
+ for i in range(nb_children):
160
+ if i == half and nb_children % 2 == 0:
161
+ pos[0] = start[0]
162
+ start[0] += hspace
163
+ if i == half+1 and nb_children % 2 == 1:
164
+ pos[0] = rpos[0]
165
+ child = tree_node.children[i]
166
+ children_str += _draw_tree(child, node_label=node_label, style_node=style_node, style_point=style_point, style_line=style_line, hspace=hspace, vspace=vspace, start=start, rpos=rpos, node_id=i, node_prefix=node_name, edge_labels=edge_labels, use_vector_notation=use_vector_notation)
167
+ if edge_labels:
168
+ if use_vector_notation:
169
+ edge_str = latex(child.up_root.to_vector())
170
+ else:
171
+ edge_str = latex(child.up_root)
172
+ lines_str += "\\draw%s (%s%s) to node[sloped,above]{\\tiny $%s$} (%s%s%s);\n" % (style_line_str, node_name, node_place_str, edge_str, node_name, i, node_place_str)
173
+ else:
174
+ lines_str += "\\draw%s (%s%s) -- (%s%s%s);\n" % (style_line_str, node_name, node_place_str, node_name, i, node_place_str)
175
+
176
+ # drawing root
177
+ if style_node is None:
178
+ style_node = ''
179
+ else:
180
+ style_node = "[%s]" % style_node
181
+ if style_point is None:
182
+ style_point = ''
183
+ else:
184
+ style_point = "[%s]" % style_point
185
+ start[1] -= vspace
186
+ rpos[0] = pos[0]
187
+ rpos[1] = pos[1]
188
+ point_str = ''
189
+ node_str = "\\node%s (%s) at (%.3f, %.3f)" % (style_node, node_name, *pos)
190
+ if node_label:
191
+ node_str += "{$%s$};\n" % tree_node._latex_()
192
+ else:
193
+ node_str += "{};\n"
194
+ point_str = "\\draw%s (%s) circle;\n" % (style_point, node_name)
195
+
196
+ res = node_str
197
+ res += children_str
198
+ res += lines_str
199
+ res += point_str
200
+ return res
201
+
202
+ #####################
203
+ # Kleber tree nodes #
204
+ #####################
205
+
206
+
207
+ class KleberTreeNode(Element):
208
+ r"""
209
+ A node in the Kleber tree.
210
+
211
+ This class is meant to be used internally by the Kleber tree class and
212
+ should not be created directly by the user.
213
+
214
+ For more on the Kleber tree and the nodes, see :class:`KleberTree`.
215
+
216
+ The dominating root is the ``up_root`` which is the difference
217
+ between the parent node's weight and this node's weight.
218
+
219
+ INPUT:
220
+
221
+ - ``parent_obj`` -- the parent object of this element
222
+ - ``node_weight`` -- the weight of this node
223
+ - ``dominant_root`` -- the dominating root
224
+ - ``parent_node`` -- (default: ``None``) the parent node of this node
225
+ """
226
+
227
+ def __init__(self, parent_obj, node_weight, dominant_root, parent_node=None):
228
+ r"""
229
+ Initialize the tree node.
230
+
231
+ TESTS::
232
+
233
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
234
+ sage: RS = RootSystem(['A', 2])
235
+ sage: WS = RS.weight_lattice()
236
+ sage: R = RS.root_lattice()
237
+ sage: KT = KleberTree(['A', 2, 1], [[1,1]])
238
+ sage: parent = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero())
239
+ sage: parent
240
+ Kleber tree node with weight [5, 2] and upwards edge root [0, 0]
241
+ sage: parent.parent_node
242
+ sage: child = KT(WS.sum_of_terms([(1,3), (2,1)]), R.sum_of_terms([(1,1), (2,2)]), parent)
243
+ sage: child
244
+ Kleber tree node with weight [3, 1] and upwards edge root [1, 2]
245
+ sage: child.parent_node
246
+ Kleber tree node with weight [5, 2] and upwards edge root [0, 0]
247
+ sage: TestSuite(parent).run()
248
+ """
249
+ self.parent_node = parent_node
250
+ self.children = []
251
+ self.weight = node_weight
252
+ self.up_root = dominant_root
253
+ Element.__init__(self, parent_obj)
254
+
255
+ @lazy_attribute
256
+ def depth(self):
257
+ """
258
+ Return the depth of this node in the tree.
259
+
260
+ EXAMPLES::
261
+
262
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
263
+ sage: RS = RootSystem(['A', 2])
264
+ sage: WS = RS.weight_lattice()
265
+ sage: R = RS.root_lattice()
266
+ sage: KT = KleberTree(['A', 2, 1], [[1,1]])
267
+ sage: n = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero())
268
+ sage: n.depth
269
+ 0
270
+ sage: n2 = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero(), n)
271
+ sage: n2.depth
272
+ 1
273
+ """
274
+ depth = -1 # Offset
275
+ cur = self
276
+ while cur is not None:
277
+ depth += 1
278
+ cur = cur.parent_node
279
+
280
+ return depth
281
+
282
+ @cached_method
283
+ def multiplicity(self):
284
+ r"""
285
+ Return the multiplicity of ``self``.
286
+
287
+ The multiplicity of a node `x` of depth `d` weight `\lambda` in a
288
+ simply-laced Kleber tree is equal to:
289
+
290
+ .. MATH::
291
+
292
+ \prod_{i > 0} \prod_{a \in \overline{I}}
293
+ \binom{p_i^{(a)} + m_i^{(a)}}{p_i^{(a)}}
294
+
295
+ Recall that
296
+
297
+ .. MATH::
298
+
299
+ m_i^{(a)} = \left( \lambda^{(i-1)} - 2 \lambda^{(i)} +
300
+ \lambda^{(i+1)} \mid \overline{\Lambda}_a \right),
301
+
302
+ p_i^{(a)} = \left( \alpha_a \mid \lambda^{(i)} \right)
303
+ - \sum_{j > i} (j - i) L_j^{(a)},
304
+
305
+ where `\lambda^{(i)}` is the weight node at depth `i` in the path
306
+ to `x` from the root and we set `\lambda^{(j)} = \lambda` for all
307
+ `j \geq d`.
308
+
309
+ Note that `m_i^{(a)} = 0` for all `i > d`.
310
+
311
+ EXAMPLES::
312
+
313
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
314
+ sage: KT = KleberTree(['A',3,1], [[3,2],[2,1],[1,1],[1,1]])
315
+ sage: for x in KT: x, x.multiplicity()
316
+ (Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 0, 0], 1)
317
+ (Kleber tree node with weight [3, 0, 1] and upwards edge root [0, 1, 1], 1)
318
+ (Kleber tree node with weight [0, 2, 2] and upwards edge root [1, 0, 0], 1)
319
+ (Kleber tree node with weight [1, 0, 3] and upwards edge root [1, 1, 0], 2)
320
+ (Kleber tree node with weight [1, 1, 1] and upwards edge root [1, 1, 1], 4)
321
+ (Kleber tree node with weight [0, 0, 2] and upwards edge root [2, 2, 1], 2)
322
+ (Kleber tree node with weight [2, 0, 0] and upwards edge root [0, 1, 1], 2)
323
+ (Kleber tree node with weight [0, 0, 2] and upwards edge root [1, 1, 0], 1)
324
+ (Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 1, 1], 2)
325
+ (Kleber tree node with weight [0, 1, 0] and upwards edge root [0, 0, 1], 1)
326
+
327
+ TESTS:
328
+
329
+ We check that :issue:`16057` is fixed::
330
+
331
+ sage: RC = RiggedConfigurations(['D',4,1], [[1,3],[3,3],[4,3]])
332
+ sage: sum(x.multiplicity() for x in RC.kleber_tree()) == len(RC.module_generators)
333
+ True
334
+ """
335
+ # The multiplicity corresponding to the root is always 1
336
+ if self.parent_node is None:
337
+ return Integer(1)
338
+
339
+ mult = Integer(1)
340
+ for a, m in self.up_root:
341
+ p = self.weight[a]
342
+ for r, s in self.parent().B:
343
+ if r == a and s > self.depth:
344
+ p -= s - self.depth
345
+ mult *= binomial(m + p, m)
346
+
347
+ prev_up_root = self.up_root
348
+ cur = self.parent_node
349
+ while cur.parent_node is not None:
350
+ root_diff = cur.up_root - prev_up_root
351
+ for a, m in root_diff:
352
+ p = cur.weight[a]
353
+ for r, s in self.parent().B:
354
+ if r == a and s > cur.depth:
355
+ p -= s - cur.depth
356
+ mult *= binomial(m + p, m)
357
+ prev_up_root = cur.up_root
358
+ cur = cur.parent_node
359
+
360
+ return mult
361
+
362
+ def __hash__(self):
363
+ r"""
364
+ TESTS::
365
+
366
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
367
+ sage: RS = RootSystem(['A', 2])
368
+ sage: WS = RS.weight_lattice()
369
+ sage: R = RS.root_lattice()
370
+ sage: KT = KleberTree(['A', 2, 1], [[1,1]])
371
+ sage: n = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero())
372
+ sage: n2 = KT(WS.sum_of_terms([(2,2), (1,5)]), R.zero())
373
+ sage: hash(n) == hash(n2)
374
+ True
375
+ sage: hash(n) == hash(R.zero())
376
+ False
377
+ """
378
+ return hash(self.depth) ^ hash(self.weight)
379
+
380
+ def _richcmp_(self, rhs, op):
381
+ r"""
382
+ Check whether two nodes are equal.
383
+
384
+ TESTS::
385
+
386
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
387
+ sage: RS = RootSystem(['A', 2])
388
+ sage: WS = RS.weight_lattice()
389
+ sage: R = RS.root_lattice()
390
+ sage: KT = KleberTree(['A', 2, 1], [[1,1]])
391
+ sage: n = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero())
392
+ sage: n2 = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero(), n)
393
+ sage: n2 > n
394
+ True
395
+ sage: n3 = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero(), n)
396
+ sage: n2 == n3
397
+ True
398
+ sage: n3 = KT(WS.sum_of_terms([(1,5), (2,3)]), R.zero(), n)
399
+ sage: n2 < n3
400
+ True
401
+ """
402
+ lx = self.depth
403
+ rx = rhs.depth
404
+ if lx != rx:
405
+ return richcmp_not_equal(lx, rx, op)
406
+
407
+ lx = self.parent_node
408
+ rx = rhs.parent_node
409
+ if lx != rx:
410
+ return richcmp_not_equal(lx, rx, op)
411
+
412
+ return richcmp(self.weight, rhs.weight, op)
413
+
414
+ def _repr_(self):
415
+ r"""
416
+ Return the string representation of ``self``.
417
+
418
+ EXAMPLES::
419
+
420
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
421
+ sage: RS = RootSystem(['A', 3])
422
+ sage: WS = RS.weight_lattice()
423
+ sage: R = RS.root_lattice()
424
+ sage: KT = KleberTree(['A', 2, 1], [[1,1]])
425
+ sage: node = KT(WS.sum_of_terms([(1,2), (2,1), (3,1)]), R.sum_of_terms([(1,3), (3,3)])); node
426
+ Kleber tree node with weight [2, 1, 1] and upwards edge root [3, 0, 3]
427
+
428
+ With virtual nodes::
429
+
430
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
431
+ sage: KT = VirtualKleberTree(['A',6,2], [[2,2]])
432
+ sage: KT.root
433
+ Kleber tree node with weight [0, 2, 0, 2, 0] and upwards edge root [0, 0, 0, 0, 0]
434
+ """
435
+ return "Kleber tree node with weight %s and upwards edge root %s" % (
436
+ list(self.weight.to_vector()), list(self.up_root.to_vector()))
437
+
438
+ def _latex_(self):
439
+ r"""
440
+ Return latex representation of ``self``.
441
+
442
+ TESTS::
443
+
444
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
445
+ sage: RS = RootSystem(['A', 3])
446
+ sage: WS = RS.weight_lattice()
447
+ sage: R = RS.root_lattice()
448
+ sage: KT = KleberTree(['A', 3, 1], [[3,2], [1,1]])
449
+ sage: node = KT(WS.sum_of_terms([(1,4), (3,1)]), R.zero())
450
+ sage: latex(node)
451
+ V_{4\omega_{1}+\omega_{3}}
452
+ sage: node = KT(WS.zero(), R.zero())
453
+ sage: latex(node)
454
+ V_{0}
455
+ sage: node = KT(WS.sum_of_terms([(1,2)]), R.zero())
456
+ sage: latex(node)
457
+ V_{2\omega_{1}}
458
+
459
+ With virtual nodes::
460
+
461
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
462
+ sage: KT = VirtualKleberTree(['C',3,1], [[2,2]])
463
+ sage: latex(KT.root)
464
+ [V_{2\omega_{2}+2\omega_{4}}]
465
+ sage: KT = VirtualKleberTree(['A',6,2], [[2,2]])
466
+ sage: latex(KT.root)
467
+ [V_{2\omega_{2}+2\omega_{4}}]
468
+ """
469
+ ret_str = "V_{"
470
+ if self.multiplicity() != 1:
471
+ ret_str = repr(self.multiplicity()) + ret_str
472
+ for pair in self.weight:
473
+ if pair[1] > 1:
474
+ ret_str += repr(pair[1]) + r"\omega_{" + repr(pair[0]) + "}+"
475
+ elif pair[1] == 1:
476
+ ret_str += r"\omega_{" + repr(pair[0]) + "}+"
477
+
478
+ if ret_str[-1] == '{':
479
+ ret_str += "0}"
480
+ else:
481
+ ret_str = ret_str[:-1] + "}"
482
+
483
+ ct = self.parent()._cartan_type
484
+ if ct.type() == 'BC' or ct.dual().type() == 'BC':
485
+ return "[" + ret_str + "]"
486
+ elif not ct.is_simply_laced():
487
+ s_factors = self.parent()._folded_ct.scaling_factors()
488
+ gamma = max(s_factors)
489
+ # Subtract 1 for indexing
490
+ if gamma > 1:
491
+ L = [self.parent()._folded_ct.folding_orbit()[a][0] for a in
492
+ range(1, len(s_factors)) if s_factors[a] == gamma]
493
+ else:
494
+ L = []
495
+
496
+ if self.depth % gamma == 0 or all(self.up_root[a] == 0 for a in L):
497
+ return "[" + ret_str + "]"
498
+ return ret_str
499
+
500
+ #######################
501
+ # Kleber tree classes #
502
+ #######################
503
+
504
+
505
+ class KleberTree(UniqueRepresentation, Parent):
506
+ r"""
507
+ The tree that is generated by Kleber's algorithm.
508
+
509
+ A Kleber tree is a tree of weights generated by Kleber's algorithm
510
+ [Kleber1]_. It is used to generate the set of all admissible rigged
511
+ configurations for the simply-laced affine types `A_n^{(1)}`,
512
+ `D_n^{(1)}`, `E_6^{(1)}`, `E_7^{(1)}`, and `E_8^{(1)}`.
513
+
514
+ .. SEEALSO::
515
+
516
+ There is a modified version for non-simply-laced affine types at
517
+ :class:`VirtualKleberTree`.
518
+
519
+ The nodes correspond to the weights in the positive Weyl chamber obtained
520
+ by subtracting a (nonzero) positive root. The edges are labeled by the
521
+ coefficients of the roots, and `X` is a child of `Y` if `Y` is the root
522
+ else if the edge label of `Y` to its parent `Z` is greater (in every
523
+ component) than the label from `X` to `Y`.
524
+
525
+ For a Kleber tree, one needs to specify an affine (simply-laced)
526
+ Cartan type and a sequence of pairs `(r,s)`, where `s` is any positive
527
+ integer and `r` is a node in the Dynkin diagram. Each `(r,s)` can be
528
+ viewed as a rectangle of width `s` and height `r`.
529
+
530
+ INPUT:
531
+
532
+ - ``cartan_type`` -- an affine simply-laced Cartan type
533
+
534
+ - ``B`` -- list of dimensions of rectangles by `[r, c]`
535
+ where `r` is the number of rows and `c` is the number of columns
536
+
537
+ REFERENCES:
538
+
539
+ .. [Kleber1] Michael Kleber.
540
+ *Combinatorial structure of finite dimensional representations of
541
+ Yangians: the simply-laced case*.
542
+ Internat. Math. Res. Notices. (1997) no. 4. 187-201.
543
+
544
+ .. [Kleber2] Michael Kleber.
545
+ *Finite dimensional representations of quantum affine algebras*.
546
+ Ph.D. dissertation at University of California Berkeley. (1998).
547
+ :arxiv:`math.QA/9809087`.
548
+
549
+ EXAMPLES:
550
+
551
+ Simply-laced example::
552
+
553
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
554
+ sage: KT = KleberTree(['A', 3, 1], [[3,2], [1,1]])
555
+ sage: KT.list()
556
+ [Kleber tree node with weight [1, 0, 2] and upwards edge root [0, 0, 0],
557
+ Kleber tree node with weight [0, 0, 1] and upwards edge root [1, 1, 1]]
558
+ sage: KT = KleberTree(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]])
559
+ sage: KT.cardinality()
560
+ 10
561
+ sage: KT = KleberTree(['D', 4, 1], [[2,2]])
562
+ sage: KT.cardinality()
563
+ 3
564
+ sage: KT = KleberTree(['D', 4, 1], [[4,5]])
565
+ sage: KT.cardinality()
566
+ 1
567
+
568
+ From [Kleber2]_::
569
+
570
+ sage: KT = KleberTree(['E', 6, 1], [[4, 2]]) # long time (9s on sage.math, 2012)
571
+ sage: KT.cardinality() # long time
572
+ 12
573
+
574
+ We check that relabelled types work (:issue:`16876`)::
575
+
576
+ sage: ct = CartanType(['A',3,1]).relabel(lambda x: x+2)
577
+ sage: kt = KleberTree(ct, [[3,1],[5,1]])
578
+ sage: list(kt)
579
+ [Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 0, 0],
580
+ Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 1, 1]]
581
+ sage: kt = KleberTree(['A',3,1], [[1,1],[3,1]])
582
+ sage: list(kt)
583
+ [Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 0, 0],
584
+ Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 1, 1]]
585
+ """
586
+ @staticmethod
587
+ def __classcall_private__(cls, cartan_type, B, classical=None):
588
+ """
589
+ Normalize the input arguments to ensure unique representation.
590
+
591
+ EXAMPLES::
592
+
593
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
594
+ sage: KT1 = KleberTree(CartanType(['A',3,1]), [[2,2]])
595
+ sage: KT2 = KleberTree(['A',3,1], [(2,2)])
596
+ sage: KT3 = KleberTree(['A',3,1], ((2,2),))
597
+ sage: KT2 is KT1, KT3 is KT1
598
+ (True, True)
599
+ """
600
+ cartan_type = CartanType(cartan_type)
601
+ if not cartan_type.is_affine():
602
+ raise ValueError("The Cartan type must be affine")
603
+
604
+ if not cartan_type.classical().is_simply_laced():
605
+ raise ValueError("use VirtualKleberTree for non-simply-laced types")
606
+
607
+ # Standardize B input into a tuple of tuples
608
+ B = tuple([tuple(rs) for rs in B])
609
+
610
+ if classical is None:
611
+ classical = cartan_type.classical()
612
+ else:
613
+ classical = CartanType(classical)
614
+ return super().__classcall__(cls, cartan_type, B, classical)
615
+
616
+ def __init__(self, cartan_type, B, classical_ct):
617
+ r"""
618
+ Construct a Kleber tree.
619
+
620
+ The input ``classical_ct`` is the classical Cartan type to run the
621
+ algorithm on and is only meant to be used internally.
622
+
623
+ EXAMPLES::
624
+
625
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
626
+ sage: KT = KleberTree(['D', 3, 1], [[1,1], [1,1]]); KT
627
+ Kleber tree of Cartan type ['D', 3, 1] and B = ((1, 1), (1, 1))
628
+ sage: TestSuite(KT).run(skip='_test_elements')
629
+ """
630
+ Parent.__init__(self, category=FiniteEnumeratedSets())
631
+
632
+ self._cartan_type = cartan_type
633
+ self.B = B
634
+ self._classical_ct = classical_ct
635
+ # Our computations in _children_iter_vector use dense vectors.
636
+ # Moreover, ranks are relatively small, so just use the dense
637
+ # version of the Cartan matrix.
638
+ self._CM = self._classical_ct.cartan_matrix().dense_matrix()
639
+ self._build_tree()
640
+ self._latex_options = dict(edge_labels=True, use_vector_notation=False,
641
+ hspace=2.5,
642
+ vspace=min(-2.5, -0.75*self._classical_ct.rank()))
643
+
644
+ def latex_options(self, **options):
645
+ """
646
+ Return the current latex options if no arguments are passed, otherwise
647
+ set the corresponding latex option.
648
+
649
+ OPTIONS:
650
+
651
+ - ``hspace`` -- (default: `2.5`) the horizontal spacing of the
652
+ tree nodes
653
+ - ``vspace`` -- (default: ``x``) the vertical spacing of the tree
654
+ nodes, here ``x`` is the minimum of `-2.5` or `-.75n` where `n` is
655
+ the rank of the classical type
656
+ - ``edge_labels`` -- boolean (default: ``True``); display edge labels
657
+ - ``use_vector_notation`` -- boolean (default: ``False``); display edge labels
658
+ using vector notation instead of a linear combination
659
+
660
+ EXAMPLES::
661
+
662
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
663
+ sage: KT = KleberTree(['D', 3, 1], [[2,1], [2,1]])
664
+ sage: KT.latex_options(vspace=-4, use_vector_notation=True)
665
+ sage: sorted(KT.latex_options().items())
666
+ [('edge_labels', True), ('hspace', 2.5), ('use_vector_notation', True), ('vspace', -4)]
667
+ """
668
+ if not options:
669
+ from copy import copy
670
+ return copy(self._latex_options)
671
+ for key, value in options.items():
672
+ self._latex_options[key] = value
673
+
674
+ def _latex_(self):
675
+ r"""
676
+ Return a latex representation of this Kleber tree.
677
+
678
+ .. SEEALSO::
679
+
680
+ :meth:`latex_options()`
681
+
682
+ EXAMPLES::
683
+
684
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
685
+ sage: KT = KleberTree(['D', 3, 1], [[2,1], [2,1]])
686
+ sage: KT._latex_()
687
+ '\\begin{tikzpicture}...\\end{tikzpicture}'
688
+ """
689
+ from sage.graphs.graph_latex import setup_latex_preamble
690
+ setup_latex_preamble()
691
+
692
+ return "\\begin{tikzpicture}\n" + \
693
+ _draw_tree(self.root, **self._latex_options) \
694
+ + "\\end{tikzpicture}"
695
+
696
+ def _build_tree(self):
697
+ """
698
+ Build the Kleber tree.
699
+
700
+ TESTS:
701
+
702
+ This is called from the constructor::
703
+
704
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
705
+ sage: KT = KleberTree(['A',3,1], [[2,2]]) # indirect doctest
706
+ """
707
+ P = self._classical_ct.root_system().weight_lattice()
708
+ # Create an empty node at first step
709
+ self.root = KleberTreeNode(self, P.zero(),
710
+ self._classical_ct.root_system().root_lattice().zero())
711
+ full_list = [self.root] # The list of tree nodes
712
+
713
+ n = self._classical_ct.rank()
714
+
715
+ # Convert the B values into an L matrix
716
+ I = self._classical_ct.index_set()
717
+ L = [[0] for _ in range(n)]
718
+
719
+ for r, s in self.B:
720
+ while len(L[0]) < s: # Add more columns if needed
721
+ for row in L:
722
+ row.append(0)
723
+ L[I.index(r)][s - 1] += 1 # The -1 is for indexing
724
+
725
+ # Perform a special case of the algorithm for the root node
726
+ weight_basis = P.basis()
727
+ for a in range(n):
728
+ self.root.weight += sum(L[a]) * weight_basis[I[a]]
729
+ new_children = []
730
+ for new_child in self._children_iter(self.root):
731
+ if not self._prune(new_child, 1):
732
+ new_children.append(new_child)
733
+ self.root.children.append(new_child)
734
+ full_list.append(new_child)
735
+
736
+ depth = 1
737
+ growth = True
738
+
739
+ # self._has_normaliz is set by _children_iter
740
+ if self._classical_ct.rank() >= 7 or self._has_normaliz:
741
+ child_itr = self._children_iter
742
+ else:
743
+ child_itr = self._children_iter_vector
744
+
745
+ while growth:
746
+ growth = False
747
+ depth += 1
748
+ leaves = new_children
749
+
750
+ if depth <= len(L[0]):
751
+ new_children = []
752
+ for x in full_list:
753
+ growth = True
754
+ for a in range(n):
755
+ for i in range(depth - 1, len(L[a])): # Subtract 1 for indexing
756
+ x.weight += L[a][i] * weight_basis[I[a]]
757
+
758
+ new_children = [new_child
759
+ for x in leaves
760
+ for new_child in child_itr(x)
761
+ if not self._prune(new_child, depth)]
762
+
763
+ # Connect the new children into the tree
764
+ if new_children:
765
+ growth = True
766
+ for new_child in new_children:
767
+ new_child.parent_node.children.append(new_child)
768
+ full_list.append(new_child)
769
+
770
+ self._set = full_list
771
+
772
+ def _children_iter(self, node):
773
+ r"""
774
+ Iterate over the children of ``node``.
775
+
776
+ Helper iterator to iterate over all children, by generating and/or
777
+ computing them, of the Kleber tree node.
778
+
779
+ We compute the children by computing integral points (expressed as
780
+ simple roots) in the polytope given by the intersection of the
781
+ negative root cone and shifted positive weight cone. More precisely,
782
+ we rewrite the condition `\lambda - \mu \in Q^+`, for `\mu \in P^+`,
783
+ as `\lambda - Q^+ = \mu \in P^+`.
784
+
785
+ INPUT:
786
+
787
+ - ``node`` -- the current node in the tree whose children we want
788
+ to generate
789
+
790
+ TESTS::
791
+
792
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
793
+ sage: KT = KleberTree(['D', 3, 1], [[1,1], [1,1]])
794
+ sage: for x in KT: x # indirect doctest
795
+ Kleber tree node with weight [2, 0, 0] and upwards edge root [0, 0, 0]
796
+ Kleber tree node with weight [0, 1, 1] and upwards edge root [1, 0, 0]
797
+ Kleber tree node with weight [0, 0, 0] and upwards edge root [2, 1, 1]
798
+
799
+ sage: KT = KleberTree(['D', 4, 1], [[2,2]])
800
+ sage: KT[1]
801
+ Kleber tree node with weight [0, 1, 0, 0] and upwards edge root [1, 2, 1, 1]
802
+ sage: for x in KT: x
803
+ Kleber tree node with weight [0, 2, 0, 0] and upwards edge root [0, 0, 0, 0]
804
+ Kleber tree node with weight [0, 1, 0, 0] and upwards edge root [1, 2, 1, 1]
805
+ Kleber tree node with weight [0, 0, 0, 0] and upwards edge root [1, 2, 1, 1]
806
+ sage: for x in KT._children_iter(KT[1]): x
807
+ Kleber tree node with weight [0, 0, 0, 0] and upwards edge root [1, 2, 1, 1]
808
+ """
809
+ # It is faster to just cycle through than build the polytope and its
810
+ # lattice points when we are sufficiently small
811
+ # The number 500 comes from testing on my machine about where the
812
+ # tradeoff occurs between the methods. However, this may grow as
813
+ # the _children_iter_vector is further optimized.
814
+ if node != self.root and prod(val+1 for val in node.up_root.coefficients()) < 1000:
815
+ yield from self._children_iter_vector(node)
816
+ return
817
+
818
+ n = self._classical_ct.rank()
819
+ I = self._classical_ct.index_set()
820
+ Q = self._classical_ct.root_system().root_lattice()
821
+ P = self._classical_ct.root_system().weight_lattice()
822
+
823
+ # Construct the polytope by inequalities
824
+ from sage.geometry.polyhedron.constructor import Polyhedron
825
+ # Construct the shifted weight cone
826
+ root_weight = node.weight.to_vector()
827
+ ieqs = [[root_weight[i]] + list(col)
828
+ for i, col in enumerate(self._CM.columns())]
829
+ # Construct the negative weight cone
830
+ for i in range(n):
831
+ v = [0] * (n+1)
832
+ v[i+1] = -1
833
+ ieqs.append(v)
834
+ ieqs.append([-1]*(n+1)) # For avoiding the origin
835
+ # Construct the bounds for the non-root nodes
836
+ if node != self.root:
837
+ for i, c in enumerate(node.up_root.to_vector()):
838
+ v = [0] * (n+1)
839
+ v[0] = c
840
+ v[i+1] = 1
841
+ ieqs.append(v)
842
+
843
+ try:
844
+ poly = Polyhedron(ieqs=ieqs, backend='normaliz')
845
+ self._has_normaliz = True
846
+ except FeatureNotPresentError:
847
+ poly = Polyhedron(ieqs=ieqs)
848
+ self._has_normaliz = False
849
+
850
+ # Build the nodes from the polytope
851
+ # Sort for a consistent ordering (it is typically a small list)
852
+ for pt in sorted(poly.integral_points(), reverse=True):
853
+ up_root = Q._from_dict({I[i]: -val for i, val in enumerate(pt) if val != 0},
854
+ remove_zeros=False)
855
+ wt = node.weight + sum(val * P.simple_root(I[i]) for i, val in enumerate(pt))
856
+ yield KleberTreeNode(self, wt, up_root, node)
857
+
858
+ def _children_iter_vector(self, node):
859
+ r"""
860
+ Iterate over the children of ``node``.
861
+
862
+ Helper iterator to iterate over all children, by generating and/or
863
+ computing them, of the Kleber tree node. This implementation
864
+ iterates over all possible uproot vectors.
865
+
866
+ .. SEEALSO::
867
+
868
+ :meth:`_children_iter`
869
+
870
+ INPUT:
871
+
872
+ - ``node`` -- the current node in the tree whose children we want
873
+ to generate
874
+
875
+ TESTS::
876
+
877
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
878
+ sage: KT = KleberTree(['D', 4, 1], [[2,2]])
879
+ sage: KT[1]
880
+ Kleber tree node with weight [0, 1, 0, 0] and upwards edge root [1, 2, 1, 1]
881
+ sage: for x in KT._children_iter(KT[1]): x
882
+ Kleber tree node with weight [0, 0, 0, 0] and upwards edge root [1, 2, 1, 1]
883
+ """
884
+ Q = self._classical_ct.root_system().root_lattice()
885
+ P = self._classical_ct.root_system().weight_lattice()
886
+ I = self._classical_ct.index_set()
887
+ wt = node.weight.to_vector()
888
+ cols = self._CM.columns()
889
+
890
+ L = [range(val + 1) for val in node.up_root.to_vector()]
891
+
892
+ it = itertools.product(*L)
893
+ next(it) # First element is the zero element
894
+ for root in it:
895
+ # Convert the list to the weight lattice
896
+ converted_root = sum(cols[i] * c for i, c in enumerate(root)
897
+ if c != 0)
898
+
899
+ if all(wt[i] >= val for i, val in enumerate(converted_root)):
900
+ wd = {I[i]: wt[i] - val for i, val in enumerate(converted_root)}
901
+ rd = {I[i]: val for i, val in enumerate(root) if val != 0}
902
+ yield KleberTreeNode(self,
903
+ P._from_dict(wd),
904
+ Q._from_dict(rd, remove_zeros=False),
905
+ node)
906
+
907
+ def _prune(self, new_child, depth):
908
+ r"""
909
+ Return ``True`` if we are to prune the tree at ``new_child``.
910
+
911
+ This always returns ``False`` since we do not do any pruning.
912
+
913
+ EXAMPLES::
914
+
915
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
916
+ sage: KT = KleberTree(['A', 2, 1], [[1,1]])
917
+ sage: KT._prune(KT.root, 0)
918
+ False
919
+ """
920
+ return False
921
+
922
+ def breadth_first_iter(self):
923
+ r"""
924
+ Iterate over all nodes in the tree following a breadth-first traversal.
925
+
926
+ EXAMPLES::
927
+
928
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
929
+ sage: KT = KleberTree(['A', 3, 1], [[2, 2], [2, 3]])
930
+ sage: for x in KT.breadth_first_iter(): x
931
+ Kleber tree node with weight [0, 5, 0] and upwards edge root [0, 0, 0]
932
+ Kleber tree node with weight [1, 3, 1] and upwards edge root [0, 1, 0]
933
+ Kleber tree node with weight [0, 3, 0] and upwards edge root [1, 2, 1]
934
+ Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 1, 0]
935
+ Kleber tree node with weight [1, 1, 1] and upwards edge root [0, 1, 0]
936
+ Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 2, 1]
937
+ """
938
+ cur = []
939
+ next = [self.root]
940
+ while next:
941
+ cur = next
942
+ next = []
943
+ for node in cur:
944
+ yield node
945
+ next.extend(node.children)
946
+
947
+ def depth_first_iter(self):
948
+ r"""
949
+ Iterate (recursively) over the nodes in the tree following a
950
+ depth-first traversal.
951
+
952
+ EXAMPLES::
953
+
954
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
955
+ sage: KT = KleberTree(['A', 3, 1], [[2, 2], [2, 3]])
956
+ sage: for x in KT.depth_first_iter(): x
957
+ Kleber tree node with weight [0, 5, 0] and upwards edge root [0, 0, 0]
958
+ Kleber tree node with weight [1, 3, 1] and upwards edge root [0, 1, 0]
959
+ Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 1, 0]
960
+ Kleber tree node with weight [0, 3, 0] and upwards edge root [1, 2, 1]
961
+ Kleber tree node with weight [1, 1, 1] and upwards edge root [0, 1, 0]
962
+ Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 2, 1]
963
+ """
964
+ return self._depth_first_iter(None)
965
+
966
+ def _depth_first_iter(self, cur):
967
+ r"""
968
+ Helper recursive function used in depth-first iteration.
969
+
970
+ EXAMPLES::
971
+
972
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
973
+ sage: KT = KleberTree(['A', 3, 1], [[2, 2], [2, 3]])
974
+ sage: for x in KT._depth_first_iter(None): x
975
+ Kleber tree node with weight [0, 5, 0] and upwards edge root [0, 0, 0]
976
+ Kleber tree node with weight [1, 3, 1] and upwards edge root [0, 1, 0]
977
+ Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 1, 0]
978
+ Kleber tree node with weight [0, 3, 0] and upwards edge root [1, 2, 1]
979
+ Kleber tree node with weight [1, 1, 1] and upwards edge root [0, 1, 0]
980
+ Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 2, 1]
981
+ """
982
+ if cur is None:
983
+ cur = self.root
984
+
985
+ yield cur
986
+
987
+ for child in cur.children:
988
+ yield from self._depth_first_iter(child)
989
+
990
+ __iter__ = breadth_first_iter
991
+
992
+ def _repr_(self):
993
+ """
994
+ Return a text representation of this Kleber tree.
995
+
996
+ EXAMPLES::
997
+
998
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
999
+ sage: KleberTree(['D', 4, 1], [[2, 2]]) # indirect doctest
1000
+ Kleber tree of Cartan type ['D', 4, 1] and B = ((2, 2),)
1001
+ """
1002
+ return "Kleber tree of Cartan type %s and B = %s" % (repr(self._cartan_type), self.B)
1003
+
1004
+ def cartan_type(self):
1005
+ r"""
1006
+ Return the Cartan type of this Kleber tree.
1007
+
1008
+ EXAMPLES::
1009
+
1010
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
1011
+ sage: KT = KleberTree(['A', 3, 1], [[1,1]])
1012
+ sage: KT.cartan_type()
1013
+ ['A', 3, 1]
1014
+ """
1015
+ return self._cartan_type
1016
+
1017
+ def digraph(self):
1018
+ r"""
1019
+ Return a DiGraph representation of this Kleber tree.
1020
+
1021
+ EXAMPLES::
1022
+
1023
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
1024
+ sage: KT = KleberTree(['D', 4, 1], [[2, 2]])
1025
+ sage: KT.digraph()
1026
+ Digraph on 3 vertices
1027
+ """
1028
+ d = {}
1029
+ for x in self.breadth_first_iter():
1030
+ d[x] = {}
1031
+ if x.parent_node is None:
1032
+ continue
1033
+ d[x][x.parent_node] = tuple(x.up_root.to_vector())
1034
+ G = DiGraph(d)
1035
+
1036
+ if have_dot2tex():
1037
+ G.set_latex_options(format='dot2tex', edge_labels=True)
1038
+ return G
1039
+
1040
+ def plot(self, **options):
1041
+ """
1042
+ Return the plot of ``self`` as a directed graph.
1043
+
1044
+ EXAMPLES::
1045
+
1046
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
1047
+ sage: KT = KleberTree(['D', 4, 1], [[2, 2]])
1048
+ sage: print(KT.plot()) # needs sage.plot
1049
+ Graphics object consisting of 8 graphics primitives
1050
+ """
1051
+ return self.digraph().plot(edge_labels=True, vertex_size=0, **options)
1052
+
1053
+ def _element_constructor_(self, node_weight, dominant_root, parent_node=None):
1054
+ """
1055
+ Construct a Kleber tree node.
1056
+
1057
+ EXAMPLES::
1058
+
1059
+ sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree
1060
+ sage: RS = RootSystem(['A', 2])
1061
+ sage: WS = RS.weight_lattice()
1062
+ sage: R = RS.root_lattice()
1063
+ sage: KT = KleberTree(['A', 2, 1], [[1,1]])
1064
+ sage: root = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero()); root # indirect doctest
1065
+ Kleber tree node with weight [5, 2] and upwards edge root [0, 0]
1066
+ sage: child = KT(WS.sum_of_terms([(1,5), (2,1)]), R.zero(), root); child # indirect doctest
1067
+ Kleber tree node with weight [5, 1] and upwards edge root [0, 0]
1068
+ sage: child.parent_node
1069
+ Kleber tree node with weight [5, 2] and upwards edge root [0, 0]
1070
+ """
1071
+ return self.element_class(self, node_weight, dominant_root, parent_node)
1072
+
1073
+ Element = KleberTreeNode
1074
+
1075
+
1076
+ class VirtualKleberTree(KleberTree):
1077
+ r"""
1078
+ A virtual Kleber tree.
1079
+
1080
+ We can use a modified version of the Kleber algorithm called the virtual
1081
+ Kleber algorithm [OSS03]_ to compute all admissible rigged configurations
1082
+ for non-simply-laced types. This uses the following embeddings
1083
+ into the simply-laced types:
1084
+
1085
+ .. MATH::
1086
+
1087
+ C_n^{(1)}, A_{2n}^{(2)}, A_{2n}^{(2)\dagger}, D_{n+1}^{(2)}
1088
+ \hookrightarrow A_{2n-1}^{(1)}
1089
+
1090
+ A_{2n-1}^{(2)}, B_n^{(1)} \hookrightarrow D_{n+1}^{(1)}
1091
+
1092
+ E_6^{(2)}, F_4^{(1)} \hookrightarrow E_6^{(1)}
1093
+
1094
+ D_4^{(3)}, G_2^{(1)} \hookrightarrow D_4^{(1)}
1095
+
1096
+ One then selects the subset of admissible nodes which are translates of
1097
+ the virtual requirements. In the graph, the selected nodes are indicated
1098
+ by brackets `[]`.
1099
+
1100
+ .. NOTE::
1101
+
1102
+ Because these are virtual nodes, all information is given
1103
+ in the corresponding simply-laced type.
1104
+
1105
+ .. SEEALSO::
1106
+
1107
+ For more on the Kleber algorithm, see :class:`KleberTree`.
1108
+
1109
+ REFERENCES:
1110
+
1111
+ .. [OSS03] Masato Okado, Anne Schilling, and Mark Shimozono.
1112
+ *Virtual crystals and Klebers algorithm*. Commun. Math. Phys. **238**
1113
+ (2003). 187-209. :arxiv:`math.QA/0209082`.
1114
+
1115
+ INPUT:
1116
+
1117
+ - ``cartan_type`` -- an affine non-simply-laced Cartan type
1118
+
1119
+ - ``B`` -- list of dimensions of rectangles by `[r, c]`
1120
+ where `r` is the number of rows and `c` is the number of columns
1121
+
1122
+ EXAMPLES::
1123
+
1124
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1125
+ sage: KT = VirtualKleberTree(['C', 4, 1], [[2,2]])
1126
+ sage: KT.cardinality()
1127
+ 3
1128
+ sage: KT.base_tree().cardinality()
1129
+ 6
1130
+ sage: KT = VirtualKleberTree(['C', 4, 1], [[4,5]])
1131
+ sage: KT.cardinality()
1132
+ 1
1133
+ sage: KT = VirtualKleberTree(['D', 5, 2], [[2,1], [1,1]])
1134
+ sage: KT.cardinality()
1135
+ 8
1136
+ sage: KT = VirtualKleberTree(CartanType(['A', 4, 2]).dual(), [[1,1], [2,2]])
1137
+ sage: KT.cardinality()
1138
+ 15
1139
+ """
1140
+ @staticmethod
1141
+ def __classcall_private__(cls, cartan_type, B):
1142
+ """
1143
+ Normalize the input arguments to ensure unique representation.
1144
+
1145
+ EXAMPLES::
1146
+
1147
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1148
+ sage: KT1 = VirtualKleberTree(CartanType(['C',3,1]).as_folding(), [[2,2]])
1149
+ sage: KT2 = VirtualKleberTree(CartanType(['C',3,1]), [(2,2)])
1150
+ sage: KT3 = VirtualKleberTree(['C',3,1], ((2,2),))
1151
+ sage: KT2 is KT1, KT3 is KT1
1152
+ (True, True)
1153
+ """
1154
+ cartan_type = CartanType(cartan_type)
1155
+ # Standardize B input into a tuple of tuples
1156
+ B = tuple(map(tuple, B))
1157
+ if cartan_type.type() == 'BC' or cartan_type.dual().type() == 'BC':
1158
+ # Types A_{2n}^{(2)} and its dual
1159
+ return KleberTreeTypeA2Even(cartan_type, B)
1160
+ if cartan_type.classical().is_simply_laced():
1161
+ raise ValueError("use KleberTree for simply-laced types")
1162
+ return super().__classcall__(cls, cartan_type, B)
1163
+
1164
+ def __init__(self, cartan_type, B):
1165
+ """
1166
+ Initialize ``self``.
1167
+
1168
+ EXAMPLES::
1169
+
1170
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1171
+ sage: KT = VirtualKleberTree(['C',4,1], [[2,2]])
1172
+ sage: TestSuite(KT).run(skip='_test_elements')
1173
+ """
1174
+ self._folded_ct = cartan_type.as_folding()
1175
+ self.base_dims = B
1176
+ sigma = self._folded_ct.folding_orbit()
1177
+ gamma = self._folded_ct.scaling_factors()
1178
+ classical_ct = self._folded_ct.folding_of().classical()
1179
+ virtual_dims = [[i, s * gamma[r]]
1180
+ for r, s in B for i in sigma[r]]
1181
+
1182
+ KleberTree.__init__(self, cartan_type, virtual_dims, classical_ct)
1183
+
1184
+ def _repr_(self):
1185
+ """
1186
+ Return a text representation of this Kleber tree.
1187
+
1188
+ EXAMPLES::
1189
+
1190
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1191
+ sage: VirtualKleberTree(['C', 4, 1], [[2, 2]])
1192
+ Virtual Kleber tree of Cartan type ['C', 4, 1] and B = ((2, 2),)
1193
+ """
1194
+ return "Virtual Kleber tree of Cartan type %s and B = %s" % (repr(self._cartan_type), self.base_dims)
1195
+
1196
+ def _prune(self, new_child, depth):
1197
+ r"""
1198
+ Return ``True`` if we are to prune the tree at ``new_child``.
1199
+
1200
+ Suppose `\lambda` is the weight of the child we want to add at depth
1201
+ `\ell`. We prune ``new_child`` if either of the following conditions
1202
+ are not satisfied:
1203
+
1204
+ 1. `(\lambda \mid \alpha_a) = (\lambda \mid \alpha_b)` if `a` and `b`
1205
+ are in the same `\sigma`-orbit.
1206
+ 2. If `\ell - 1 \notin \gamma_a \ZZ`, then the `a`-th component of
1207
+ ``up_root`` of ``new_child`` must equal the `a`-th component of
1208
+ ``up_root`` of its ``parent_node``. Note that from condition 1,
1209
+ we only need to check one such `a` from each `\sigma`-orbit.
1210
+
1211
+ These conditions are equivalent to Definition 4.1 in [OSS03]_.
1212
+
1213
+ EXAMPLES::
1214
+
1215
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1216
+ sage: RS = RootSystem(['A', 3])
1217
+ sage: WS = RS.weight_lattice()
1218
+ sage: R = RS.root_lattice()
1219
+ sage: KT = VirtualKleberTree(['C',2,1], [[1,2],[1,1],[2,1]])
1220
+ sage: x = KT(WS.sum_of_terms([(1,1), (2,1), (3,3)]), R.sum_of_terms([(1,2),(2,2),(3,1)]), KT.root)
1221
+ sage: KT._prune(x, 1)
1222
+ True
1223
+ """
1224
+ sigma = self._folded_ct._orbit
1225
+ for orbit in sigma[1:]:
1226
+ start = new_child.weight[orbit[0]]
1227
+ if any(new_child.weight[i] != start for i in orbit[1:]):
1228
+ return True
1229
+ gamma = self._folded_ct.scaling_factors()
1230
+ for a in range(1, len(gamma)):
1231
+ s = sigma[a][0]
1232
+ if ((depth - 1) % gamma[a] != 0 and
1233
+ new_child.up_root[s] != new_child.parent_node.up_root[s]):
1234
+ return True
1235
+ return False
1236
+
1237
+ def breadth_first_iter(self, all_nodes=False):
1238
+ r"""
1239
+ Iterate over all nodes in the tree following a breadth-first traversal.
1240
+
1241
+ INPUT:
1242
+
1243
+ - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all
1244
+ nodes in the tree
1245
+
1246
+ EXAMPLES::
1247
+
1248
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1249
+ sage: KT = VirtualKleberTree(['C', 2, 1], [[1,1], [2,1]])
1250
+ sage: for x in KT.breadth_first_iter(): x
1251
+ Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0]
1252
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1253
+ sage: for x in KT.breadth_first_iter(True): x
1254
+ Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0]
1255
+ Kleber tree node with weight [0, 2, 0] and upwards edge root [1, 1, 1]
1256
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1257
+ """
1258
+ s_factors = self._folded_ct.scaling_factors()
1259
+ gamma = max(s_factors)
1260
+ # Subtract 1 for indexing
1261
+ if gamma > 1:
1262
+ sigma = self._folded_ct.folding_orbit()
1263
+ L = [sigma[a][0] for a in range(1, len(s_factors))
1264
+ if s_factors[a] == gamma]
1265
+ else:
1266
+ L = []
1267
+
1268
+ for x in KleberTree.breadth_first_iter(self):
1269
+ if all_nodes or (x.depth) % gamma == 0 or all(x.up_root[a] == 0 for a in L):
1270
+ yield x
1271
+
1272
+ def depth_first_iter(self, all_nodes=False):
1273
+ r"""
1274
+ Iterate (recursively) over the nodes in the tree following a
1275
+ depth-first traversal.
1276
+
1277
+ INPUT:
1278
+
1279
+ - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all
1280
+ nodes in the tree
1281
+
1282
+ EXAMPLES::
1283
+
1284
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1285
+ sage: KT = VirtualKleberTree(['C', 2, 1], [[1,1], [2,1]])
1286
+ sage: for x in KT.depth_first_iter(): x
1287
+ Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0]
1288
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1289
+ sage: for x in KT.depth_first_iter(True): x
1290
+ Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0]
1291
+ Kleber tree node with weight [0, 2, 0] and upwards edge root [1, 1, 1]
1292
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1293
+ """
1294
+ s_factors = self._folded_ct.scaling_factors()
1295
+ gamma = max(s_factors)
1296
+ # Subtract 1 for indexing
1297
+ if gamma > 1:
1298
+ sigma = self._folded_ct.folding_orbit()
1299
+ L = [sigma[a][0] for a in range(1, len(s_factors))
1300
+ if s_factors[a] == gamma]
1301
+ else:
1302
+ L = []
1303
+
1304
+ for x in self._depth_first_iter(None):
1305
+ if all_nodes or (x.depth) % gamma == 0 or all(x.up_root[a] == 0 for a in L):
1306
+ yield x
1307
+
1308
+ __iter__ = breadth_first_iter
1309
+
1310
+ def base_tree(self):
1311
+ """
1312
+ Return the underlying virtual Kleber tree associated to ``self``.
1313
+
1314
+ EXAMPLES::
1315
+
1316
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1317
+ sage: KT = VirtualKleberTree(['C', 4, 1], [[2,2]])
1318
+ sage: KT.base_tree()
1319
+ Kleber tree of Cartan type ['A', 7, 1] and B = ((2, 2), (6, 2))
1320
+ """
1321
+ return KleberTree(self._folded_ct.folding_of(), self.B)
1322
+
1323
+
1324
+ class KleberTreeTypeA2Even(VirtualKleberTree):
1325
+ r"""
1326
+ Kleber tree for types `A_{2n}^{(2)}` and `A_{2n}^{(2)\dagger}`.
1327
+
1328
+ Note that here for `A_{2n}^{(2)}` we use `\tilde{\gamma}_a` in place of
1329
+ `\gamma_a` in constructing the virtual Kleber tree, and so we end up
1330
+ selecting all nodes since `\tilde{\gamma}_a = 1` for all `a \in
1331
+ \overline{I}`. For type `A_{2n}^{(2)\dagger}`, we have `\gamma_a = 1`
1332
+ for all `a \in \overline{I}`.
1333
+
1334
+ .. SEEALSO::
1335
+
1336
+ :class:`VirtualKleberTree`
1337
+ """
1338
+ @staticmethod
1339
+ def __classcall_private__(cls, cartan_type, B):
1340
+ """
1341
+ Normalize the input arguments to ensure unique representation.
1342
+
1343
+ EXAMPLES::
1344
+
1345
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1346
+ sage: KT1 = VirtualKleberTree(CartanType(['A',6,2]), [[2,2]])
1347
+ sage: KT2 = VirtualKleberTree(['A',6,2], [(2,2)])
1348
+ sage: KT3 = VirtualKleberTree(['A',6,2], ((2,2),))
1349
+ sage: KT2 is KT1, KT3 is KT1
1350
+ (True, True)
1351
+ """
1352
+ cartan_type = CartanType(cartan_type)
1353
+ # Standardize B input into a tuple of tuples
1354
+ B = tuple(map(tuple, B))
1355
+ return super().__classcall__(cls, cartan_type, B)
1356
+
1357
+ def __init__(self, cartan_type, B):
1358
+ """
1359
+ Initialize ``self``.
1360
+
1361
+ EXAMPLES::
1362
+
1363
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1364
+ sage: KT = VirtualKleberTree(['A',6,2], [[2,2]]); KT
1365
+ Virtual Kleber tree of Cartan type ['BC', 3, 2] and B = ((2, 2),)
1366
+ sage: TestSuite(KT).run(skip='_test_elements')
1367
+ """
1368
+ self._folded_ct = cartan_type.as_folding()
1369
+ virtual_dims = []
1370
+ n = cartan_type.classical().rank()
1371
+ self.base_dims = B
1372
+ sigma = self._folded_ct.folding_orbit()
1373
+ classical_ct = self._folded_ct.folding_of().classical()
1374
+ for r, s in B:
1375
+ if r == n:
1376
+ virtual_dims.extend([[n, s], [n, s]])
1377
+ else:
1378
+ virtual_dims.extend([i, s] for i in sigma[r])
1379
+
1380
+ KleberTree.__init__(self, cartan_type, virtual_dims, classical_ct)
1381
+
1382
+ def __iter__(self):
1383
+ """
1384
+ Iterate over all of the nodes.
1385
+
1386
+ EXAMPLES::
1387
+
1388
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1389
+ sage: KT = VirtualKleberTree(['A',6,2], [[2,2]])
1390
+ sage: L = [x for x in KT]
1391
+ sage: len(L) == KT.cardinality()
1392
+ True
1393
+ """
1394
+ return KleberTree.__iter__(self)
1395
+
1396
+ def _prune(self, new_child, depth):
1397
+ r"""
1398
+ Return ``True`` if we are to prune the tree at ``new_child``.
1399
+
1400
+ Suppose `\lambda` is the weight of the child we want to add at
1401
+ depth `\ell`. We prune ``new_child`` if `(\lambda \mid \alpha_a)
1402
+ \neq (\lambda \mid \alpha_b)` if `a` and `b` are in the same
1403
+ `\sigma`-orbit.
1404
+
1405
+ These conditions are equivalent to Definition 4.1 in [OSS03]_ by using
1406
+ `\tilde{\gamma}`, and since `\tilde{\gamma}_a = 1` for all `a`, the
1407
+ second condition becomes vacuous.
1408
+
1409
+ EXAMPLES::
1410
+
1411
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1412
+ sage: RS = RootSystem(['A', 5])
1413
+ sage: WS = RS.weight_lattice()
1414
+ sage: R = RS.root_lattice()
1415
+ sage: KT = VirtualKleberTree(['A',6,2], [[2,2]])
1416
+ sage: x = KT(WS.sum_of_terms([(2,1), (4,1)]), R.sum_of_terms([(1,1),(2,2),(3,2),(4,2),(5,1)]), KT.root)
1417
+ sage: KT._prune(x, 1)
1418
+ False
1419
+ """
1420
+ sigma = self._folded_ct._orbit
1421
+ for orbit in sigma[1:]:
1422
+ start = new_child.weight[orbit[0]]
1423
+ for i in orbit[1:]:
1424
+ if new_child.weight[i] != start:
1425
+ return True
1426
+ return False
1427
+
1428
+ def breadth_first_iter(self, all_nodes=False):
1429
+ r"""
1430
+ Iterate over all nodes in the tree following a breadth-first traversal.
1431
+
1432
+ INPUT:
1433
+
1434
+ - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all
1435
+ nodes in the tree
1436
+
1437
+ EXAMPLES::
1438
+
1439
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1440
+ sage: KT = VirtualKleberTree(['A', 4, 2], [[2,1]])
1441
+ sage: for x in KT.breadth_first_iter(): x
1442
+ Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0]
1443
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1444
+ Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1]
1445
+ sage: for x in KT.breadth_first_iter(True): x
1446
+ Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0]
1447
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1448
+ Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1]
1449
+ """
1450
+ return KleberTree.breadth_first_iter(self)
1451
+
1452
+ def depth_first_iter(self, all_nodes=False):
1453
+ r"""
1454
+ Iterate (recursively) over the nodes in the tree following a
1455
+ depth-first traversal.
1456
+
1457
+ INPUT:
1458
+
1459
+ - ``all_nodes`` -- boolean (default: ``False``); if ``True``, output all
1460
+ nodes in the tree
1461
+
1462
+ EXAMPLES::
1463
+
1464
+ sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree
1465
+ sage: KT = VirtualKleberTree(['A', 4, 2], [[2,1]])
1466
+ sage: for x in KT.depth_first_iter(): x
1467
+ Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0]
1468
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1469
+ Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1]
1470
+ sage: for x in KT.depth_first_iter(True): x
1471
+ Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0]
1472
+ Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0]
1473
+ Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1]
1474
+ """
1475
+ return KleberTree.depth_first_iter(self)