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,1518 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.graphs sage.modules
3
+ r"""
4
+ Littelmann paths
5
+
6
+ AUTHORS:
7
+
8
+ - Mark Shimozono, Anne Schilling (2012): Initial version
9
+ - Anne Schilling (2013): Implemented
10
+ :class:`~sage.combinat.crystals.littelmann_path.CrystalOfProjectedLevelZeroLSPaths`
11
+ - Travis Scrimshaw (2016): Implemented
12
+ :class:`~sage.combinat.crystals.littelmann_path.InfinityCrystalOfLSPaths`
13
+ """
14
+ # ***************************************************************************
15
+ # Copyright (C) 2012 Mark Shimozono
16
+ # Anne Schilling
17
+ # 2016 Travis Scrimshaw <tcscrims at gmail.com>
18
+ #
19
+ # Distributed under the terms of the GNU General Public License (GPL)
20
+ #
21
+ # This code is distributed in the hope that it will be useful,
22
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24
+ # General Public License for more details.
25
+ #
26
+ # The full text of the GPL is available at:
27
+ #
28
+ # https://www.gnu.org/licenses/
29
+ # ***************************************************************************
30
+
31
+ from sage.misc.cachefunc import cached_in_parent_method, cached_method
32
+ from sage.misc.lazy_import import lazy_import
33
+ from sage.structure.unique_representation import UniqueRepresentation
34
+ from sage.structure.element_wrapper import ElementWrapper
35
+ from sage.structure.parent import Parent
36
+ from sage.categories.highest_weight_crystals import HighestWeightCrystals
37
+ from sage.categories.regular_crystals import RegularCrystals
38
+ from sage.categories.classical_crystals import ClassicalCrystals
39
+ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
40
+ from sage.categories.loop_crystals import (RegularLoopCrystals,
41
+ KirillovReshetikhinCrystals)
42
+ from sage.combinat.root_system.cartan_type import CartanType
43
+ from sage.rings.integer import Integer
44
+ from sage.rings.rational_field import QQ
45
+ from sage.combinat.root_system.root_system import RootSystem
46
+ from sage.arith.misc import integer_floor as floor
47
+ from sage.misc.latex import latex
48
+
49
+ lazy_import('sage.combinat.root_system.weyl_group', 'WeylGroup')
50
+
51
+
52
+ class CrystalOfLSPaths(UniqueRepresentation, Parent):
53
+ r"""
54
+ Crystal graph of LS paths generated from the straight-line path
55
+ to a given weight.
56
+
57
+ INPUT:
58
+
59
+ - ``cartan_type`` -- (optional) the Cartan type
60
+ - ``starting_weight`` -- a weight; if ``cartan_type`` is given,
61
+ then the weight should be given as a list of coefficients of
62
+ the fundamental weights, otherwise it should be given in the
63
+ ``weight_space`` basis; for affine highest weight crystals,
64
+ one needs to use the extended weight space
65
+
66
+ The crystal class of piecewise linear paths in the weight space,
67
+ generated from a straight-line path from the origin to a given
68
+ element of the weight lattice.
69
+
70
+ EXAMPLES::
71
+
72
+ sage: R = RootSystem(['A',2,1])
73
+ sage: La = R.weight_space(extended = True).basis()
74
+ sage: B = crystals.LSPaths(La[2]-La[0]); B
75
+ The crystal of LS paths of type ['A', 2, 1] and weight -Lambda[0] + Lambda[2]
76
+
77
+ sage: C = crystals.LSPaths(['A',2,1],[-1,0,1]); C
78
+ The crystal of LS paths of type ['A', 2, 1] and weight -Lambda[0] + Lambda[2]
79
+ sage: B == C
80
+ True
81
+ sage: c = C.module_generators[0]; c
82
+ (-Lambda[0] + Lambda[2],)
83
+ sage: [c.f(i) for i in C.index_set()]
84
+ [None, None, (Lambda[1] - Lambda[2],)]
85
+
86
+ sage: R = C.R; R
87
+ Root system of type ['A', 2, 1]
88
+ sage: Lambda = R.weight_space().basis(); Lambda
89
+ Finite family {0: Lambda[0], 1: Lambda[1], 2: Lambda[2]}
90
+ sage: b=C(tuple([-Lambda[0]+Lambda[2]]))
91
+ sage: b==c
92
+ True
93
+ sage: b.f(2)
94
+ (Lambda[1] - Lambda[2],)
95
+
96
+ For classical highest weight crystals, we can also compare the results
97
+ with the tableaux implementation::
98
+
99
+ sage: C = crystals.LSPaths(['A',2],[1,1])
100
+ sage: sorted(C, key=str)
101
+ [(-2*Lambda[1] + Lambda[2],), (-Lambda[1] + 1/2*Lambda[2], Lambda[1] - 1/2*Lambda[2]),
102
+ (-Lambda[1] + 2*Lambda[2],), (-Lambda[1] - Lambda[2],),
103
+ (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2]), (2*Lambda[1] - Lambda[2],),
104
+ (Lambda[1] + Lambda[2],), (Lambda[1] - 2*Lambda[2],)]
105
+ sage: C.cardinality()
106
+ 8
107
+ sage: B = crystals.Tableaux(['A',2],shape=[2,1])
108
+ sage: B.cardinality()
109
+ 8
110
+ sage: B.digraph().is_isomorphic(C.digraph())
111
+ True
112
+
113
+ Make sure you use the weight space and not the weight lattice
114
+ for your weights::
115
+
116
+ sage: R = RootSystem(['A',2,1])
117
+ sage: La = R.weight_lattice(extended = True).basis()
118
+ sage: B = crystals.LSPaths(La[2]); B
119
+ Traceback (most recent call last):
120
+ ...
121
+ ValueError: use the weight space, rather than weight lattice for your weights
122
+
123
+ REFERENCES:
124
+
125
+ - [Li1995b]_
126
+ """
127
+ @staticmethod
128
+ def __classcall_private__(cls, starting_weight, cartan_type=None, starting_weight_parent=None):
129
+ """
130
+ Classcall to mend the input.
131
+
132
+ Internally, the
133
+ :class:`~sage.combinat.crystals.littelmann_path.CrystalOfLSPaths` code
134
+ works with a ``starting_weight`` that is in the weight space associated
135
+ to the crystal. The user can, however, also input a ``cartan_type``
136
+ and the coefficients of the fundamental weights as
137
+ ``starting_weight``. This code transforms the input into the right
138
+ format (also necessary for UniqueRepresentation).
139
+
140
+ TESTS::
141
+
142
+ sage: crystals.LSPaths(['A',2,1], [-1,0,1])
143
+ The crystal of LS paths of type ['A', 2, 1] and weight -Lambda[0] + Lambda[2]
144
+
145
+ sage: R = RootSystem(['B',2,1])
146
+ sage: La = R.weight_space(extended=True).basis()
147
+ sage: C = crystals.LSPaths(['B',2,1],[0,0,1])
148
+ sage: B = crystals.LSPaths(La[2])
149
+ sage: B is C
150
+ True
151
+
152
+ sage: La = RootSystem(['A', 3]).weight_space().fundamental_weights()
153
+ sage: crystals.LSPaths(['A', 3], La[2])
154
+ The crystal of LS paths of type ['A', 3] and weight Lambda[2]
155
+
156
+ sage: crystals.LSPaths(La[2] + 2*La[3], ['A', 3])
157
+ The crystal of LS paths of type ['A', 3] and weight Lambda[2] + 2*Lambda[3]
158
+
159
+ sage: crystals.LSPaths(La[2], starting_weight_parent=RootSystem(['B', 3]).weight_space())
160
+ Traceback (most recent call last):
161
+ ...
162
+ ValueError: the passed parent is not equal to parent of the inputted weight
163
+ """
164
+ if cartan_type is not None:
165
+ try:
166
+ cartan_type, starting_weight = CartanType(starting_weight), cartan_type
167
+ except (ValueError, TypeError):
168
+ cartan_type = CartanType(cartan_type)
169
+ extended = cartan_type.is_affine()
170
+
171
+ R = RootSystem(cartan_type)
172
+ P = R.weight_space(extended=extended)
173
+ Lambda = P.basis()
174
+ if not isinstance(starting_weight, P.Element):
175
+ offset = R.index_set()[Integer(0)]
176
+ starting_weight = P.sum(starting_weight[j-offset]*Lambda[j] for j in R.index_set())
177
+ if starting_weight_parent is None:
178
+ starting_weight_parent = starting_weight.parent()
179
+ else:
180
+ # Both the weight and the parent of the weight are passed as arguments of init to be able
181
+ # to distinguish between crystals with the extended and non-extended weight lattice!
182
+ if starting_weight.parent() != starting_weight_parent:
183
+ raise ValueError("the passed parent is not equal to parent of the inputted weight")
184
+
185
+ return super().__classcall__(cls, starting_weight, starting_weight_parent=starting_weight_parent)
186
+
187
+ def __init__(self, starting_weight, starting_weight_parent):
188
+ """
189
+ Initialize ``self``.
190
+
191
+ EXAMPLES::
192
+
193
+ sage: C = crystals.LSPaths(['A',2,1],[-1,0,1]); C
194
+ The crystal of LS paths of type ['A', 2, 1] and weight -Lambda[0] + Lambda[2]
195
+ sage: C.R
196
+ Root system of type ['A', 2, 1]
197
+ sage: C.weight
198
+ -Lambda[0] + Lambda[2]
199
+ sage: C.weight.parent()
200
+ Extended weight space over the Rational Field of the Root system of type ['A', 2, 1]
201
+ sage: C.module_generators
202
+ ((-Lambda[0] + Lambda[2],),)
203
+
204
+ TESTS::
205
+
206
+ sage: C = crystals.LSPaths(['A',2,1], [-1,0,1])
207
+ sage: TestSuite(C).run() # long time
208
+ sage: C = crystals.LSPaths(['E',6], [1,0,0,0,0,0])
209
+ sage: TestSuite(C).run()
210
+
211
+ sage: R = RootSystem(['C',3,1])
212
+ sage: La = R.weight_space().basis()
213
+ sage: LaE = R.weight_space(extended=True).basis()
214
+ sage: B = crystals.LSPaths(La[0])
215
+ sage: BE = crystals.LSPaths(LaE[0])
216
+ sage: B is BE
217
+ False
218
+ sage: B.weight_lattice_realization()
219
+ Weight space over the Rational Field of the Root system of type ['C', 3, 1]
220
+ sage: BE.weight_lattice_realization()
221
+ Extended weight space over the Rational Field of the Root system of type ['C', 3, 1]
222
+ """
223
+ cartan_type = starting_weight.parent().cartan_type()
224
+ self.R = RootSystem(cartan_type)
225
+ self.weight = starting_weight
226
+ if not self.weight.parent().base_ring().has_coerce_map_from(QQ):
227
+ raise ValueError("use the weight space, rather than weight lattice for your weights")
228
+ self._cartan_type = cartan_type
229
+ if cartan_type.is_affine():
230
+ if all(i >= 0 for i in starting_weight.coefficients()):
231
+ Parent.__init__(self, category=(RegularCrystals(),
232
+ HighestWeightCrystals(),
233
+ InfiniteEnumeratedSets()))
234
+ elif starting_weight.parent().is_extended():
235
+ Parent.__init__(self, category=(RegularCrystals(), InfiniteEnumeratedSets()))
236
+ else:
237
+ cl = self._cartan_type.classical().index_set()
238
+ if sum(self.weight[i] for i in cl) == 1:
239
+ cat = KirillovReshetikhinCrystals()
240
+ else:
241
+ cat = RegularLoopCrystals().Finite()
242
+ Parent.__init__(self, category=cat)
243
+ else:
244
+ Parent.__init__(self, category=ClassicalCrystals())
245
+
246
+ if starting_weight == starting_weight.parent().zero():
247
+ initial_element = self(())
248
+ else:
249
+ initial_element = self((starting_weight,))
250
+ self.module_generators = (initial_element,)
251
+
252
+ def _repr_(self):
253
+ r"""
254
+ EXAMPLES::
255
+
256
+ sage: crystals.LSPaths(['B',3],[1,1,0]) # indirect doctest
257
+ The crystal of LS paths of type ['B', 3] and weight Lambda[1] + Lambda[2]
258
+ """
259
+ return f"The crystal of LS paths of type {self._cartan_type} and weight {self.weight}"
260
+
261
+ def weight_lattice_realization(self):
262
+ r"""
263
+ Return weight lattice realization of ``self``.
264
+
265
+ EXAMPLES::
266
+
267
+ sage: B = crystals.LSPaths(['B',3],[1,1,0])
268
+ sage: B.weight_lattice_realization()
269
+ Weight space over the Rational Field of the Root system of type ['B', 3]
270
+ sage: B = crystals.LSPaths(['B',3,1],[1,1,1,0])
271
+ sage: B.weight_lattice_realization()
272
+ Extended weight space over the Rational Field of the Root system of type ['B', 3, 1]
273
+ """
274
+ return self.weight.parent()
275
+
276
+ class Element(ElementWrapper):
277
+ """
278
+ A Littelmann path (crystal element).
279
+
280
+ TESTS::
281
+
282
+ sage: C = crystals.LSPaths(['E',6],[1,0,0,0,0,0])
283
+ sage: c = C.an_element()
284
+ sage: TestSuite(c).run()
285
+ """
286
+ def endpoint(self):
287
+ r"""
288
+ Compute the endpoint of ``self``.
289
+
290
+ EXAMPLES::
291
+
292
+ sage: C = crystals.LSPaths(['A',2],[1,1])
293
+ sage: b = C.module_generators[0]
294
+ sage: b.endpoint()
295
+ Lambda[1] + Lambda[2]
296
+ sage: b.f_string([1,2,2,1])
297
+ (-Lambda[1] - Lambda[2],)
298
+ sage: b.f_string([1,2,2,1]).endpoint()
299
+ -Lambda[1] - Lambda[2]
300
+ sage: b.f_string([1,2])
301
+ (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
302
+ sage: b.f_string([1,2]).endpoint()
303
+ 0
304
+ sage: b = C([])
305
+ sage: b.endpoint()
306
+ 0
307
+ """
308
+ if not self.value:
309
+ return self.parent().weight.parent().zero()
310
+ return sum(self.value)
311
+ #return self.parent().R.weight_space(extended = self.parent().extended).zero()
312
+
313
+ def compress(self):
314
+ r"""
315
+ Merge consecutive positively parallel steps present in ``self``.
316
+
317
+ EXAMPLES::
318
+
319
+ sage: C = crystals.LSPaths(['A',2],[1,1])
320
+ sage: Lambda = C.R.weight_space().fundamental_weights(); Lambda
321
+ Finite family {1: Lambda[1], 2: Lambda[2]}
322
+ sage: c = C(tuple([1/2*Lambda[1]+1/2*Lambda[2], 1/2*Lambda[1]+1/2*Lambda[2]]))
323
+ sage: c.compress()
324
+ (Lambda[1] + Lambda[2],)
325
+ """
326
+ if not self.value:
327
+ return self
328
+ q = []
329
+ curr = self.value[0]
330
+ for v in self.value[1:]:
331
+ if positively_parallel_weights(curr, v):
332
+ curr = curr + v
333
+ else:
334
+ q.append(curr)
335
+ curr = v
336
+ q.append(curr)
337
+ return self.parent()(tuple(q))
338
+
339
+ def split_step(self, which_step, r):
340
+ r"""
341
+ Split the indicated step into two parallel steps of relative
342
+ lengths `r` and `1-r`.
343
+
344
+ INPUT:
345
+
346
+ - ``which_step`` -- a position in the tuple ``self``
347
+ - ``r`` -- a rational number between 0 and 1
348
+
349
+ EXAMPLES::
350
+
351
+ sage: C = crystals.LSPaths(['A',2],[1,1])
352
+ sage: b = C.module_generators[0]
353
+ sage: b.split_step(0,1/3)
354
+ (1/3*Lambda[1] + 1/3*Lambda[2], 2/3*Lambda[1] + 2/3*Lambda[2])
355
+ """
356
+ v = self.value[which_step]
357
+ return self.parent()(self.value[:which_step] + (r*v,(1-r)*v) + self.value[which_step+1:])
358
+
359
+ def reflect_step(self, which_step, i):
360
+ r"""
361
+ Apply the `i`-th simple reflection to the indicated step in ``self``.
362
+
363
+ EXAMPLES::
364
+
365
+ sage: C = crystals.LSPaths(['A',2],[1,1])
366
+ sage: b = C.module_generators[0]
367
+ sage: b.reflect_step(0,1)
368
+ (-Lambda[1] + 2*Lambda[2],)
369
+ sage: b.reflect_step(0,2)
370
+ (2*Lambda[1] - Lambda[2],)
371
+ """
372
+ return self.parent()(self.value[:which_step]+tuple([self.value[which_step].simple_reflection(i)])+self.value[which_step+1:])
373
+
374
+ def _string_data(self, i):
375
+ r"""
376
+ Compute the `i`-string data of ``self``.
377
+
378
+ TESTS::
379
+
380
+ sage: C = crystals.LSPaths(['A',2],[1,1])
381
+ sage: b = C.module_generators[0]
382
+ sage: b._string_data(1)
383
+ ()
384
+ sage: b._string_data(2)
385
+ ()
386
+ sage: b.f(1)._string_data(1)
387
+ ((0, -1, -1),)
388
+ sage: b.f(1).f(2)._string_data(2)
389
+ ((0, -1, -1),)
390
+ """
391
+ if not self.value:
392
+ return ()
393
+ # get the i-th simple coroot
394
+ alv = self.value[0].parent().alphacheck()[i]
395
+ # Compute the i-heights of the steps of vs
396
+ steps = [v.scalar(alv) for v in self.value]
397
+ # Get the wet step data
398
+ minima_pos = []
399
+ ps = 0
400
+ psmin = 0
401
+ for ix, step in enumerate(steps):
402
+ ps = ps + step
403
+ if ps < psmin:
404
+ minima_pos.append((ix,ps,step))
405
+ psmin = ps
406
+ return tuple(minima_pos)
407
+
408
+ def epsilon(self, i):
409
+ r"""
410
+ Return the distance to the beginning of the `i`-string.
411
+
412
+ This method overrides the generic implementation in the category of crystals
413
+ since this computation is more efficient.
414
+
415
+ EXAMPLES::
416
+
417
+ sage: C = crystals.LSPaths(['A',2],[1,1])
418
+ sage: [c.epsilon(1) for c in C]
419
+ [0, 1, 0, 0, 1, 0, 1, 2]
420
+ sage: [c.epsilon(2) for c in C]
421
+ [0, 0, 1, 2, 1, 1, 0, 0]
422
+ """
423
+ return self.e(i, length_only=True)
424
+
425
+ def phi(self, i):
426
+ r"""
427
+ Return the distance to the end of the `i`-string.
428
+
429
+ This method overrides the generic implementation in the category of crystals
430
+ since this computation is more efficient.
431
+
432
+ EXAMPLES::
433
+
434
+ sage: C = crystals.LSPaths(['A',2],[1,1])
435
+ sage: [c.phi(1) for c in C]
436
+ [1, 0, 0, 1, 0, 2, 1, 0]
437
+ sage: [c.phi(2) for c in C]
438
+ [1, 2, 1, 0, 0, 0, 0, 1]
439
+ """
440
+ return self.f(i, length_only=True)
441
+
442
+ def e(self, i, power=1, to_string_end=False, length_only=False):
443
+ r"""
444
+ Return the `i`-th crystal raising operator on ``self``.
445
+
446
+ INPUT:
447
+
448
+ - ``i`` -- element of the index set of the underlying root system
449
+ - ``power`` -- positive integer (default: 1); specifies the power
450
+ of the raising operator to be applied
451
+ - ``to_string_end`` -- boolean (default: ``False``); if ``True``,
452
+ returns the dominant end of the `i`-string of ``self``
453
+ - ``length_only`` -- boolean; if ``True``, returns the distance
454
+ to the dominant end of the `i`-string of ``self``
455
+
456
+ EXAMPLES::
457
+
458
+ sage: C = crystals.LSPaths(['A',2],[1,1])
459
+ sage: c = C[2]; c
460
+ (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
461
+ sage: c.e(1)
462
+ sage: c.e(2)
463
+ (-Lambda[1] + 2*Lambda[2],)
464
+ sage: c.e(2,to_string_end=True)
465
+ (-Lambda[1] + 2*Lambda[2],)
466
+ sage: c.e(1,to_string_end=True)
467
+ (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
468
+ sage: c.e(1,length_only=True)
469
+ 0
470
+ """
471
+ data = self._string_data(i)
472
+ # compute the minimum i-height M on the path
473
+ if not data:
474
+ M = 0
475
+ else:
476
+ M = data[-1][1]
477
+ max_raisings = floor(-M)
478
+ if length_only:
479
+ return max_raisings
480
+ # set the power of e_i to apply
481
+ if to_string_end:
482
+ p = max_raisings
483
+ else:
484
+ p = power
485
+ if p > max_raisings:
486
+ return None
487
+
488
+ # copy the vector sequence into a working vector sequence ws
489
+ #!!! ws only needs to be the actual vector sequence, not some
490
+ #!!! fancy crystal graph element
491
+ P = self.parent()
492
+ ws = P(self.value)
493
+
494
+ ix = len(data) - 1
495
+ while ix >= 0 and data[ix][1] < M + p:
496
+ # get the index of the current step to be processed
497
+ j = data[ix][0]
498
+ # find the i-height where the current step might need to be split
499
+ if ix == 0:
500
+ prev_ht = M + p
501
+ else:
502
+ prev_ht = min(data[ix-1][1], M+p)
503
+ # if necessary split the step. Then reflect the wet part.
504
+ if data[ix][1] - data[ix][2] > prev_ht:
505
+ ws = ws.split_step(j, 1-(prev_ht-data[ix][1])/(-data[ix][2]))
506
+ ws = ws.reflect_step(j+1, i)
507
+ else:
508
+ ws = ws.reflect_step(j, i)
509
+ ix -= 1
510
+ #!!! at this point we should return the fancy crystal graph element
511
+ #!!! corresponding to the humble vector sequence ws
512
+ return P(ws.compress())
513
+
514
+ def dualize(self):
515
+ r"""
516
+ Return the dualized path of ``self``.
517
+
518
+ EXAMPLES::
519
+
520
+ sage: C = crystals.LSPaths(['A',2],[1,1])
521
+ sage: for c in C:
522
+ ....: print("{} {}".format(c, c.dualize()))
523
+ (Lambda[1] + Lambda[2],) (-Lambda[1] - Lambda[2],)
524
+ (-Lambda[1] + 2*Lambda[2],) (Lambda[1] - 2*Lambda[2],)
525
+ (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2]) (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2])
526
+ (Lambda[1] - 2*Lambda[2],) (-Lambda[1] + 2*Lambda[2],)
527
+ (-Lambda[1] - Lambda[2],) (Lambda[1] + Lambda[2],)
528
+ (2*Lambda[1] - Lambda[2],) (-2*Lambda[1] + Lambda[2],)
529
+ (-Lambda[1] + 1/2*Lambda[2], Lambda[1] - 1/2*Lambda[2]) (-Lambda[1] + 1/2*Lambda[2], Lambda[1] - 1/2*Lambda[2])
530
+ (-2*Lambda[1] + Lambda[2],) (2*Lambda[1] - Lambda[2],)
531
+ """
532
+ if not self.value:
533
+ return self
534
+ dual_path = [-v for v in reversed(self.value)]
535
+ return self.parent()(tuple(dual_path))
536
+
537
+ def f(self, i, power=1, to_string_end=False, length_only=False):
538
+ r"""
539
+ Return the `i`-th crystal lowering operator on ``self``.
540
+
541
+ INPUT:
542
+
543
+ - ``i`` -- element of the index set of the underlying root system
544
+ - ``power`` -- positive integer (default: 1); specifies the power
545
+ of the lowering operator to be applied
546
+ - ``to_string_end`` -- boolean (default: ``False``); if ``True``,
547
+ returns the anti-dominant end of the `i`-string of ``self``
548
+ - ``length_only`` -- boolean; if ``True``, returns the distance
549
+ to the anti-dominant end of the `i`-string of ``self``
550
+
551
+ EXAMPLES::
552
+
553
+ sage: C = crystals.LSPaths(['A',2],[1,1])
554
+ sage: c = C.module_generators[0]
555
+ sage: c.f(1)
556
+ (-Lambda[1] + 2*Lambda[2],)
557
+ sage: c.f(1,power=2)
558
+ sage: c.f(2)
559
+ (2*Lambda[1] - Lambda[2],)
560
+ sage: c.f(2,to_string_end=True)
561
+ (2*Lambda[1] - Lambda[2],)
562
+ sage: c.f(2,length_only=True)
563
+ 1
564
+
565
+ sage: C = crystals.LSPaths(['A',2,1],[-1,-1,2])
566
+ sage: c = C.module_generators[0]
567
+ sage: c.f(2,power=2)
568
+ (Lambda[0] + Lambda[1] - 2*Lambda[2],)
569
+ """
570
+ dual_path = self.dualize()
571
+ dual_path = dual_path.e(i, power, to_string_end, length_only)
572
+ if length_only:
573
+ return dual_path
574
+ if dual_path is None:
575
+ return None
576
+ return dual_path.dualize()
577
+
578
+ def s(self, i):
579
+ r"""
580
+ Compute the reflection of ``self`` along the `i`-string.
581
+
582
+ This method is more efficient than the generic implementation since
583
+ it uses powers of `e` and `f` in the Littelmann model directly.
584
+
585
+ EXAMPLES::
586
+
587
+ sage: C = crystals.LSPaths(['A',2],[1,1])
588
+ sage: c = C.module_generators[0]
589
+ sage: c.s(1)
590
+ (-Lambda[1] + 2*Lambda[2],)
591
+ sage: c.s(2)
592
+ (2*Lambda[1] - Lambda[2],)
593
+
594
+ sage: C = crystals.LSPaths(['A',2,1],[-1,0,1])
595
+ sage: c = C.module_generators[0]; c
596
+ (-Lambda[0] + Lambda[2],)
597
+ sage: c.s(2)
598
+ (Lambda[1] - Lambda[2],)
599
+ sage: c.s(1)
600
+ (-Lambda[0] + Lambda[2],)
601
+ sage: c.f(2).s(1)
602
+ (Lambda[0] - Lambda[1],)
603
+ """
604
+ ph = self.phi(i)
605
+ ep = self.epsilon(i)
606
+ diff = ph - ep
607
+ if diff >= 0:
608
+ return self.f(i, power=diff)
609
+ else:
610
+ return self.e(i, power=-diff)
611
+
612
+ def weight(self):
613
+ """
614
+ Return the weight of ``self``.
615
+
616
+ EXAMPLES::
617
+
618
+ sage: B = crystals.LSPaths(['A',1,1],[1,0])
619
+ sage: b = B.highest_weight_vector()
620
+ sage: b.f(0).weight()
621
+ -Lambda[0] + 2*Lambda[1] - delta
622
+ """
623
+ P = self.parent().weight_lattice_realization()
624
+ return P.sum(self.value)
625
+
626
+ def _latex_(self):
627
+ r"""
628
+ Latex method for ``self``.
629
+
630
+ EXAMPLES::
631
+
632
+ sage: C = crystals.LSPaths(['A',2],[1,1])
633
+ sage: c = C.module_generators[0]
634
+ sage: c._latex_()
635
+ [\Lambda_{1} + \Lambda_{2}]
636
+ """
637
+ return [latex(p) for p in self.value]
638
+
639
+
640
+ #####################################################################
641
+ # Projected level-zero
642
+
643
+
644
+ class CrystalOfProjectedLevelZeroLSPaths(CrystalOfLSPaths):
645
+ r"""
646
+ Crystal of projected level zero LS paths.
647
+
648
+ INPUT:
649
+
650
+ - ``weight`` -- a dominant weight of the weight space of an affine
651
+ Kac-Moody root system
652
+
653
+ When ``weight`` is just a single fundamental weight `\Lambda_r`, this
654
+ crystal is isomorphic to a Kirillov-Reshetikhin (KR) crystal, see also
655
+ :meth:`sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinFromLSPaths`.
656
+ For general weights, it is isomorphic to a tensor product of
657
+ single-column KR crystals.
658
+
659
+ EXAMPLES::
660
+
661
+ sage: R = RootSystem(['C',3,1])
662
+ sage: La = R.weight_space().basis()
663
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
664
+ sage: LS.cardinality()
665
+ 84
666
+ sage: GLS = LS.digraph()
667
+
668
+ sage: K1 = crystals.KirillovReshetikhin(['C',3,1],1,1)
669
+ sage: K3 = crystals.KirillovReshetikhin(['C',3,1],3,1)
670
+ sage: T = crystals.TensorProduct(K3,K1)
671
+ sage: T.cardinality()
672
+ 84
673
+ sage: GT = T.digraph() # long time
674
+ sage: GLS.is_isomorphic(GT, edge_labels = True) # long time
675
+ True
676
+
677
+ TESTS::
678
+
679
+ sage: ct = CartanType(['A',4,2]).dual()
680
+ sage: P = RootSystem(ct).weight_space()
681
+ sage: La = P.fundamental_weights()
682
+ sage: C = crystals.ProjectedLevelZeroLSPaths(La[1])
683
+ sage: sorted(C, key=str)
684
+ [(-Lambda[0] + Lambda[1],),
685
+ (-Lambda[1] + 2*Lambda[2],),
686
+ (1/2*Lambda[1] - Lambda[2], -1/2*Lambda[1] + Lambda[2]),
687
+ (Lambda[0] - Lambda[1],),
688
+ (Lambda[1] - 2*Lambda[2],)]
689
+ """
690
+ @staticmethod
691
+ def __classcall_private__(cls, weight):
692
+ """
693
+ Classcall to mend the input.
694
+
695
+ Internally, the
696
+ :class:`~sage.combinat.crystals.littelmann_path.CrystalOfProjectedLevelZeroLSPaths`
697
+ uses a level zero weight, which is passed on to
698
+ :class:`~sage.combinat.crystals.littelmann_path.CrystalOfLSPaths`.
699
+ ``weight`` is first coerced to a level zero weight.
700
+
701
+ TESTS::
702
+
703
+ sage: R = RootSystem(['C',3,1])
704
+ sage: La = R.weight_space().basis()
705
+ sage: C = crystals.ProjectedLevelZeroLSPaths(La[1] + La[2])
706
+ sage: C2 = crystals.ProjectedLevelZeroLSPaths(La[1] + La[2])
707
+ sage: C is C2
708
+ True
709
+
710
+ sage: R = RootSystem(['C',3,1])
711
+ sage: La = R.weight_space(extended = True).basis()
712
+ sage: crystals.ProjectedLevelZeroLSPaths(La[1] + La[2])
713
+ Traceback (most recent call last):
714
+ ...
715
+ ValueError: the weight should be in the non-extended weight lattice
716
+ """
717
+ if weight.parent().is_extended():
718
+ raise ValueError("the weight should be in the non-extended weight lattice")
719
+ La = weight.parent().basis()
720
+ weight = weight - weight.level() * La[0] / La[0].level()
721
+ return super().__classcall__(cls, weight,
722
+ starting_weight_parent=weight.parent())
723
+
724
+ @cached_method
725
+ def maximal_vector(self):
726
+ """
727
+ Return the maximal vector of ``self``.
728
+
729
+ EXAMPLES::
730
+
731
+ sage: R = RootSystem(['A',2,1])
732
+ sage: La = R.weight_space().basis()
733
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]+La[2])
734
+ sage: LS.maximal_vector()
735
+ (-3*Lambda[0] + 2*Lambda[1] + Lambda[2],)
736
+ """
737
+ return self.module_generators[0]
738
+
739
+ @cached_method
740
+ def classically_highest_weight_vectors(self):
741
+ r"""
742
+ Return the classically highest weight vectors of ``self``.
743
+
744
+ EXAMPLES::
745
+
746
+ sage: R = RootSystem(['A',2,1])
747
+ sage: La = R.weight_space().basis()
748
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1])
749
+ sage: LS.classically_highest_weight_vectors()
750
+ ((-2*Lambda[0] + 2*Lambda[1],),
751
+ (-Lambda[0] + Lambda[1], -Lambda[1] + Lambda[2]))
752
+ """
753
+ I0 = self.cartan_type().classical().index_set()
754
+ return tuple([x for x in self.list() if x.is_highest_weight(I0)])
755
+
756
+ def one_dimensional_configuration_sum(self, q=None, group_components=True):
757
+ r"""
758
+ Compute the one-dimensional configuration sum.
759
+
760
+ INPUT:
761
+
762
+ - ``q`` -- (default: ``None``) a variable or ``None``; if ``None``,
763
+ a variable ``q`` is set in the code
764
+ - ``group_components`` -- boolean (default: ``True``); if ``True``,
765
+ then the terms are grouped by classical component
766
+
767
+ The one-dimensional configuration sum is the sum of the weights
768
+ of all elements in the crystal weighted by the energy function.
769
+ For untwisted types it uses the parabolic quantum Bruhat graph,
770
+ see [LNSSS2013]_. In the dual-of-untwisted case, the parabolic
771
+ quantum Bruhat graph is defined by exchanging the roles of roots
772
+ and coroots (which is still conjectural at this point).
773
+
774
+ EXAMPLES::
775
+
776
+ sage: R = RootSystem(['A',2,1])
777
+ sage: La = R.weight_space().basis()
778
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1])
779
+ sage: LS.one_dimensional_configuration_sum() # long time
780
+ B[-2*Lambda[1] + 2*Lambda[2]] + (q+1)*B[-Lambda[1]]
781
+ + (q+1)*B[Lambda[1] - Lambda[2]] + B[2*Lambda[1]]
782
+ + B[-2*Lambda[2]] + (q+1)*B[Lambda[2]]
783
+ sage: R.<t> = ZZ[]
784
+ sage: LS.one_dimensional_configuration_sum(t, False) # long time
785
+ B[-2*Lambda[1] + 2*Lambda[2]] + (t+1)*B[-Lambda[1]]
786
+ + (t+1)*B[Lambda[1] - Lambda[2]] + B[2*Lambda[1]]
787
+ + B[-2*Lambda[2]] + (t+1)*B[Lambda[2]]
788
+
789
+ TESTS::
790
+
791
+ sage: R = RootSystem(['B',3,1])
792
+ sage: La = R.weight_space().basis()
793
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
794
+ sage: LS.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum(group_components=False) # long time
795
+ True
796
+ sage: K1 = crystals.KirillovReshetikhin(['B',3,1],1,1)
797
+ sage: K2 = crystals.KirillovReshetikhin(['B',3,1],2,1)
798
+ sage: T = crystals.TensorProduct(K2,K1)
799
+ sage: T.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum() # long time
800
+ True
801
+
802
+ sage: R = RootSystem(['D',4,2])
803
+ sage: La = R.weight_space().basis()
804
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
805
+ sage: K1 = crystals.KirillovReshetikhin(['D',4,2],1,1)
806
+ sage: K2 = crystals.KirillovReshetikhin(['D',4,2],2,1)
807
+ sage: T = crystals.TensorProduct(K2,K1)
808
+ sage: T.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum() # long time
809
+ True
810
+
811
+ sage: R = RootSystem(['A',5,2])
812
+ sage: La = R.weight_space().basis()
813
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(3*La[1])
814
+ sage: K1 = crystals.KirillovReshetikhin(['A',5,2],1,1)
815
+ sage: T = crystals.TensorProduct(K1,K1,K1)
816
+ sage: T.one_dimensional_configuration_sum() == LS.one_dimensional_configuration_sum() # long time
817
+ True
818
+ """
819
+ if q is None:
820
+ from sage.rings.rational_field import QQ
821
+ q = QQ['q'].gens()[0]
822
+ #P0 = self.weight_lattice_realization().classical()
823
+ P0 = RootSystem(self.cartan_type().classical()).weight_lattice()
824
+ R = P0.base_ring()
825
+ B = P0.algebra(q.parent())
826
+
827
+ I0 = frozenset(P0.index_set())
828
+
829
+ def weight(x):
830
+ w = x.weight()
831
+ return P0.element_class(P0, {i: R(c) for i, c in w if i in I0})
832
+
833
+ if group_components:
834
+ G = self.digraph(index_set=self.cartan_type().classical().index_set())
835
+ C = G.connected_components(sort=False)
836
+ return sum(q**(c[0].energy_function()) * B.sum(B(weight(b)) for b in c) for c in C)
837
+ return B.sum(q**(b.energy_function()) * B(weight(b)) for b in self)
838
+
839
+ def is_perfect(self, level=1):
840
+ r"""
841
+ Check whether the crystal ``self`` is perfect (of level ``level``).
842
+
843
+ INPUT:
844
+
845
+ - ``level`` -- (default: 1) positive integer
846
+
847
+ A crystal `\mathcal{B}` is perfect of level `\ell` if:
848
+
849
+ #. `\mathcal{B}` is isomorphic to the crystal graph of a
850
+ finite-dimensional `U_q^{'}(\mathfrak{g})`-module.
851
+ #. `\mathcal{B}\otimes \mathcal{B}` is connected.
852
+ #. There exists a `\lambda\in X`, such that
853
+ `\mathrm{wt}(\mathcal{B}) \subset \lambda + \sum_{i\in I} \ZZ_{\le 0} \alpha_i`
854
+ and there is a unique element in
855
+ `\mathcal{B}` of classical weight `\lambda`.
856
+ #. For all `b \in \mathcal{B}`,
857
+ `\mathrm{level}(\varepsilon (b)) \geq \ell`.
858
+ #. For all `\Lambda` dominant weights of level `\ell`, there exist
859
+ unique elements `b_{\Lambda}, b^{\Lambda} \in \mathcal{B}`, such
860
+ that `\varepsilon (b_{\Lambda}) = \Lambda = \varphi(b^{\Lambda})`.
861
+
862
+ Points (1)-(3) are known to hold. This method checks points (4) and (5).
863
+
864
+ EXAMPLES::
865
+
866
+ sage: C = CartanType(['C',2,1])
867
+ sage: R = RootSystem(C)
868
+ sage: La = R.weight_space().basis()
869
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1])
870
+ sage: LS.is_perfect()
871
+ False
872
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[2])
873
+ sage: LS.is_perfect()
874
+ True
875
+
876
+ sage: C = CartanType(['E',6,1])
877
+ sage: R = RootSystem(C)
878
+ sage: La = R.weight_space().basis()
879
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1])
880
+ sage: LS.is_perfect()
881
+ True
882
+ sage: LS.is_perfect(2)
883
+ False
884
+
885
+ sage: C = CartanType(['D',4,1])
886
+ sage: R = RootSystem(C)
887
+ sage: La = R.weight_space().basis()
888
+ sage: all(crystals.ProjectedLevelZeroLSPaths(La[i]).is_perfect() for i in [1,2,3,4])
889
+ True
890
+
891
+ sage: C = CartanType(['A',6,2])
892
+ sage: R = RootSystem(C)
893
+ sage: La = R.weight_space().basis()
894
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
895
+ sage: LS.is_perfect()
896
+ True
897
+ sage: LS.is_perfect(2)
898
+ False
899
+ """
900
+ MPhi = []
901
+ for b in self:
902
+ p = b.Phi().level()
903
+ assert p == b.Epsilon().level()
904
+ if p < level:
905
+ return False
906
+ if p == level:
907
+ MPhi += [b]
908
+ weights = []
909
+ I = self.index_set()
910
+ rank = len(I)
911
+ WLR = self.weight_lattice_realization()
912
+ R = WLR.base_ring()
913
+ from sage.combinat.integer_vector import integer_vectors_nk_fast_iter
914
+ for n in range(1, level+1):
915
+ for c in integer_vectors_nk_fast_iter(n, rank):
916
+ w = WLR.element_class(WLR, {i: R(c[i]) for i in I if c[i]})
917
+ if w.level() == level:
918
+ weights.append(w)
919
+ return sorted([b.Phi() for b in MPhi]) == sorted(weights)
920
+
921
+ class Element(CrystalOfLSPaths.Element):
922
+ """
923
+ Element of a crystal of projected level zero LS paths.
924
+ """
925
+ @cached_in_parent_method
926
+ def scalar_factors(self):
927
+ r"""
928
+ Return the scalar factors for ``self``.
929
+
930
+ Each LS path (or ``self``) can be written as a piecewise linear map
931
+
932
+ .. MATH::
933
+
934
+ \pi(t) = \sum_{u'=1}^{u-1} (\sigma_{u'} - \sigma_{u'-1}) \nu_{u'}
935
+ + (t-\sigma_{u-1}) \nu_{u}
936
+
937
+ for `0 < \sigma_1 < \sigma_2 < \cdots < \sigma_s=1` and
938
+ `\sigma_{u-1} \le t \le \sigma_{u}` and `1 \le u \le s`.
939
+ This method returns the tuple of `(\sigma_1,\ldots,\sigma_s)`.
940
+
941
+ EXAMPLES::
942
+
943
+ sage: R = RootSystem(['C',3,1])
944
+ sage: La = R.weight_space().basis()
945
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
946
+ sage: b = LS.module_generators[0]
947
+ sage: b.scalar_factors()
948
+ [1]
949
+ sage: c = b.f(1).f(3).f(2)
950
+ sage: c.scalar_factors()
951
+ [1/3, 1]
952
+ """
953
+ weight = self.parent().weight
954
+ l = []
955
+ s = 0
956
+ for c in self.value:
957
+ supp = c.support()
958
+ if supp:
959
+ i = supp[0]
960
+ for w in weight._orbit_iter():
961
+ # Check whether the vectors c and w are positive scalar multiples of each other
962
+ # If i is not in the support of w, then the first
963
+ # product is 0
964
+ if c[i] * w[i] > 0 and c[i] * w == w[i] * c:
965
+ s += c[i] / w[i]
966
+ l += [s]
967
+ break
968
+ return l
969
+
970
+ @cached_in_parent_method
971
+ def weyl_group_representation(self):
972
+ r"""
973
+ Transform the weights in the LS path ``self`` to elements
974
+ in the Weyl group.
975
+
976
+ Each LS path can be written as the piecewise linear map:
977
+
978
+ .. MATH::
979
+
980
+ \pi(t) = \sum_{u'=1}^{u-1} (\sigma_{u'} - \sigma_{u'-1}) \nu_{u'}
981
+ + (t-\sigma_{u-1}) \nu_{u}
982
+
983
+ for `0 < \sigma_1 < \sigma_2 < \cdots < \sigma_s = 1` and
984
+ `\sigma_{u-1} \le t \le \sigma_{u}` and `1 \le u \le s`.
985
+ Each weight `\nu_u` is also associated to a Weyl group element.
986
+ This method returns the list of Weyl group elements associated
987
+ to the `\nu_u` for `1\le u\le s`.
988
+
989
+ EXAMPLES::
990
+
991
+ sage: R = RootSystem(['C',3,1])
992
+ sage: La = R.weight_space().basis()
993
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
994
+ sage: b = LS.module_generators[0]
995
+ sage: c = b.f(1).f(3).f(2)
996
+ sage: c.weyl_group_representation()
997
+ [s2*s1*s3, s1*s3]
998
+ """
999
+ cartan = self.parent().weight.parent().cartan_type().classical()
1000
+ I = cartan.index_set()
1001
+ W = WeylGroup(cartan, prefix='s', implementation='permutation')
1002
+ return [W.from_reduced_word(x.to_dominant_chamber(index_set=I, reduced_word=True)[1]) for x in self.value]
1003
+
1004
+ @cached_in_parent_method
1005
+ def energy_function(self):
1006
+ r"""
1007
+ Return the energy function of ``self``.
1008
+
1009
+ The energy function `D(\pi)` of the level zero LS path
1010
+ `\pi \in \mathbb{B}_\mathrm{cl}(\lambda)` requires a series
1011
+ of definitions; for simplicity the root system is assumed to
1012
+ be untwisted affine.
1013
+
1014
+ The LS path `\pi` is a piecewise linear map from the unit
1015
+ interval `[0,1]` to the weight lattice. It is specified by
1016
+ "times" `0 = \sigma_0 < \sigma_1 < \dotsm < \sigma_s = 1` and
1017
+ "direction vectors" `x_u \lambda` where `x_u \in W / W_J` for
1018
+ `1 \le u \le s`, and `W_J` is the stabilizer of `\lambda` in
1019
+ the finite Weyl group `W`. Precisely,
1020
+
1021
+ .. MATH::
1022
+
1023
+ \pi(t) = \sum_{u'=1}^{u-1} (\sigma_{u'}-\sigma_{u'-1})
1024
+ x_{u'} \lambda + (t-\sigma_{u-1}) x_{u} \lambda
1025
+
1026
+ for `1 \le u \le s` and `\sigma_{u-1} \le t \le \sigma_{u}`.
1027
+
1028
+ For any `x,y \in W / W_J`, let
1029
+
1030
+ .. MATH::
1031
+
1032
+ d: x = w_{0} \stackrel{\beta_{1}}{\leftarrow}
1033
+ w_{1} \stackrel{\beta_{2}}{\leftarrow} \cdots
1034
+ \stackrel{\beta_{n}}{\leftarrow} w_{n}=y
1035
+
1036
+ be a shortest directed path in the parabolic quantum
1037
+ Bruhat graph. Define
1038
+
1039
+ .. MATH::
1040
+
1041
+ \mathrm{wt}(d) := \sum_{\substack{1 \le k \le n
1042
+ \\ \ell(w_{k-1}) < \ell(w_k)}}
1043
+ \beta_{k}^{\vee}.
1044
+
1045
+ It can be shown that `\mathrm{wt}(d)` depends only on `x,y`;
1046
+ call its value `\mathrm{wt}(x,y)`. The energy function `D(\pi)`
1047
+ is defined by
1048
+
1049
+ .. MATH::
1050
+
1051
+ D(\pi) = -\sum_{u=1}^{s-1} (1-\sigma_{u}) \langle \lambda,
1052
+ \mathrm{wt}(x_u,x_{u+1}) \rangle.
1053
+
1054
+ For more information, see [LNSSS2013]_.
1055
+
1056
+ .. NOTE::
1057
+
1058
+ In the dual-of-untwisted case the parabolic quantum
1059
+ Bruhat graph that is used is obtained by exchanging the
1060
+ roles of roots and coroots. Moreover, in the computation
1061
+ of the pairing the short roots must be doubled (or tripled
1062
+ for type `G`). This factor is determined by the translation
1063
+ factor of the corresponding root. Type `BC` is viewed as
1064
+ untwisted type, whereas the dual of `BC` is viewed as twisted.
1065
+ Except for the untwisted cases, these formulas are
1066
+ currently still conjectural.
1067
+
1068
+ EXAMPLES::
1069
+
1070
+ sage: R = RootSystem(['C',3,1])
1071
+ sage: La = R.weight_space().basis()
1072
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[3])
1073
+ sage: b = LS.module_generators[0]
1074
+ sage: c = b.f(1).f(3).f(2)
1075
+ sage: c.energy_function()
1076
+ 0
1077
+ sage: c=b.e(0)
1078
+ sage: c.energy_function()
1079
+ 1
1080
+
1081
+ sage: R = RootSystem(['A',2,1])
1082
+ sage: La = R.weight_space().basis()
1083
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1])
1084
+ sage: b = LS.module_generators[0]
1085
+ sage: c = b.e(0)
1086
+ sage: c.energy_function()
1087
+ 1
1088
+ sage: for c in sorted(LS, key=str):
1089
+ ....: print("{} {}".format(c,c.energy_function()))
1090
+ (-2*Lambda[0] + 2*Lambda[1],) 0
1091
+ (-2*Lambda[1] + 2*Lambda[2],) 0
1092
+ (-Lambda[0] + Lambda[1], -Lambda[1] + Lambda[2]) 1
1093
+ (-Lambda[0] + Lambda[1], Lambda[0] - Lambda[2]) 1
1094
+ (-Lambda[1] + Lambda[2], -Lambda[0] + Lambda[1]) 0
1095
+ (-Lambda[1] + Lambda[2], Lambda[0] - Lambda[2]) 1
1096
+ (2*Lambda[0] - 2*Lambda[2],) 0
1097
+ (Lambda[0] - Lambda[2], -Lambda[0] + Lambda[1]) 0
1098
+ (Lambda[0] - Lambda[2], -Lambda[1] + Lambda[2]) 0
1099
+
1100
+ The next test checks that the energy function is constant
1101
+ on classically connected components::
1102
+
1103
+ sage: R = RootSystem(['A',2,1])
1104
+ sage: La = R.weight_space().basis()
1105
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]+La[2])
1106
+ sage: G = LS.digraph(index_set=[1,2])
1107
+ sage: C = G.connected_components(sort=False)
1108
+ sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C]
1109
+ [True, True, True, True]
1110
+
1111
+ sage: R = RootSystem(['D',4,2])
1112
+ sage: La = R.weight_space().basis()
1113
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[2])
1114
+ sage: J = R.cartan_type().classical().index_set()
1115
+ sage: hw = [x for x in LS if x.is_highest_weight(J)]
1116
+ sage: [(x.weight(), x.energy_function()) for x in hw]
1117
+ [(-2*Lambda[0] + Lambda[2], 0), (-2*Lambda[0] + Lambda[1], 1), (0, 2)]
1118
+ sage: G = LS.digraph(index_set=J)
1119
+ sage: C = G.connected_components(sort=False)
1120
+ sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C]
1121
+ [True, True, True]
1122
+
1123
+ sage: R = RootSystem(CartanType(['G',2,1]).dual())
1124
+ sage: La = R.weight_space().basis()
1125
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(La[1]+La[2])
1126
+ sage: G = LS.digraph(index_set=[1,2])
1127
+ sage: C = G.connected_components(sort=False)
1128
+ sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] # long time
1129
+ [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
1130
+
1131
+ sage: ct = CartanType(['BC',2,2]).dual()
1132
+ sage: R = RootSystem(ct)
1133
+ sage: La = R.weight_space().basis()
1134
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]+La[2])
1135
+ sage: G = LS.digraph(index_set=R.cartan_type().classical().index_set())
1136
+ sage: C = G.connected_components(sort=False)
1137
+ sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] # long time
1138
+ [True, True, True, True, True, True, True, True, True, True, True]
1139
+
1140
+ sage: R = RootSystem(['BC',2,2])
1141
+ sage: La = R.weight_space().basis()
1142
+ sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]+La[2])
1143
+ sage: G = LS.digraph(index_set=R.cartan_type().classical().index_set())
1144
+ sage: C = G.connected_components(sort=False)
1145
+ sage: [all(c[0].energy_function()==a.energy_function() for a in c) for c in C] # long time
1146
+ [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True,
1147
+ True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
1148
+ """
1149
+ weight = self.parent().weight
1150
+ P = weight.parent()
1151
+ c_weight = P.classical()(weight)
1152
+ ct = P.cartan_type()
1153
+ cartan = ct.classical()
1154
+ Qv = RootSystem(cartan).coroot_lattice()
1155
+ W = WeylGroup(cartan, prefix='s', implementation='permutation')
1156
+ J = tuple(weight.weyl_stabilizer())
1157
+ L = self.weyl_group_representation()
1158
+ if ct.is_untwisted_affine() or ct.type() == 'BC':
1159
+ untwisted = True
1160
+ G = W.quantum_bruhat_graph(J)
1161
+ else:
1162
+ untwisted = False
1163
+ cartan_dual = cartan.dual()
1164
+ Wd = WeylGroup(cartan_dual, prefix='s', implementation='permutation')
1165
+ G = Wd.quantum_bruhat_graph(J)
1166
+ Qd = RootSystem(cartan_dual).root_lattice()
1167
+
1168
+ def dualize(x):
1169
+ return Qv.from_vector(x.to_vector())
1170
+
1171
+ L = [Wd.from_reduced_word(x.reduced_word()) for x in L]
1172
+
1173
+ def stretch_short_root(a):
1174
+ # stretches roots by translation factor
1175
+ if ct.dual().type() == 'BC':
1176
+ return ct.c()[a.to_simple_root()]*a
1177
+ return ct.dual().c()[a.to_simple_root()]*a
1178
+ #if a.is_short_root():
1179
+ # if cartan_dual.type() == 'G':
1180
+ # return 3*a
1181
+ # else:
1182
+ # return 2*a
1183
+ #return a
1184
+
1185
+ paths = [G.shortest_path(L[i+1],L[i]) for i in range(len(L)-1)]
1186
+ paths_labels = [[G.edge_label(p[i],p[i+1]) for i in range(len(p)-1) if p[i].length()+1 != p[i+1].length()] for p in paths]
1187
+ scalars = self.scalar_factors()
1188
+ if untwisted:
1189
+ s = sum((1 - scalars[i]) * c_weight.scalar(Qv.sum(root.associated_coroot() for root in label))
1190
+ for i, label in enumerate(paths_labels))
1191
+ if ct.type() == 'BC':
1192
+ return 2 * s
1193
+ else:
1194
+ return s
1195
+ else:
1196
+ s = sum((1 - scalars[i]) * c_weight.scalar(dualize(Qd.sum(stretch_short_root(root) for root in label)))
1197
+ for i, label in enumerate(paths_labels))
1198
+ if ct.dual().type() == 'BC':
1199
+ return s / 2
1200
+ else:
1201
+ return s
1202
+
1203
+
1204
+ #####################################################################
1205
+ # B(\infty)
1206
+
1207
+
1208
+ class InfinityCrystalOfLSPaths(UniqueRepresentation, Parent):
1209
+ r"""
1210
+ LS path model for `\mathcal{B}(\infty)`.
1211
+
1212
+ Elements of `\mathcal{B}(\infty)` are equivalence classes of paths `[\pi]`
1213
+ in `\mathcal{B}(k\rho)` for `k\gg 0`, where `\rho` is the Weyl vector. A
1214
+ canonical representative for an element of `\mathcal{B}(\infty)` is chosen
1215
+ by taking `k` to be minimal such that the endpoint of `\pi` is strictly
1216
+ dominant but its representative in `\mathcal{B}((k-1)\rho)` is on the wall
1217
+ of the dominant chamber.
1218
+
1219
+ REFERENCES:
1220
+
1221
+ - [LZ2011]_
1222
+ """
1223
+ @staticmethod
1224
+ def __classcall_private__(cls, cartan_type):
1225
+ """
1226
+ Normalize input to ensure a unique representation.
1227
+
1228
+ EXAMPLES::
1229
+
1230
+ sage: B1 = crystals.infinity.LSPaths(['A',4])
1231
+ sage: B2 = crystals.infinity.LSPaths('A4')
1232
+ sage: B3 = crystals.infinity.LSPaths(CartanType(['A',4]))
1233
+ sage: B1 is B2 and B2 is B3
1234
+ True
1235
+ """
1236
+ cartan_type = CartanType(cartan_type)
1237
+ return super().__classcall__(cls, cartan_type)
1238
+
1239
+ def __init__(self, cartan_type):
1240
+ """
1241
+ Initialize ``self``.
1242
+
1243
+ EXAMPLES::
1244
+
1245
+ sage: B = crystals.infinity.LSPaths(['D',4,3])
1246
+ sage: TestSuite(B).run(max_runs=500)
1247
+ sage: B = crystals.infinity.LSPaths(['B',3])
1248
+ sage: TestSuite(B).run() # long time
1249
+ """
1250
+ Parent.__init__(self, category=(HighestWeightCrystals(),
1251
+ InfiniteEnumeratedSets()))
1252
+ self._cartan_type = cartan_type
1253
+ self.module_generators = (self.module_generator(),)
1254
+
1255
+ def _repr_(self):
1256
+ """
1257
+ Return a string representation of ``self``.
1258
+
1259
+ EXAMPLES::
1260
+
1261
+ sage: crystals.infinity.LSPaths(['A',4])
1262
+ The infinity crystal of LS paths of type ['A', 4]
1263
+ """
1264
+ return "The infinity crystal of LS paths of type %s" % self._cartan_type
1265
+
1266
+ @cached_method
1267
+ def module_generator(self):
1268
+ r"""
1269
+ Return the module generator (or highest weight element) of ``self``.
1270
+
1271
+ The module generator is the unique path
1272
+ `\pi_\infty\colon t \mapsto t\rho`, for `t \in [0,\infty)`.
1273
+
1274
+ EXAMPLES::
1275
+
1276
+ sage: B = crystals.infinity.LSPaths(['A',6,2])
1277
+ sage: mg = B.module_generator(); mg
1278
+ (Lambda[0] + Lambda[1] + Lambda[2] + Lambda[3],)
1279
+ sage: mg.weight()
1280
+ 0
1281
+ """
1282
+ rho = self.weight_lattice_realization().rho()
1283
+ return self((rho,))
1284
+
1285
+ def weight_lattice_realization(self):
1286
+ """
1287
+ Return the weight lattice realization of ``self``.
1288
+
1289
+ EXAMPLES::
1290
+
1291
+ sage: B = crystals.infinity.LSPaths(['C',4])
1292
+ sage: B.weight_lattice_realization()
1293
+ Weight space over the Rational Field of the Root system of type ['C', 4]
1294
+ """
1295
+ if self._cartan_type.is_affine():
1296
+ return self._cartan_type.root_system().weight_space(extended=True)
1297
+ return self._cartan_type.root_system().weight_space()
1298
+
1299
+ class Element(CrystalOfLSPaths.Element):
1300
+ def e(self, i, power=1, length_only=False):
1301
+ r"""
1302
+ Return the `i`-th crystal raising operator on ``self``.
1303
+
1304
+ INPUT:
1305
+
1306
+ - ``i`` -- element of the index set
1307
+ - ``power`` -- (default: 1) positive integer; specifies the
1308
+ power of the lowering operator to be applied
1309
+ - ``length_only`` -- boolean (default: ``False``); if ``True``,
1310
+ then return the distance to the anti-dominant end of the
1311
+ `i`-string of ``self``
1312
+
1313
+ EXAMPLES::
1314
+
1315
+ sage: B = crystals.infinity.LSPaths(['B',3,1])
1316
+ sage: mg = B.module_generator()
1317
+ sage: mg.e(0)
1318
+ sage: mg.e(1)
1319
+ sage: mg.e(2)
1320
+ sage: x = mg.f_string([1,0,2,1,0,2,1,1,0])
1321
+ sage: all(x.f(i).e(i) == x for i in B.index_set())
1322
+ True
1323
+ sage: all(x.e(i).f(i) == x for i in B.index_set() if x.epsilon(i) > 0)
1324
+ True
1325
+
1326
+ TESTS:
1327
+
1328
+ Check that this works in affine types::
1329
+
1330
+ sage: B = crystals.infinity.LSPaths(['A',3,1])
1331
+ sage: mg = B.highest_weight_vector()
1332
+ sage: x = mg.f_string([0,1,2,3])
1333
+ sage: x.e_string([3,2,1,0]) == mg
1334
+ True
1335
+
1336
+ We check that :meth:`epsilon` works::
1337
+
1338
+ sage: B = crystals.infinity.LSPaths(['D',4])
1339
+ sage: mg = B.highest_weight_vector()
1340
+ sage: x = mg.f_string([1,3,4,2,4,3,2,1,4])
1341
+ sage: [x.epsilon(i) for i in B.index_set()]
1342
+ [1, 1, 0, 1]
1343
+
1344
+ Check that :issue:`21671` is fixed::
1345
+
1346
+ sage: B = crystals.infinity.LSPaths(['G',2])
1347
+ sage: len(B.subcrystal(max_depth=7))
1348
+ 116
1349
+ """
1350
+ ret = super().e(i, power=power,
1351
+ length_only=length_only)
1352
+ if ret is None:
1353
+ return None
1354
+ if length_only:
1355
+ return ret
1356
+ WLR = self.parent().weight_lattice_realization()
1357
+ value = list(ret.value)
1358
+ endpoint = sum(value)
1359
+ rho = WLR.rho()
1360
+ h = WLR.simple_coroots()
1361
+
1362
+ if not positively_parallel_weights(value[-1], rho):
1363
+ value.append(rho)
1364
+ endpoint += rho
1365
+
1366
+ while any(endpoint.scalar(alc) < 1 for alc in h):
1367
+ value[-1] += rho
1368
+ endpoint += rho
1369
+ while all(endpoint.scalar(alc) > 1 for alc in h) and value[-1] != WLR.zero():
1370
+ value[-1] -= rho
1371
+ endpoint -= rho
1372
+ while value[-1] == WLR.zero():
1373
+ value.pop()
1374
+ ret.value = tuple(value)
1375
+ return ret
1376
+
1377
+ def f(self, i, power=1, length_only=False):
1378
+ r"""
1379
+ Return the `i`-th crystal lowering operator on ``self``.
1380
+
1381
+ INPUT:
1382
+
1383
+ - ``i`` -- element of the index set
1384
+ - ``power`` -- (default: 1) positive integer; specifies the
1385
+ power of the lowering operator to be applied
1386
+ - ``length_only`` -- boolean (default: ``False``); if ``True``,
1387
+ then return the distance to the anti-dominant end of the
1388
+ `i`-string of ``self``
1389
+
1390
+ EXAMPLES::
1391
+
1392
+ sage: B = crystals.infinity.LSPaths(['D',3,2])
1393
+ sage: mg = B.highest_weight_vector()
1394
+ sage: mg.f(1)
1395
+ (3*Lambda[0] - Lambda[1] + 3*Lambda[2],
1396
+ 2*Lambda[0] + 2*Lambda[1] + 2*Lambda[2])
1397
+ sage: mg.f(2)
1398
+ (Lambda[0] + 2*Lambda[1] - Lambda[2],
1399
+ 2*Lambda[0] + 2*Lambda[1] + 2*Lambda[2])
1400
+ sage: mg.f(0)
1401
+ (-Lambda[0] + 2*Lambda[1] + Lambda[2] - delta,
1402
+ 2*Lambda[0] + 2*Lambda[1] + 2*Lambda[2])
1403
+ """
1404
+ dual_path = self.dualize()
1405
+ dual_path = super(InfinityCrystalOfLSPaths.Element, dual_path).e(i, power, length_only=length_only)
1406
+ if length_only:
1407
+ return dual_path
1408
+ if dual_path is None:
1409
+ return None
1410
+ ret = dual_path.dualize()
1411
+ WLR = self.parent().weight_lattice_realization()
1412
+ value = list(ret.value)
1413
+ endpoint = sum(value)
1414
+ rho = WLR.rho()
1415
+ h = WLR.simple_coroots()
1416
+
1417
+ if not positively_parallel_weights(value[-1], rho):
1418
+ value.append(rho)
1419
+ endpoint += rho
1420
+
1421
+ while any(endpoint.scalar(alc) < 1 for alc in h):
1422
+ value[-1] += rho
1423
+ endpoint += rho
1424
+ while all(endpoint.scalar(alc) > 1 for alc in h) and value[-1] != WLR.zero():
1425
+ value[-1] -= rho
1426
+ endpoint -= rho
1427
+ while value[-1] == WLR.zero():
1428
+ value.pop()
1429
+ ret.value = tuple(value)
1430
+ return ret
1431
+
1432
+ @cached_method
1433
+ def weight(self):
1434
+ """
1435
+ Return the weight of ``self``.
1436
+
1437
+ .. TODO::
1438
+
1439
+ This is a generic algorithm. We should find a better
1440
+ description and implement it.
1441
+
1442
+ EXAMPLES::
1443
+
1444
+ sage: B = crystals.infinity.LSPaths(['E',6])
1445
+ sage: mg = B.highest_weight_vector()
1446
+ sage: f_seq = [1,4,2,6,4,2,3,1,5,5]
1447
+ sage: x = mg.f_string(f_seq)
1448
+ sage: x.weight()
1449
+ -3*Lambda[1] - 2*Lambda[2] + 2*Lambda[3] + Lambda[4] - Lambda[5]
1450
+
1451
+ sage: al = B.cartan_type().root_system().weight_space().simple_roots()
1452
+ sage: x.weight() == -sum(al[i] for i in f_seq)
1453
+ True
1454
+ """
1455
+ WLR = self.parent().weight_lattice_realization()
1456
+ alpha = WLR.simple_roots()
1457
+ return -WLR.sum(alpha[i] for i in self.to_highest_weight()[1])
1458
+
1459
+ def phi(self, i):
1460
+ r"""
1461
+ Return `\varphi_i` of ``self``.
1462
+
1463
+ Let `\pi \in \mathcal{B}(\infty)`. Define
1464
+
1465
+ .. MATH::
1466
+
1467
+ \varphi_i(\pi) := \varepsilon_i(\pi) + \langle h_i,
1468
+ \mathrm{wt}(\pi) \rangle,
1469
+
1470
+ where `h_i` is the `i`-th simple coroot and `\mathrm{wt}(\pi)`
1471
+ is the :meth:`weight` of `\pi`.
1472
+
1473
+ INPUT:
1474
+
1475
+ - ``i`` -- element of the index set
1476
+
1477
+ EXAMPLES::
1478
+
1479
+ sage: B = crystals.infinity.LSPaths(['D',4])
1480
+ sage: mg = B.highest_weight_vector()
1481
+ sage: x = mg.f_string([1,3,4,2,4,3,2,1,4])
1482
+ sage: [x.phi(i) for i in B.index_set()]
1483
+ [-1, 4, -2, -3]
1484
+ """
1485
+ WLR = self.parent().weight_lattice_realization()
1486
+ h = WLR.simple_coroots()
1487
+ return self.epsilon(i) + WLR(self.weight()).scalar(h[i])
1488
+
1489
+
1490
+ #####################################################################
1491
+ # Helper functions
1492
+
1493
+
1494
+ def positively_parallel_weights(v, w):
1495
+ """
1496
+ Check whether the vectors ``v`` and ``w`` are positive scalar
1497
+ multiples of each other.
1498
+
1499
+ EXAMPLES::
1500
+
1501
+ sage: from sage.combinat.crystals.littelmann_path import positively_parallel_weights
1502
+ sage: La = RootSystem(['A',5,2]).weight_space(extended=True).fundamental_weights()
1503
+ sage: rho = sum(La)
1504
+ sage: positively_parallel_weights(rho, 4*rho)
1505
+ True
1506
+ sage: positively_parallel_weights(4*rho, rho)
1507
+ True
1508
+ sage: positively_parallel_weights(rho, -rho)
1509
+ False
1510
+ sage: positively_parallel_weights(rho, La[1] + La[2])
1511
+ False
1512
+ """
1513
+ supp = v.support()
1514
+ if supp:
1515
+ i = supp[0]
1516
+ if v[i] * w[i] > 0 and v[i] * w == w[i] * v:
1517
+ return True
1518
+ return False