passagemath-combinat 10.6.42__cp314-cp314t-win_amd64.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 (401) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
  3. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  4. passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
  5. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  6. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  7. passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
  8. passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
  9. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  10. sage/algebras/all.py +24 -0
  11. sage/algebras/all__sagemath_combinat.py +35 -0
  12. sage/algebras/askey_wilson.py +935 -0
  13. sage/algebras/associated_graded.py +345 -0
  14. sage/algebras/cellular_basis.py +350 -0
  15. sage/algebras/cluster_algebra.py +2766 -0
  16. sage/algebras/down_up_algebra.py +860 -0
  17. sage/algebras/free_algebra.py +1698 -0
  18. sage/algebras/free_algebra_element.py +345 -0
  19. sage/algebras/free_algebra_quotient.py +405 -0
  20. sage/algebras/free_algebra_quotient_element.py +295 -0
  21. sage/algebras/free_zinbiel_algebra.py +885 -0
  22. sage/algebras/hall_algebra.py +783 -0
  23. sage/algebras/hecke_algebras/all.py +4 -0
  24. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  25. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  28. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  29. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  30. sage/algebras/jordan_algebra.py +1773 -0
  31. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  32. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  33. sage/algebras/lie_conformal_algebras/all.py +18 -0
  34. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  35. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  36. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  37. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  38. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  39. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  40. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  41. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  45. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  46. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  47. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  48. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  49. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  50. sage/algebras/nil_coxeter_algebra.py +191 -0
  51. sage/algebras/q_commuting_polynomials.py +673 -0
  52. sage/algebras/q_system.py +608 -0
  53. sage/algebras/quantum_clifford.py +959 -0
  54. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  55. sage/algebras/quantum_groups/all.py +9 -0
  56. sage/algebras/quantum_groups/fock_space.py +2219 -0
  57. sage/algebras/quantum_groups/q_numbers.py +207 -0
  58. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  59. sage/algebras/quantum_groups/representations.py +591 -0
  60. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  61. sage/algebras/quantum_oscillator.py +623 -0
  62. sage/algebras/quaternion_algebra.py +20 -0
  63. sage/algebras/quaternion_algebra_element.py +55 -0
  64. sage/algebras/rational_cherednik_algebra.py +525 -0
  65. sage/algebras/schur_algebra.py +670 -0
  66. sage/algebras/shuffle_algebra.py +1011 -0
  67. sage/algebras/splitting_algebra.py +779 -0
  68. sage/algebras/tensor_algebra.py +709 -0
  69. sage/algebras/yangian.py +1082 -0
  70. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  71. sage/all__sagemath_combinat.py +44 -0
  72. sage/combinat/SJT.py +255 -0
  73. sage/combinat/affine_permutation.py +2405 -0
  74. sage/combinat/algebraic_combinatorics.py +55 -0
  75. sage/combinat/all.py +53 -0
  76. sage/combinat/all__sagemath_combinat.py +195 -0
  77. sage/combinat/alternating_sign_matrix.py +2063 -0
  78. sage/combinat/baxter_permutations.py +346 -0
  79. sage/combinat/bijectionist.py +3220 -0
  80. sage/combinat/binary_recurrence_sequences.py +1180 -0
  81. sage/combinat/blob_algebra.py +685 -0
  82. sage/combinat/catalog_partitions.py +27 -0
  83. sage/combinat/chas/all.py +23 -0
  84. sage/combinat/chas/fsym.py +1180 -0
  85. sage/combinat/chas/wqsym.py +2601 -0
  86. sage/combinat/cluster_complex.py +326 -0
  87. sage/combinat/colored_permutations.py +2039 -0
  88. sage/combinat/colored_permutations_representations.py +964 -0
  89. sage/combinat/composition_signed.py +142 -0
  90. sage/combinat/composition_tableau.py +855 -0
  91. sage/combinat/constellation.py +1729 -0
  92. sage/combinat/core.py +751 -0
  93. sage/combinat/counting.py +12 -0
  94. sage/combinat/crystals/affine.py +742 -0
  95. sage/combinat/crystals/affine_factorization.py +518 -0
  96. sage/combinat/crystals/affinization.py +331 -0
  97. sage/combinat/crystals/alcove_path.py +2013 -0
  98. sage/combinat/crystals/all.py +22 -0
  99. sage/combinat/crystals/bkk_crystals.py +141 -0
  100. sage/combinat/crystals/catalog.py +115 -0
  101. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  102. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  103. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  104. sage/combinat/crystals/crystals.py +257 -0
  105. sage/combinat/crystals/direct_sum.py +260 -0
  106. sage/combinat/crystals/elementary_crystals.py +1251 -0
  107. sage/combinat/crystals/fast_crystals.py +441 -0
  108. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  109. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  110. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  111. sage/combinat/crystals/induced_structure.py +695 -0
  112. sage/combinat/crystals/infinity_crystals.py +730 -0
  113. sage/combinat/crystals/kac_modules.py +863 -0
  114. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  115. sage/combinat/crystals/kyoto_path_model.py +497 -0
  116. sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
  117. sage/combinat/crystals/letters.pxd +79 -0
  118. sage/combinat/crystals/letters.pyx +3056 -0
  119. sage/combinat/crystals/littelmann_path.py +1518 -0
  120. sage/combinat/crystals/monomial_crystals.py +1262 -0
  121. sage/combinat/crystals/multisegments.py +462 -0
  122. sage/combinat/crystals/mv_polytopes.py +467 -0
  123. sage/combinat/crystals/pbw_crystal.py +511 -0
  124. sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
  125. sage/combinat/crystals/pbw_datum.pxd +4 -0
  126. sage/combinat/crystals/pbw_datum.pyx +487 -0
  127. sage/combinat/crystals/polyhedral_realization.py +372 -0
  128. sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
  129. sage/combinat/crystals/spins.pxd +21 -0
  130. sage/combinat/crystals/spins.pyx +756 -0
  131. sage/combinat/crystals/star_crystal.py +290 -0
  132. sage/combinat/crystals/subcrystal.py +464 -0
  133. sage/combinat/crystals/tensor_product.py +1177 -0
  134. sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
  135. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  136. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  137. sage/combinat/crystals/virtual_crystal.py +420 -0
  138. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  139. sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
  140. sage/combinat/debruijn_sequence.pyx +355 -0
  141. sage/combinat/decorated_permutation.py +270 -0
  142. sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
  143. sage/combinat/degree_sequences.pyx +588 -0
  144. sage/combinat/derangements.py +527 -0
  145. sage/combinat/descent_algebra.py +1008 -0
  146. sage/combinat/diagram.py +1551 -0
  147. sage/combinat/diagram_algebras.py +5886 -0
  148. sage/combinat/dyck_word.py +4349 -0
  149. sage/combinat/e_one_star.py +1623 -0
  150. sage/combinat/enumerated_sets.py +123 -0
  151. sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
  152. sage/combinat/expnums.pyx +148 -0
  153. sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
  154. sage/combinat/fast_vector_partitions.pyx +346 -0
  155. sage/combinat/fqsym.py +1977 -0
  156. sage/combinat/free_dendriform_algebra.py +954 -0
  157. sage/combinat/free_prelie_algebra.py +1141 -0
  158. sage/combinat/fully_commutative_elements.py +1077 -0
  159. sage/combinat/fully_packed_loop.py +1523 -0
  160. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  161. sage/combinat/gray_codes.py +311 -0
  162. sage/combinat/grossman_larson_algebras.py +667 -0
  163. sage/combinat/growth.py +4352 -0
  164. sage/combinat/hall_polynomial.py +188 -0
  165. sage/combinat/hillman_grassl.py +866 -0
  166. sage/combinat/integer_matrices.py +329 -0
  167. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  168. sage/combinat/k_tableau.py +4564 -0
  169. sage/combinat/kazhdan_lusztig.py +215 -0
  170. sage/combinat/key_polynomial.py +885 -0
  171. sage/combinat/knutson_tao_puzzles.py +2286 -0
  172. sage/combinat/lr_tableau.py +311 -0
  173. sage/combinat/matrices/all.py +24 -0
  174. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  175. sage/combinat/matrices/latin.py +2912 -0
  176. sage/combinat/misc.py +401 -0
  177. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  178. sage/combinat/ncsf_qsym/all.py +21 -0
  179. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  180. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  181. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  182. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  183. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  184. sage/combinat/ncsym/all.py +21 -0
  185. sage/combinat/ncsym/bases.py +855 -0
  186. sage/combinat/ncsym/dual.py +593 -0
  187. sage/combinat/ncsym/ncsym.py +2076 -0
  188. sage/combinat/necklace.py +551 -0
  189. sage/combinat/non_decreasing_parking_function.py +634 -0
  190. sage/combinat/nu_dyck_word.py +1474 -0
  191. sage/combinat/output.py +861 -0
  192. sage/combinat/parallelogram_polyomino.py +4326 -0
  193. sage/combinat/parking_functions.py +1602 -0
  194. sage/combinat/partition_algebra.py +1998 -0
  195. sage/combinat/partition_kleshchev.py +1982 -0
  196. sage/combinat/partition_shifting_algebras.py +584 -0
  197. sage/combinat/partition_tuple.py +3114 -0
  198. sage/combinat/path_tableaux/all.py +13 -0
  199. sage/combinat/path_tableaux/catalog.py +29 -0
  200. sage/combinat/path_tableaux/dyck_path.py +380 -0
  201. sage/combinat/path_tableaux/frieze.py +476 -0
  202. sage/combinat/path_tableaux/path_tableau.py +728 -0
  203. sage/combinat/path_tableaux/semistandard.py +510 -0
  204. sage/combinat/perfect_matching.py +779 -0
  205. sage/combinat/plane_partition.py +3300 -0
  206. sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
  207. sage/combinat/q_bernoulli.pyx +128 -0
  208. sage/combinat/quickref.py +81 -0
  209. sage/combinat/recognizable_series.py +2051 -0
  210. sage/combinat/regular_sequence.py +4316 -0
  211. sage/combinat/regular_sequence_bounded.py +543 -0
  212. sage/combinat/restricted_growth.py +81 -0
  213. sage/combinat/ribbon.py +20 -0
  214. sage/combinat/ribbon_shaped_tableau.py +489 -0
  215. sage/combinat/ribbon_tableau.py +1180 -0
  216. sage/combinat/rigged_configurations/all.py +46 -0
  217. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  218. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  219. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  222. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  223. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  224. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  225. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  226. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  227. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  228. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  229. sage/combinat/rigged_configurations/bijection.py +143 -0
  230. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  231. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  232. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  233. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  234. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  235. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  236. sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  238. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  240. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  241. sage/combinat/rsk.py +3438 -0
  242. sage/combinat/schubert_polynomial.py +508 -0
  243. sage/combinat/set_partition.py +3318 -0
  244. sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
  245. sage/combinat/set_partition_iterator.pyx +136 -0
  246. sage/combinat/set_partition_ordered.py +1590 -0
  247. sage/combinat/sf/abreu_nigro.py +346 -0
  248. sage/combinat/sf/all.py +52 -0
  249. sage/combinat/sf/character.py +576 -0
  250. sage/combinat/sf/classical.py +319 -0
  251. sage/combinat/sf/dual.py +996 -0
  252. sage/combinat/sf/elementary.py +549 -0
  253. sage/combinat/sf/hall_littlewood.py +1028 -0
  254. sage/combinat/sf/hecke.py +336 -0
  255. sage/combinat/sf/homogeneous.py +464 -0
  256. sage/combinat/sf/jack.py +1428 -0
  257. sage/combinat/sf/k_dual.py +1458 -0
  258. sage/combinat/sf/kfpoly.py +447 -0
  259. sage/combinat/sf/llt.py +789 -0
  260. sage/combinat/sf/macdonald.py +2019 -0
  261. sage/combinat/sf/monomial.py +525 -0
  262. sage/combinat/sf/multiplicative.py +113 -0
  263. sage/combinat/sf/new_kschur.py +1786 -0
  264. sage/combinat/sf/ns_macdonald.py +964 -0
  265. sage/combinat/sf/orthogonal.py +246 -0
  266. sage/combinat/sf/orthotriang.py +355 -0
  267. sage/combinat/sf/powersum.py +963 -0
  268. sage/combinat/sf/schur.py +880 -0
  269. sage/combinat/sf/sf.py +1653 -0
  270. sage/combinat/sf/sfa.py +7053 -0
  271. sage/combinat/sf/symplectic.py +253 -0
  272. sage/combinat/sf/witt.py +721 -0
  273. sage/combinat/shifted_primed_tableau.py +2735 -0
  274. sage/combinat/shuffle.py +830 -0
  275. sage/combinat/sidon_sets.py +146 -0
  276. sage/combinat/similarity_class_type.py +1721 -0
  277. sage/combinat/sine_gordon.py +618 -0
  278. sage/combinat/six_vertex_model.py +784 -0
  279. sage/combinat/skew_partition.py +2053 -0
  280. sage/combinat/skew_tableau.py +2989 -0
  281. sage/combinat/sloane_functions.py +8935 -0
  282. sage/combinat/specht_module.py +1403 -0
  283. sage/combinat/species/all.py +48 -0
  284. sage/combinat/species/characteristic_species.py +321 -0
  285. sage/combinat/species/composition_species.py +273 -0
  286. sage/combinat/species/cycle_species.py +284 -0
  287. sage/combinat/species/empty_species.py +155 -0
  288. sage/combinat/species/functorial_composition_species.py +148 -0
  289. sage/combinat/species/generating_series.py +673 -0
  290. sage/combinat/species/library.py +148 -0
  291. sage/combinat/species/linear_order_species.py +169 -0
  292. sage/combinat/species/misc.py +83 -0
  293. sage/combinat/species/partition_species.py +290 -0
  294. sage/combinat/species/permutation_species.py +268 -0
  295. sage/combinat/species/product_species.py +423 -0
  296. sage/combinat/species/recursive_species.py +476 -0
  297. sage/combinat/species/set_species.py +192 -0
  298. sage/combinat/species/species.py +820 -0
  299. sage/combinat/species/structure.py +539 -0
  300. sage/combinat/species/subset_species.py +243 -0
  301. sage/combinat/species/sum_species.py +225 -0
  302. sage/combinat/subword.py +564 -0
  303. sage/combinat/subword_complex.py +2122 -0
  304. sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
  305. sage/combinat/subword_complex_c.pyx +119 -0
  306. sage/combinat/super_tableau.py +821 -0
  307. sage/combinat/superpartition.py +1154 -0
  308. sage/combinat/symmetric_group_algebra.py +3774 -0
  309. sage/combinat/symmetric_group_representations.py +1830 -0
  310. sage/combinat/t_sequences.py +877 -0
  311. sage/combinat/tableau.py +9506 -0
  312. sage/combinat/tableau_residues.py +860 -0
  313. sage/combinat/tableau_tuple.py +5353 -0
  314. sage/combinat/tiling.py +2432 -0
  315. sage/combinat/triangles_FHM.py +777 -0
  316. sage/combinat/tutorial.py +1857 -0
  317. sage/combinat/vector_partition.py +337 -0
  318. sage/combinat/words/abstract_word.py +1722 -0
  319. sage/combinat/words/all.py +59 -0
  320. sage/combinat/words/alphabet.py +268 -0
  321. sage/combinat/words/finite_word.py +7201 -0
  322. sage/combinat/words/infinite_word.py +113 -0
  323. sage/combinat/words/lyndon_word.py +652 -0
  324. sage/combinat/words/morphic.py +351 -0
  325. sage/combinat/words/morphism.py +3878 -0
  326. sage/combinat/words/paths.py +2932 -0
  327. sage/combinat/words/shuffle_product.py +278 -0
  328. sage/combinat/words/suffix_trees.py +1873 -0
  329. sage/combinat/words/word.py +769 -0
  330. sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
  331. sage/combinat/words/word_char.pyx +847 -0
  332. sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
  333. sage/combinat/words/word_datatypes.pxd +4 -0
  334. sage/combinat/words/word_datatypes.pyx +1067 -0
  335. sage/combinat/words/word_generators.py +2026 -0
  336. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  337. sage/combinat/words/word_options.py +99 -0
  338. sage/combinat/words/words.py +2396 -0
  339. sage/data_structures/all__sagemath_combinat.py +1 -0
  340. sage/databases/all__sagemath_combinat.py +13 -0
  341. sage/databases/findstat.py +4897 -0
  342. sage/databases/oeis.py +2058 -0
  343. sage/databases/sloane.py +393 -0
  344. sage/dynamics/all__sagemath_combinat.py +14 -0
  345. sage/dynamics/cellular_automata/all.py +7 -0
  346. sage/dynamics/cellular_automata/catalog.py +34 -0
  347. sage/dynamics/cellular_automata/elementary.py +612 -0
  348. sage/dynamics/cellular_automata/glca.py +477 -0
  349. sage/dynamics/cellular_automata/solitons.py +1463 -0
  350. sage/dynamics/finite_dynamical_system.py +1249 -0
  351. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  352. sage/games/all.py +7 -0
  353. sage/games/hexad.py +704 -0
  354. sage/games/quantumino.py +591 -0
  355. sage/games/sudoku.py +889 -0
  356. sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
  357. sage/games/sudoku_backtrack.pyx +189 -0
  358. sage/groups/all__sagemath_combinat.py +1 -0
  359. sage/groups/indexed_free_group.py +489 -0
  360. sage/libs/all__sagemath_combinat.py +6 -0
  361. sage/libs/lrcalc/__init__.py +1 -0
  362. sage/libs/lrcalc/lrcalc.py +525 -0
  363. sage/libs/symmetrica/__init__.py +7 -0
  364. sage/libs/symmetrica/all.py +101 -0
  365. sage/libs/symmetrica/kostka.pxi +168 -0
  366. sage/libs/symmetrica/part.pxi +193 -0
  367. sage/libs/symmetrica/plet.pxi +42 -0
  368. sage/libs/symmetrica/sab.pxi +196 -0
  369. sage/libs/symmetrica/sb.pxi +332 -0
  370. sage/libs/symmetrica/sc.pxi +192 -0
  371. sage/libs/symmetrica/schur.pxi +956 -0
  372. sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
  373. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  374. sage/libs/symmetrica/symmetrica.pyx +39 -0
  375. sage/monoids/all.py +13 -0
  376. sage/monoids/automatic_semigroup.py +1054 -0
  377. sage/monoids/free_abelian_monoid.py +315 -0
  378. sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
  379. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  380. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  381. sage/monoids/free_monoid.py +335 -0
  382. sage/monoids/free_monoid_element.py +431 -0
  383. sage/monoids/hecke_monoid.py +65 -0
  384. sage/monoids/string_monoid.py +817 -0
  385. sage/monoids/string_monoid_element.py +547 -0
  386. sage/monoids/string_ops.py +143 -0
  387. sage/monoids/trace_monoid.py +972 -0
  388. sage/rings/all__sagemath_combinat.py +2 -0
  389. sage/sat/all.py +4 -0
  390. sage/sat/boolean_polynomials.py +405 -0
  391. sage/sat/converters/__init__.py +6 -0
  392. sage/sat/converters/anf2cnf.py +14 -0
  393. sage/sat/converters/polybori.py +611 -0
  394. sage/sat/solvers/__init__.py +5 -0
  395. sage/sat/solvers/cryptominisat.py +287 -0
  396. sage/sat/solvers/dimacs.py +783 -0
  397. sage/sat/solvers/picosat.py +228 -0
  398. sage/sat/solvers/sat_lp.py +156 -0
  399. sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
  400. sage/sat/solvers/satsolver.pxd +3 -0
  401. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,2403 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.graphs sage.modules
3
+ r"""
4
+ Rigged configuration elements
5
+
6
+ A rigged configuration element is a sequence of
7
+ :class:`~sage.combinat.rigged_configurations.rigged_partition.RiggedPartition`
8
+ objects.
9
+
10
+ AUTHORS:
11
+
12
+ - Travis Scrimshaw (2010-09-26): initial version
13
+ - Travis Scrimshaw (2012-10-25): added virtual rigged configurations
14
+ """
15
+
16
+ # ****************************************************************************
17
+ # Copyright (C) 2010-2012 Travis Scrimshaw <tscrim@ucdavis.edu>
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
+ from sage.misc.cachefunc import cached_method
31
+ from sage.structure.list_clone import ClonableArray
32
+ from sage.rings.integer import Integer
33
+ from sage.rings.integer_ring import ZZ
34
+ from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition, RiggedPartitionTypeB
35
+
36
+
37
+ ####################################################
38
+ # Base classes for rigged configuration elements #
39
+ ####################################################
40
+
41
+ class RiggedConfigurationElement(ClonableArray):
42
+ """
43
+ A rigged configuration for simply-laced types.
44
+
45
+ For more information on rigged configurations, see
46
+ :class:`RiggedConfigurations`. For rigged configurations for
47
+ non-simply-laced types, use :class:`RCNonSimplyLacedElement`.
48
+
49
+ Typically to create a specific rigged configuration, the user will pass in
50
+ the optional argument ``partition_list`` and if the user wants to specify
51
+ the rigging values, give the optional argument ``rigging_list`` as well.
52
+ If ``rigging_list`` is not passed, the rigging values are set to the
53
+ corresponding vacancy numbers.
54
+
55
+ INPUT:
56
+
57
+ - ``parent`` -- the parent of this element
58
+
59
+ - ``rigged_partitions`` -- list of rigged partitions
60
+
61
+ There are two optional arguments to explicitly construct a rigged
62
+ configuration. The first is ``partition_list`` which gives a list of
63
+ partitions, and the second is ``rigging_list`` which is a list of
64
+ corresponding lists of riggings. If only partition_list is specified,
65
+ then it sets the rigging equal to the calculated vacancy numbers.
66
+
67
+ If we are constructing a rigged configuration from a rigged configuration
68
+ (say of another type) and we don't want to recompute the vacancy numbers,
69
+ we can use the ``use_vacancy_numbers`` to avoid the recomputation.
70
+
71
+ EXAMPLES:
72
+
73
+ Type `A_n^{(1)}` examples::
74
+
75
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
76
+ sage: RC(partition_list=[[2], [2, 2], [2], [2]])
77
+ <BLANKLINE>
78
+ 0[ ][ ]0
79
+ <BLANKLINE>
80
+ -2[ ][ ]-2
81
+ -2[ ][ ]-2
82
+ <BLANKLINE>
83
+ 2[ ][ ]2
84
+ <BLANKLINE>
85
+ -2[ ][ ]-2
86
+ <BLANKLINE>
87
+
88
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[1, 1], [1, 1]])
89
+ sage: RC(partition_list=[[], [], [], []])
90
+ <BLANKLINE>
91
+ (/)
92
+ <BLANKLINE>
93
+ (/)
94
+ <BLANKLINE>
95
+ (/)
96
+ <BLANKLINE>
97
+ (/)
98
+ <BLANKLINE>
99
+
100
+ Type `D_n^{(1)}` examples::
101
+
102
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
103
+ sage: RC(partition_list=[[3], [3,2], [4], [3]])
104
+ <BLANKLINE>
105
+ -1[ ][ ][ ]-1
106
+ <BLANKLINE>
107
+ 1[ ][ ][ ]1
108
+ 0[ ][ ]0
109
+ <BLANKLINE>
110
+ -3[ ][ ][ ][ ]-3
111
+ <BLANKLINE>
112
+ -1[ ][ ][ ]-1
113
+ <BLANKLINE>
114
+
115
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[1, 1], [2, 1]])
116
+ sage: RC(partition_list=[[1], [1,1], [1], [1]])
117
+ <BLANKLINE>
118
+ 1[ ]1
119
+ <BLANKLINE>
120
+ 0[ ]0
121
+ 0[ ]0
122
+ <BLANKLINE>
123
+ 0[ ]0
124
+ <BLANKLINE>
125
+ 0[ ]0
126
+ <BLANKLINE>
127
+ sage: elt = RC(partition_list=[[1], [1,1], [1], [1]], rigging_list=[[0], [0,0], [0], [0]]); elt
128
+ <BLANKLINE>
129
+ 1[ ]0
130
+ <BLANKLINE>
131
+ 0[ ]0
132
+ 0[ ]0
133
+ <BLANKLINE>
134
+ 0[ ]0
135
+ <BLANKLINE>
136
+ 0[ ]0
137
+ <BLANKLINE>
138
+
139
+ sage: from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition
140
+ sage: RC2 = RiggedConfigurations(['D', 5, 1], [[2, 1], [3, 1]])
141
+ sage: l = [RiggedPartition()] + list(elt)
142
+ sage: ascii_art(RC2(*l))
143
+ (/) 1[ ]0 0[ ]0 0[ ]0 0[ ]0
144
+ 0[ ]0
145
+ sage: ascii_art(RC2(*l, use_vacancy_numbers=True))
146
+ (/) 1[ ]0 0[ ]0 0[ ]0 0[ ]0
147
+ 0[ ]0
148
+ """
149
+
150
+ def __init__(self, parent, rigged_partitions=[], **options):
151
+ r"""
152
+ Construct a rigged configuration element.
153
+
154
+ .. WARNING::
155
+
156
+ This changes the vacancy numbers of the rigged partitions, so
157
+ if the rigged partitions comes from another rigged configuration,
158
+ a deep copy should be made before being passed here. We do not
159
+ make a deep copy here because the crystal operators generate
160
+ their own rigged partitions. See :issue:`17054`.
161
+
162
+ EXAMPLES::
163
+
164
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
165
+ sage: RC(partition_list=[[], [], [], []])
166
+ <BLANKLINE>
167
+ (/)
168
+ <BLANKLINE>
169
+ (/)
170
+ <BLANKLINE>
171
+ (/)
172
+ <BLANKLINE>
173
+ (/)
174
+ <BLANKLINE>
175
+ sage: RC(partition_list=[[1], [1], [], []])
176
+ <BLANKLINE>
177
+ -1[ ]-1
178
+ <BLANKLINE>
179
+ 0[ ]0
180
+ <BLANKLINE>
181
+ (/)
182
+ <BLANKLINE>
183
+ (/)
184
+ <BLANKLINE>
185
+ sage: elt = RC(partition_list=[[1], [1], [], []], rigging_list=[[-1], [0], [], []]); elt
186
+ <BLANKLINE>
187
+ -1[ ]-1
188
+ <BLANKLINE>
189
+ 0[ ]0
190
+ <BLANKLINE>
191
+ (/)
192
+ <BLANKLINE>
193
+ (/)
194
+ <BLANKLINE>
195
+ sage: TestSuite(elt).run()
196
+ """
197
+ n = options.get('n', parent._cartan_type.rank())
198
+ if "partition_list" in options:
199
+ data = options["partition_list"]
200
+ if len(data) == 0:
201
+ # Create a size n array of empty rigged tableau since no tableau
202
+ # were given
203
+ nu = [RiggedPartition() for _ in range(n)]
204
+ else:
205
+ if len(data) != n: # otherwise n should be equal to the number of tableaux
206
+ raise ValueError("incorrect number of partitions")
207
+
208
+ nu = []
209
+ if "rigging_list" in options:
210
+ rigging_data = options["rigging_list"]
211
+
212
+ if len(rigging_data) != n:
213
+ raise ValueError("incorrect number of riggings")
214
+
215
+ for i in range(n):
216
+ nu.append(RiggedPartition(tuple(data[i]),
217
+ list(rigging_data[i])))
218
+ else:
219
+ for partition_data in data:
220
+ nu.append(RiggedPartition(tuple(partition_data)))
221
+ elif n == len(rigged_partitions) and isinstance(rigged_partitions[0], RiggedPartition):
222
+ # The isinstance check is to make sure we are not in the n == 1 special case because
223
+ # Parent's __call__ always passes at least 1 argument to the element constructor
224
+
225
+ if options.get('use_vacancy_numbers', False):
226
+ ClonableArray.__init__(self, parent, rigged_partitions)
227
+ return
228
+ nu = rigged_partitions
229
+ else:
230
+ # Otherwise we did not receive any info, create a size n array of
231
+ # empty rigged partitions
232
+ nu = []
233
+ for i in range(n):
234
+ nu.append(RiggedPartition())
235
+ # raise ValueError("Invalid input")
236
+ # raise ValueError("Incorrect number of rigged partitions")
237
+
238
+ # Set the vacancy numbers
239
+ for a, partition in enumerate(nu):
240
+ # If the partition is empty, there's nothing to do
241
+ if len(partition) <= 0:
242
+ continue
243
+
244
+ # Setup the first block
245
+ block_len = partition[0]
246
+ vac_num = parent._calc_vacancy_number(nu, a, block_len)
247
+
248
+ for i, row_len in enumerate(partition):
249
+ # If we've gone to a different sized block, then update the
250
+ # values which change when moving to a new block size
251
+ if block_len != row_len:
252
+ vac_num = parent._calc_vacancy_number(nu, a, row_len)
253
+ block_len = row_len
254
+
255
+ partition.vacancy_numbers[i] = vac_num
256
+ if partition.rigging[i] is None:
257
+ partition.rigging[i] = partition.vacancy_numbers[i]
258
+
259
+ ClonableArray.__init__(self, parent, nu)
260
+
261
+ def check(self):
262
+ """
263
+ Check the rigged configuration is properly defined.
264
+
265
+ There is nothing to check here.
266
+
267
+ EXAMPLES::
268
+
269
+ sage: RC = crystals.infinity.RiggedConfigurations(['A', 4])
270
+ sage: b = RC.module_generators[0].f_string([1,2,1,1,2,4,2,3,3,2])
271
+ sage: b.check()
272
+ """
273
+ pass
274
+
275
+ def _repr_(self):
276
+ """
277
+ Return a string representation of ``self``.
278
+
279
+ EXAMPLES::
280
+
281
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
282
+ sage: elt = RC(partition_list=[[2], [3,1], [3], [3]]); elt
283
+ <BLANKLINE>
284
+ -1[ ][ ]-1
285
+ <BLANKLINE>
286
+ 2[ ][ ][ ]2
287
+ 0[ ]0
288
+ <BLANKLINE>
289
+ -2[ ][ ][ ]-2
290
+ <BLANKLINE>
291
+ -2[ ][ ][ ]-2
292
+ <BLANKLINE>
293
+ sage: RC.options(display='horizontal')
294
+ sage: elt
295
+ -1[ ][ ]-1 2[ ][ ][ ]2 -2[ ][ ][ ]-2 -2[ ][ ][ ]-2
296
+ 0[ ]0
297
+ sage: RC.options._reset()
298
+ """
299
+ return self.parent().options._dispatch(self, '_repr_', 'display')
300
+
301
+ def _repr_vertical(self):
302
+ """
303
+ Return the string representation of ``self`` vertically.
304
+
305
+ EXAMPLES::
306
+
307
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
308
+ sage: print(RC(partition_list=[[2], [3,1], [3], [3]])._repr_vertical())
309
+ <BLANKLINE>
310
+ -1[ ][ ]-1
311
+ <BLANKLINE>
312
+ 2[ ][ ][ ]2
313
+ 0[ ]0
314
+ <BLANKLINE>
315
+ -2[ ][ ][ ]-2
316
+ <BLANKLINE>
317
+ -2[ ][ ][ ]-2
318
+ <BLANKLINE>
319
+ sage: print(RC(partition_list=[[],[],[],[]])._repr_vertical())
320
+ <BLANKLINE>
321
+ (/)
322
+ <BLANKLINE>
323
+ (/)
324
+ <BLANKLINE>
325
+ (/)
326
+ <BLANKLINE>
327
+ (/)
328
+ <BLANKLINE>
329
+ """
330
+ ret_str = ""
331
+ for tableau in self:
332
+ ret_str += "\n" + repr(tableau)
333
+ return ret_str
334
+
335
+ def _repr_horizontal(self):
336
+ """
337
+ Return the string representation of ``self`` horizontally.
338
+
339
+ EXAMPLES::
340
+
341
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
342
+ sage: print(RC(partition_list=[[2], [3,1], [3], [3]])._repr_horizontal())
343
+ -1[ ][ ]-1 2[ ][ ][ ]2 -2[ ][ ][ ]-2 -2[ ][ ][ ]-2
344
+ 0[ ]0
345
+ sage: print(RC(partition_list=[[],[],[],[]])._repr_horizontal())
346
+ (/) (/) (/) (/)
347
+ """
348
+ tab_str = [repr(x).splitlines() for x in self]
349
+ height = max(len(t) for t in tab_str)
350
+ widths = [max(len(x) for x in t) for t in tab_str]
351
+ ret_str = ''
352
+ for i in range(height):
353
+ if i != 0:
354
+ ret_str += '\n'
355
+ for j,t in enumerate(tab_str):
356
+ if j != 0:
357
+ ret_str += ' '
358
+ if i < len(t):
359
+ ret_str += t[i] + ' ' * (widths[j]-len(t[i]))
360
+ else:
361
+ ret_str += ' ' * widths[j]
362
+ return ret_str
363
+
364
+ def _latex_(self):
365
+ r"""
366
+ Return the LaTeX representation of ``self``.
367
+
368
+ EXAMPLES::
369
+
370
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
371
+ sage: latex(RC(partition_list=[[2], [3,1], [3], [3]]))
372
+ {
373
+ \begin{array}[t]{r|c|c|l}
374
+ \cline{2-3} -1 &\phantom{|}&\phantom{|}& -1 \\
375
+ \cline{2-3}
376
+ \end{array}
377
+ }
378
+ \quad
379
+ {
380
+ \begin{array}[t]{r|c|c|c|l}
381
+ \cline{2-4} 2 &\phantom{|}&\phantom{|}&\phantom{|}& 2 \\
382
+ \cline{2-4} 0 &\phantom{|}& \multicolumn{3 }{l}{ 0 } \\
383
+ \cline{2-2}
384
+ \end{array}
385
+ }
386
+ \quad
387
+ {
388
+ \begin{array}[t]{r|c|c|c|l}
389
+ \cline{2-4} -2 &\phantom{|}&\phantom{|}&\phantom{|}& -2 \\
390
+ \cline{2-4}
391
+ \end{array}
392
+ }
393
+ \quad
394
+ {
395
+ \begin{array}[t]{r|c|c|c|l}
396
+ \cline{2-4} -2 &\phantom{|}&\phantom{|}&\phantom{|}& -2 \\
397
+ \cline{2-4}
398
+ \end{array}
399
+ }
400
+ sage: latex(RC(partition_list=[[],[],[],[]]))
401
+ {\emptyset}
402
+ \quad
403
+ {\emptyset}
404
+ \quad
405
+ {\emptyset}
406
+ \quad
407
+ {\emptyset}
408
+ """
409
+ ret_string = self[0]._latex_()
410
+
411
+ for partition in self[1:]:
412
+ ret_string += "\n\\quad\n" + partition._latex_()
413
+
414
+ return ret_string
415
+
416
+ def _ascii_art_(self):
417
+ """
418
+ Return an ASCII art representation of ``self``.
419
+
420
+ EXAMPLES::
421
+
422
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
423
+ sage: ascii_art(RC(partition_list=[[2], [3,1], [3], [3]]))
424
+ -1[ ][ ]-1 2[ ][ ][ ]2 -2[ ][ ][ ]-2 -2[ ][ ][ ]-2
425
+ 0[ ]0
426
+ sage: ascii_art(RC(partition_list=[[],[],[],[]]))
427
+ (/) (/) (/) (/)
428
+ sage: RC = RiggedConfigurations(['D', 7, 1], [[3,3],[5,2],[4,3],[2,3],[4,4],[3,1],[1,4],[2,2]])
429
+ sage: elt = RC(partition_list=[[2],[3,2,1],[2,2,1,1],[2,2,1,1,1,1],[3,2,1,1,1,1],[2,1,1],[2,2]],
430
+ ....: rigging_list=[[2],[1,0,0],[4,1,2,1],[1,0,0,0,0,0],[0,1,0,0,0,0],[0,0,0],[0,0]])
431
+ sage: ascii_art(elt)
432
+ 3[ ][ ]2 1[ ][ ][ ]1 4[ ][ ]4 2[ ][ ]1 0[ ][ ][ ]0 0[ ][ ]0 0[ ][ ]0
433
+ 2[ ][ ]0 4[ ][ ]1 2[ ][ ]0 2[ ][ ]1 0[ ]0 0[ ][ ]0
434
+ 1[ ]0 3[ ]2 0[ ]0 0[ ]0 0[ ]0
435
+ 3[ ]1 0[ ]0 0[ ]0
436
+ 0[ ]0 0[ ]0
437
+ 0[ ]0 0[ ]0
438
+ sage: Partitions.options(convention='French')
439
+ sage: ascii_art(elt)
440
+ 0[ ]0 0[ ]0
441
+ 0[ ]0 0[ ]0
442
+ 3[ ]1 0[ ]0 0[ ]0
443
+ 1[ ]0 3[ ]2 0[ ]0 0[ ]0 0[ ]0
444
+ 2[ ][ ]0 4[ ][ ]1 2[ ][ ]0 2[ ][ ]1 0[ ]0 0[ ][ ]0
445
+ 3[ ][ ]2 1[ ][ ][ ]1 4[ ][ ]4 2[ ][ ]1 0[ ][ ][ ]0 0[ ][ ]0 0[ ][ ]0
446
+ sage: Partitions.options._reset()
447
+ """
448
+ from sage.combinat.partition import Partitions
449
+ if Partitions.options.convention == "French":
450
+ baseline = lambda s: 0
451
+ else:
452
+ baseline = len
453
+ from sage.typeset.ascii_art import AsciiArt
454
+ s = repr(self[0]).splitlines()
455
+ ret = AsciiArt(s, baseline=baseline(s))
456
+ for tableau in self[1:]:
457
+ s = repr(tableau).splitlines()
458
+ ret += AsciiArt([" "], baseline=baseline(s)) + AsciiArt(s, baseline=baseline(s))
459
+ return ret
460
+
461
+ def nu(self):
462
+ r"""
463
+ Return the list `\nu` of rigged partitions of this rigged
464
+ configuration element.
465
+
466
+ OUTPUT: the `\nu` array as a list
467
+
468
+ EXAMPLES::
469
+
470
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
471
+ sage: RC(partition_list=[[2], [2,2], [2], [2]]).nu()
472
+ [0[ ][ ]0
473
+ , -2[ ][ ]-2
474
+ -2[ ][ ]-2
475
+ , 2[ ][ ]2
476
+ , -2[ ][ ]-2
477
+ ]
478
+ """
479
+ return list(self)
480
+
481
+ # TODO: Change e/f to work for all types
482
+ def e(self, a):
483
+ r"""
484
+ Return the action of the crystal operator `e_a` on ``self``.
485
+
486
+ This implements the method defined in [CrysStructSchilling06]_ which
487
+ finds the value `k` which is the length of the string with the
488
+ smallest negative rigging of smallest length. Then it removes a box
489
+ from a string of length `k` in the `a`-th rigged partition, keeping all
490
+ colabels fixed and increasing the new label by one. If no such string
491
+ exists, then `e_a` is undefined.
492
+
493
+ This method can also be used when the underlying Cartan matrix is a
494
+ Borcherds-Cartan matrix. In this case, then method of [SS2018]_ is
495
+ used, where the new label is increased by half of the `a`-th diagonal
496
+ entry of the underlying Borcherds-Cartan matrix. This method will also
497
+ return ``None`` if `a` is imaginary and the smallest rigging in the
498
+ `a`-th rigged partition is not exactly half of the `a`-th diagonal entry
499
+ of the Borcherds-Cartan matrix.
500
+
501
+ INPUT:
502
+
503
+ - ``a`` -- the index of the partition to remove a box
504
+
505
+ OUTPUT: the resulting rigged configuration element
506
+
507
+ EXAMPLES::
508
+
509
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
510
+ sage: elt = RC(partition_list=[[1], [1], [1], [1]])
511
+ sage: elt.e(3)
512
+ sage: elt.e(1)
513
+ <BLANKLINE>
514
+ (/)
515
+ <BLANKLINE>
516
+ 0[ ]0
517
+ <BLANKLINE>
518
+ 0[ ]0
519
+ <BLANKLINE>
520
+ -1[ ]-1
521
+ <BLANKLINE>
522
+
523
+ sage: A = CartanMatrix([[-2,-1],[-1,-2]], borcherds=True)
524
+ sage: RC = crystals.infinity.RiggedConfigurations(A)
525
+ sage: nu0 = RC(partition_list=[[],[]])
526
+ sage: nu = nu0.f_string([1,0,0,0])
527
+ sage: ascii_art(nu.e(0))
528
+ 5[ ]3 4[ ]3
529
+ 5[ ]1
530
+ """
531
+ if a not in self.parent()._rc_index_inverse:
532
+ raise ValueError("{} is not in the index set".format(a))
533
+ a = self.parent()._rc_index_inverse[a]
534
+ M = self.parent()._cartan_matrix
535
+
536
+ new_list = self[a][:]
537
+ new_vac_nums = self[a].vacancy_numbers[:]
538
+ new_rigging = self[a].rigging[:]
539
+
540
+ # Separate out one of the Borcherds cases
541
+ if M[a,a] != 2:
542
+ k = None
543
+ set_vac_num = True
544
+ if new_rigging[-1] != -M[a,a] // 2:
545
+ return None
546
+ new_list.pop()
547
+ new_vac_nums.pop()
548
+ new_rigging.pop()
549
+ else:
550
+ # Find k and perform e_a
551
+ k = None
552
+ num_rows = len(new_list)
553
+ cur_rigging = -1
554
+ rigging_index = None
555
+ for i in range(num_rows):
556
+ if new_rigging[i] <= cur_rigging:
557
+ cur_rigging = new_rigging[i]
558
+ rigging_index = i
559
+
560
+ # If we've not found a valid k
561
+ if rigging_index is None:
562
+ return None
563
+
564
+ # Note that because the riggings are weakly decreasing, we will always
565
+ # remove the last box on of a block
566
+ k = new_list[rigging_index]
567
+ set_vac_num = False
568
+ if k == 1:
569
+ new_list.pop()
570
+ new_vac_nums.pop()
571
+ new_rigging.pop()
572
+ else:
573
+ new_list[rigging_index] -= 1
574
+ cur_rigging += M[a,a] // 2
575
+ # Properly sort the riggings
576
+ j = rigging_index + 1
577
+ # Update the vacancy number if the row lengths are the same
578
+ if j < num_rows and new_list[j] == new_list[rigging_index]:
579
+ new_vac_nums[rigging_index] = new_vac_nums[j]
580
+ set_vac_num = True
581
+ while j < num_rows and new_list[j] == new_list[rigging_index] \
582
+ and new_rigging[j] > cur_rigging:
583
+ new_rigging[j-1] = new_rigging[j] # Shuffle it along
584
+ j += 1
585
+ new_rigging[j-1] = cur_rigging
586
+
587
+ new_partitions = []
588
+ for b in range(len(self)):
589
+ if b != a:
590
+ new_partitions.append(self._generate_partition_e(a, b, k))
591
+ else:
592
+ # Update the vacancy numbers and the rigging
593
+ for i in range(len(new_vac_nums)):
594
+ if k is not None and new_list[i] < k:
595
+ break
596
+
597
+ new_vac_nums[i] += M[a,b]
598
+ new_rigging[i] += M[a,b]
599
+
600
+ if k != 1 and not set_vac_num: # If we did not remove a row nor found another row of length k-1
601
+ new_vac_nums[rigging_index] += 2
602
+
603
+ new_partitions.append(RiggedPartition(new_list, new_rigging, new_vac_nums))
604
+
605
+ ret_RC = self.__class__(self.parent(), new_partitions, use_vacancy_numbers=True)
606
+ nu = ret_RC.nu()
607
+ if k != 1 and not set_vac_num: # If we did not remove a row nor found another row of length k-1
608
+ # Update that row's vacancy number
609
+ ret_RC[a].vacancy_numbers[rigging_index] = \
610
+ self.parent()._calc_vacancy_number(nu, a, nu[a][rigging_index])
611
+ return ret_RC
612
+
613
+ def _generate_partition_e(self, a, b, k):
614
+ r"""
615
+ Generate a new partition for a given value of `a` by updating the
616
+ vacancy numbers and preserving co-labels for the map `e_a`.
617
+
618
+ INPUT:
619
+
620
+ - ``a`` -- the index of the partition we operated on
621
+ - ``b`` -- the index of the partition to generate
622
+ - ``k`` -- the length of the string with the smallest negative
623
+ rigging of smallest length
624
+
625
+ OUTPUT: the constructed rigged partition
626
+
627
+ TESTS::
628
+
629
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
630
+ sage: RC(partition_list=[[1], [1], [1], [1]])._generate_partition_e(1, 2, 1)
631
+ -1[ ]-1
632
+ <BLANKLINE>
633
+ """
634
+ # Check to make sure we will do something
635
+ if not self.parent()._cartan_matrix[a,b]:
636
+ return self[b]
637
+
638
+ new_list = self[b]._list
639
+ new_vac_nums = self[b].vacancy_numbers[:]
640
+ new_rigging = self[b].rigging[:]
641
+
642
+ # Update the vacancy numbers and the rigging
643
+ value = self.parent()._cartan_matrix[b,a]
644
+ for i in range(len(new_vac_nums)):
645
+ if k is not None and new_list[i] < k:
646
+ break
647
+
648
+ new_vac_nums[i] += value
649
+ new_rigging[i] += value
650
+
651
+ return RiggedPartition(new_list, new_rigging, new_vac_nums)
652
+
653
+ def f(self, a):
654
+ r"""
655
+ Return the action of the crystal operator `f_a` on ``self``.
656
+
657
+ This implements the method defined in [CrysStructSchilling06]_ which
658
+ finds the value `k` which is the length of the string with the
659
+ smallest nonpositive rigging of largest length. Then it adds a box from
660
+ a string of length `k` in the `a`-th rigged partition, keeping all
661
+ colabels fixed and decreasing the new label by one. If no such string
662
+ exists, then it adds a new string of length 1 with label `-1`. However
663
+ we need to modify the definition to work for `B(\infty)` by removing
664
+ the condition that the resulting rigged configuration is valid.
665
+
666
+ This method can also be used when the underlying Cartan matrix is a
667
+ Borcherds-Cartan matrix. In this case, then method of [SS2018]_ is
668
+ used, where the new label is decreased by half of the `a`-th diagonal
669
+ entry of the underlying Borcherds-Cartan matrix.
670
+
671
+ INPUT:
672
+
673
+ - ``a`` -- the index of the partition to add a box
674
+
675
+ OUTPUT: the resulting rigged configuration element
676
+
677
+ EXAMPLES::
678
+
679
+ sage: RC = crystals.infinity.RiggedConfigurations(['A', 3])
680
+ sage: nu0 = RC.module_generators[0]
681
+ sage: nu0.f(2)
682
+ <BLANKLINE>
683
+ (/)
684
+ <BLANKLINE>
685
+ -2[ ]-1
686
+ <BLANKLINE>
687
+ (/)
688
+ <BLANKLINE>
689
+
690
+ sage: A = CartanMatrix([[-2,-1],[-1,-2]], borcherds=True)
691
+ sage: RC = crystals.infinity.RiggedConfigurations(A)
692
+ sage: nu0 = RC(partition_list=[[],[]])
693
+ sage: nu = nu0.f_string([1,0,0,0])
694
+ sage: ascii_art(nu.f(0))
695
+ 9[ ]7 6[ ]5
696
+ 9[ ]5
697
+ 9[ ]3
698
+ 9[ ]1
699
+ """
700
+ if a not in self.parent()._rc_index_inverse:
701
+ raise ValueError("{} is not in the index set".format(a))
702
+ a = self.parent()._rc_index_inverse[a]
703
+ M = self.parent()._cartan_matrix
704
+
705
+ new_list = self[a][:]
706
+ new_vac_nums = self[a].vacancy_numbers[:]
707
+ new_rigging = self[a].rigging[:]
708
+
709
+ # Find k and perform f_a
710
+ k = None
711
+ add_index = -1 # Index where we will add our row too
712
+ rigging_index = None # Index which we will pull the rigging from
713
+ cur_rigging = ZZ.zero()
714
+ num_rows = len(new_list)
715
+ for i in reversed(range(num_rows)):
716
+ # If we need to increment a row, look for when we change rows for
717
+ # the correct index.
718
+ if add_index is None and new_list[i] != new_list[rigging_index]:
719
+ add_index = i+1
720
+
721
+ if new_rigging[i] <= cur_rigging:
722
+ cur_rigging = new_rigging[i]
723
+ k = new_list[i]
724
+ rigging_index = i
725
+ add_index = None
726
+
727
+ # If we've not found a valid k
728
+ if k is None:
729
+ new_list.append(1)
730
+ new_rigging.append(-M[a,a] // 2)
731
+ new_vac_nums.append(None)
732
+ k = 0
733
+ add_index = num_rows
734
+ num_rows += 1 # We've added a row
735
+ else:
736
+ if add_index is None: # We are adding to the first row in the list
737
+ add_index = 0
738
+ new_list[add_index] += 1
739
+ new_rigging.insert(add_index, new_rigging[rigging_index] - M[a,a] // 2)
740
+ new_vac_nums.insert(add_index, None)
741
+ new_rigging.pop(rigging_index + 1) # add 1 for the insertion
742
+ new_vac_nums.pop(rigging_index + 1)
743
+
744
+ new_partitions = []
745
+ for b in range(len(self)):
746
+ if b != a:
747
+ new_partitions.append(self._generate_partition_f(a, b, k))
748
+ else:
749
+ # Update the vacancy numbers and the rigging
750
+ for i in range(num_rows):
751
+ if new_list[i] <= k:
752
+ break
753
+
754
+ if i != add_index:
755
+ new_vac_nums[i] -= M[a,b]
756
+ new_rigging[i] -= M[a,b]
757
+
758
+ new_partitions.append(RiggedPartition(new_list, new_rigging, new_vac_nums))
759
+
760
+ new_partitions[a].vacancy_numbers[add_index] = \
761
+ self.parent()._calc_vacancy_number(new_partitions, a,
762
+ new_partitions[a][add_index])
763
+
764
+ # Note that we do not need to sort the rigging since if there was a
765
+ # smaller rigging in a larger row, then `k` would be larger.
766
+ return self.__class__(self.parent(), new_partitions, use_vacancy_numbers=True)
767
+
768
+ def _generate_partition_f(self, a, b, k):
769
+ r"""
770
+ Generate a new partition for a given value of `a` by updating the
771
+ vacancy numbers and preserving co-labels for the map `f_a`.
772
+
773
+ INPUT:
774
+
775
+ - ``a`` -- the index of the partition we operated on
776
+ - ``b`` -- the index of the partition to generate
777
+ - ``k`` -- the length of the string with smallest nonpositive rigging
778
+ of largest length
779
+
780
+ OUTPUT: the constructed rigged partition
781
+
782
+ TESTS::
783
+
784
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
785
+ sage: RC(partition_list=[[1], [1], [1], [1]])._generate_partition_f(1, 2, 1)
786
+ 0[ ]0
787
+ <BLANKLINE>
788
+ """
789
+ # Check to make sure we will do something
790
+ if not self.parent()._cartan_matrix[a,b]:
791
+ return self[b]
792
+
793
+ new_list = self[b]._list
794
+ new_vac_nums = self[b].vacancy_numbers[:]
795
+ new_rigging = self[b].rigging[:]
796
+
797
+ # Update the vacancy numbers and the rigging
798
+ value = self.parent()._cartan_matrix[b,a]
799
+ for i in range(len(new_vac_nums)):
800
+ if new_list[i] <= k:
801
+ break
802
+
803
+ new_vac_nums[i] -= value
804
+ new_rigging[i] -= value
805
+
806
+ return RiggedPartition(new_list, new_rigging, new_vac_nums)
807
+
808
+ def epsilon(self, a):
809
+ r"""
810
+ Return `\varepsilon_a` of ``self``.
811
+
812
+ Let `x_{\ell}` be the smallest string of `\nu^{(a)}` or `0` if
813
+ `\nu^{(a)} = \emptyset`, then we have
814
+ `\varepsilon_a = -\min(0, x_{\ell})`.
815
+
816
+ EXAMPLES::
817
+
818
+ sage: La = RootSystem(['B',2]).weight_lattice().fundamental_weights()
819
+ sage: RC = crystals.RiggedConfigurations(La[1]+La[2])
820
+ sage: I = RC.index_set()
821
+ sage: matrix([[rc.epsilon(i) for i in I] for rc in RC[:4]])
822
+ [0 0]
823
+ [1 0]
824
+ [0 1]
825
+ [0 2]
826
+ """
827
+ a = self.parent()._rc_index_inverse[a]
828
+ if not self[a]:
829
+ return ZZ.zero()
830
+ return Integer(-min(0, *self[a].rigging))
831
+
832
+ def phi(self, a):
833
+ r"""
834
+ Return `\varphi_a` of ``self``.
835
+
836
+ Let `x_{\ell}` be the smallest string of `\nu^{(a)}` or `0` if
837
+ `\nu^{(a)} = \emptyset`, then we have
838
+ `\varepsilon_a = p_{\infty}^{(a)} - \min(0, x_{\ell})`.
839
+
840
+ EXAMPLES::
841
+
842
+ sage: La = RootSystem(['B',2]).weight_lattice().fundamental_weights()
843
+ sage: RC = crystals.RiggedConfigurations(La[1]+La[2])
844
+ sage: I = RC.index_set()
845
+ sage: matrix([[rc.phi(i) for i in I] for rc in RC[:4]])
846
+ [1 1]
847
+ [0 3]
848
+ [0 2]
849
+ [1 1]
850
+ """
851
+ a = self.parent()._rc_index_inverse[a]
852
+ p_inf = self.parent()._calc_vacancy_number(self, a, float("inf"))
853
+ if not self[a]:
854
+ return Integer(p_inf)
855
+ return Integer(p_inf - min(0, *self[a].rigging))
856
+
857
+ def vacancy_number(self, a, i):
858
+ r"""
859
+ Return the vacancy number `p_i^{(a)}`.
860
+
861
+ INPUT:
862
+
863
+ - ``a`` -- the index of the rigged partition
864
+
865
+ - ``i`` -- the row of the rigged partition
866
+
867
+ EXAMPLES::
868
+
869
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
870
+ sage: elt = RC(partition_list=[[1], [2,1], [1], []])
871
+ sage: elt.vacancy_number(2, 3)
872
+ -2
873
+ sage: elt.vacancy_number(2, 2)
874
+ -2
875
+ sage: elt.vacancy_number(2, 1)
876
+ -1
877
+
878
+ sage: RC = RiggedConfigurations(['D',4,1], [[2,1], [2,1]])
879
+ sage: x = RC(partition_list=[[3], [3,1,1], [2], [3,1]]); ascii_art(x)
880
+ -1[ ][ ][ ]-1 1[ ][ ][ ]1 0[ ][ ]0 -3[ ][ ][ ]-3
881
+ 0[ ]0 -1[ ]-1
882
+ 0[ ]0
883
+ sage: x.vacancy_number(2,2)
884
+ 1
885
+ """
886
+ a = self.parent()._rc_index_inverse[a]
887
+ return self.parent()._calc_vacancy_number(self, a, i)
888
+
889
+ def partition_rigging_lists(self):
890
+ """
891
+ Return the list of partitions and the associated list of riggings
892
+ of ``self``.
893
+
894
+ EXAMPLES::
895
+
896
+ sage: RC = RiggedConfigurations(['A',3,1], [[1,2],[2,2]])
897
+ sage: rc = RC(partition_list=[[2],[1],[1]], rigging_list=[[-1],[0],[-1]]); rc
898
+ <BLANKLINE>
899
+ -1[ ][ ]-1
900
+ <BLANKLINE>
901
+ 1[ ]0
902
+ <BLANKLINE>
903
+ -1[ ]-1
904
+ <BLANKLINE>
905
+ sage: rc.partition_rigging_lists()
906
+ [[[2], [1], [1]], [[-1], [0], [-1]]]
907
+ """
908
+ partitions = []
909
+ riggings = []
910
+ for p in self:
911
+ partitions.append(list(p))
912
+ riggings.append(list(p.rigging))
913
+ return [partitions, riggings]
914
+
915
+
916
+ class RCNonSimplyLacedElement(RiggedConfigurationElement):
917
+ """
918
+ Rigged configuration elements for non-simply-laced types.
919
+
920
+ TESTS::
921
+
922
+ sage: vct = CartanType(['C',2,1]).as_folding()
923
+ sage: RC = crystals.infinity.RiggedConfigurations(vct)
924
+ sage: elt = RC.module_generators[0].f_string([1,0,2,2,0,1]); elt
925
+ <BLANKLINE>
926
+ -2[ ][ ]-1
927
+ <BLANKLINE>
928
+ -2[ ]-1
929
+ -2[ ]-1
930
+ <BLANKLINE>
931
+ -2[ ][ ]-1
932
+ <BLANKLINE>
933
+ sage: TestSuite(elt).run()
934
+ """
935
+
936
+ def to_virtual_configuration(self):
937
+ """
938
+ Return the corresponding rigged configuration in the virtual crystal.
939
+
940
+ EXAMPLES::
941
+
942
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
943
+ sage: elt = RC(partition_list=[[3],[2]]); elt
944
+ <BLANKLINE>
945
+ 0[ ][ ][ ]0
946
+ <BLANKLINE>
947
+ 0[ ][ ]0
948
+ sage: elt.to_virtual_configuration()
949
+ <BLANKLINE>
950
+ 0[ ][ ][ ]0
951
+ <BLANKLINE>
952
+ 0[ ][ ][ ][ ]0
953
+ <BLANKLINE>
954
+ 0[ ][ ][ ]0
955
+ """
956
+ return self.parent().to_virtual(self)
957
+
958
+ def e(self, a):
959
+ r"""
960
+ Return the action of `e_a` on ``self``.
961
+
962
+ This works by lifting into the virtual configuration, then applying
963
+
964
+ .. MATH::
965
+
966
+ e^v_a = \prod_{j \in \iota(a)} \hat{e}_j^{\gamma_j}
967
+
968
+ and pulling back.
969
+
970
+ EXAMPLES::
971
+
972
+ sage: vct = CartanType(['C',2,1]).as_folding()
973
+ sage: RC = crystals.infinity.RiggedConfigurations(vct)
974
+ sage: elt = RC(partition_list=[[2],[1,1],[2]], rigging_list=[[-1],[-1,-1],[-1]])
975
+ sage: ascii_art(elt.e(0))
976
+ 0[ ]0 -2[ ]-1 -2[ ][ ]-1
977
+ -2[ ]-1
978
+ sage: ascii_art(elt.e(1))
979
+ -3[ ][ ]-2 0[ ]1 -3[ ][ ]-2
980
+ sage: ascii_art(elt.e(2))
981
+ -2[ ][ ]-1 -2[ ]-1 0[ ]0
982
+ -2[ ]-1
983
+ """
984
+ vct = self.parent()._folded_ct
985
+ L = []
986
+ gamma = vct.scaling_factors()
987
+ for i in vct.folding_orbit()[a]:
988
+ L.extend([i]*gamma[a])
989
+ virtual_rc = self.parent().to_virtual(self).e_string(L)
990
+ if virtual_rc is None:
991
+ return None
992
+ return self.parent().from_virtual(virtual_rc)
993
+
994
+ def f(self, a):
995
+ r"""
996
+ Return the action of `f_a` on ``self``.
997
+
998
+ This works by lifting into the virtual configuration, then applying
999
+
1000
+ .. MATH::
1001
+
1002
+ f^v_a = \prod_{j \in \iota(a)} \hat{f}_j^{\gamma_j}
1003
+
1004
+ and pulling back.
1005
+
1006
+ EXAMPLES::
1007
+
1008
+ sage: vct = CartanType(['C',2,1]).as_folding()
1009
+ sage: RC = crystals.infinity.RiggedConfigurations(vct)
1010
+ sage: elt = RC(partition_list=[[2],[1,1],[2]], rigging_list=[[-1],[-1,-1],[-1]])
1011
+ sage: ascii_art(elt.f(0))
1012
+ -4[ ][ ][ ]-2 -2[ ]-1 -2[ ][ ]-1
1013
+ -2[ ]-1
1014
+ sage: ascii_art(elt.f(1))
1015
+ -1[ ][ ]0 -2[ ][ ]-2 -1[ ][ ]0
1016
+ -2[ ]-1
1017
+ sage: ascii_art(elt.f(2))
1018
+ -2[ ][ ]-1 -2[ ]-1 -4[ ][ ][ ]-2
1019
+ -2[ ]-1
1020
+ """
1021
+ vct = self.parent()._folded_ct
1022
+ L = []
1023
+ gamma = vct.scaling_factors()
1024
+ for i in vct.folding_orbit()[a]:
1025
+ L.extend([i]*gamma[a])
1026
+ virtual_rc = self.parent().to_virtual(self).f_string(L)
1027
+ if virtual_rc is None:
1028
+ return None
1029
+ return self.parent().from_virtual(virtual_rc)
1030
+
1031
+ ##########################################################
1032
+ # Highest weight crystal rigged configuration elements #
1033
+ ##########################################################
1034
+
1035
+
1036
+ class RCHighestWeightElement(RiggedConfigurationElement):
1037
+ """
1038
+ Rigged configurations in highest weight crystals.
1039
+
1040
+ TESTS::
1041
+
1042
+ sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
1043
+ sage: RC = crystals.RiggedConfigurations(['A',2,1], La[0])
1044
+ sage: elt = RC(partition_list=[[1,1],[1],[2]]); elt
1045
+ <BLANKLINE>
1046
+ -1[ ]-1
1047
+ -1[ ]-1
1048
+ <BLANKLINE>
1049
+ 1[ ]1
1050
+ <BLANKLINE>
1051
+ -1[ ][ ]-1
1052
+ <BLANKLINE>
1053
+ sage: TestSuite(elt).run()
1054
+ """
1055
+
1056
+ def check(self):
1057
+ """
1058
+ Make sure all of the riggings are less than or equal to the
1059
+ vacancy number.
1060
+
1061
+ TESTS::
1062
+
1063
+ sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
1064
+ sage: RC = crystals.RiggedConfigurations(['A',2,1], La[0])
1065
+ sage: elt = RC(partition_list=[[1,1],[1],[2]])
1066
+ sage: elt.check()
1067
+ """
1068
+ for a, partition in enumerate(self):
1069
+ for i, vac_num in enumerate(partition.vacancy_numbers):
1070
+ if vac_num < partition.rigging[i]:
1071
+ raise ValueError("rigging can be at most the vacancy number")
1072
+
1073
+ def f(self, a):
1074
+ r"""
1075
+ Return the action of the crystal operator `f_a` on ``self``.
1076
+
1077
+ This implements the method defined in [CrysStructSchilling06]_ which
1078
+ finds the value `k` which is the length of the string with the
1079
+ smallest nonpositive rigging of largest length. Then it adds a box
1080
+ from a string of length `k` in the `a`-th rigged partition, keeping
1081
+ all colabels fixed and decreasing the new label by one. If no such
1082
+ string exists, then it adds a new string of length 1 with label `-1`.
1083
+ If any of the resulting vacancy numbers are larger than the labels
1084
+ (i.e. it is an invalid rigged configuration), then `f_a` is
1085
+ undefined.
1086
+
1087
+ INPUT:
1088
+
1089
+ - ``a`` -- the index of the partition to add a box
1090
+
1091
+ OUTPUT: the resulting rigged configuration element
1092
+
1093
+ EXAMPLES::
1094
+
1095
+ sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
1096
+ sage: RC = crystals.RiggedConfigurations(['A',2,1], La[0])
1097
+ sage: elt = RC(partition_list=[[1,1],[1],[2]])
1098
+ sage: elt.f(0)
1099
+ <BLANKLINE>
1100
+ -2[ ][ ]-2
1101
+ -1[ ]-1
1102
+ <BLANKLINE>
1103
+ 1[ ]1
1104
+ <BLANKLINE>
1105
+ 0[ ][ ]0
1106
+ <BLANKLINE>
1107
+ sage: elt.f(1)
1108
+ <BLANKLINE>
1109
+ 0[ ]0
1110
+ 0[ ]0
1111
+ <BLANKLINE>
1112
+ -1[ ]-1
1113
+ -1[ ]-1
1114
+ <BLANKLINE>
1115
+ 0[ ][ ]0
1116
+ <BLANKLINE>
1117
+ sage: elt.f(2)
1118
+ """
1119
+ if not self.phi(a):
1120
+ return None
1121
+ return RiggedConfigurationElement.f(self, a)
1122
+
1123
+ def weight(self):
1124
+ """
1125
+ Return the weight of ``self``.
1126
+
1127
+ EXAMPLES::
1128
+
1129
+ sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
1130
+ sage: B = crystals.RiggedConfigurations(['A',2,1], La[0])
1131
+ sage: mg = B.module_generators[0]
1132
+ sage: mg.f_string([0,1,2,0]).weight()
1133
+ -Lambda[0] + Lambda[1] + Lambda[2] - 2*delta
1134
+ """
1135
+ P = self.parent().weight_lattice_realization()
1136
+ alpha = list(P.simple_roots())
1137
+ return self.parent()._wt - sum(sum(x) * alpha[i] for i,x in enumerate(self))
1138
+
1139
+
1140
+ class RCHWNonSimplyLacedElement(RCNonSimplyLacedElement):
1141
+ """
1142
+ Rigged configurations in highest weight crystals.
1143
+
1144
+ TESTS::
1145
+
1146
+ sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
1147
+ sage: vct = CartanType(['C',2,1]).as_folding()
1148
+ sage: RC = crystals.RiggedConfigurations(vct, La[0])
1149
+ sage: elt = RC(partition_list=[[1,1],[2],[2]]); ascii_art(elt)
1150
+ -1[ ]-1 2[ ][ ]2 -2[ ][ ]-2
1151
+ -1[ ]-1
1152
+ sage: TestSuite(elt).run()
1153
+ """
1154
+
1155
+ def check(self):
1156
+ """
1157
+ Make sure all of the riggings are less than or equal to the
1158
+ vacancy number.
1159
+
1160
+ TESTS::
1161
+
1162
+ sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
1163
+ sage: vct = CartanType(['C',2,1]).as_folding()
1164
+ sage: RC = crystals.RiggedConfigurations(vct, La[0])
1165
+ sage: elt = RC(partition_list=[[1,1],[2],[2]])
1166
+ sage: elt.check()
1167
+ """
1168
+ for partition in self:
1169
+ for i, vac_num in enumerate(partition.vacancy_numbers):
1170
+ if vac_num < partition.rigging[i]:
1171
+ raise ValueError("rigging can be at most the vacancy number")
1172
+
1173
+ def f(self, a):
1174
+ r"""
1175
+ Return the action of `f_a` on ``self``.
1176
+
1177
+ This works by lifting into the virtual configuration, then applying
1178
+
1179
+ .. MATH::
1180
+
1181
+ f^v_a = \prod_{j \in \iota(a)} \hat{f}_j^{\gamma_j}
1182
+
1183
+ and pulling back.
1184
+
1185
+ EXAMPLES::
1186
+
1187
+ sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
1188
+ sage: vct = CartanType(['C',2,1]).as_folding()
1189
+ sage: RC = crystals.RiggedConfigurations(vct, La[0])
1190
+ sage: elt = RC(partition_list=[[1,1],[2],[2]])
1191
+ sage: elt.f(0)
1192
+ sage: ascii_art(elt.f(1))
1193
+ 0[ ]0 0[ ][ ]0 -1[ ][ ]-1
1194
+ 0[ ]0 -1[ ]-1
1195
+ sage: elt.f(2)
1196
+ """
1197
+ if not self.phi(a):
1198
+ return None
1199
+ return RCNonSimplyLacedElement.f(self, a)
1200
+
1201
+ # FIXME: Do not duplicate with the simply-laced HW RC element class
1202
+ def weight(self):
1203
+ """
1204
+ Return the weight of ``self``.
1205
+
1206
+ EXAMPLES::
1207
+
1208
+ sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
1209
+ sage: vct = CartanType(['C',2,1]).as_folding()
1210
+ sage: B = crystals.RiggedConfigurations(vct, La[0])
1211
+ sage: mg = B.module_generators[0]
1212
+ sage: mg.f_string([0,1,2]).weight()
1213
+ 2*Lambda[1] - Lambda[2] - delta
1214
+ """
1215
+ P = self.parent().weight_lattice_realization()
1216
+ alpha = list(P.simple_roots())
1217
+ return self.parent()._wt - sum(sum(x) * alpha[i] for i,x in enumerate(self))
1218
+
1219
+ ##############################################
1220
+ # KR crystal rigged configuration elements #
1221
+ ##############################################
1222
+
1223
+
1224
+ class KRRiggedConfigurationElement(RiggedConfigurationElement):
1225
+ r"""
1226
+ `U_q^{\prime}(\mathfrak{g})` rigged configurations.
1227
+
1228
+ EXAMPLES:
1229
+
1230
+ We can go between :class:`rigged configurations <RiggedConfigurations>`
1231
+ and tensor products of :class:`tensor products of KR tableaux
1232
+ <sage.combinat.rigged_configurations.tensor_product_kr_tableaux.TensorProductOfKirillovReshetikhinTableaux>`::
1233
+
1234
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[1,1], [2,1]])
1235
+ sage: rc_elt = RC(partition_list=[[1], [1,1], [1], [1]])
1236
+ sage: tp_krtab = rc_elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); tp_krtab
1237
+ [[-2]] (X) [[1], [2]]
1238
+ sage: tp_krcrys = rc_elt.to_tensor_product_of_kirillov_reshetikhin_crystals(); tp_krcrys
1239
+ [[[-2]], [[1], [2]]]
1240
+ sage: tp_krcrys == tp_krtab.to_tensor_product_of_kirillov_reshetikhin_crystals()
1241
+ True
1242
+ sage: RC(tp_krcrys) == rc_elt
1243
+ True
1244
+ sage: RC(tp_krtab) == rc_elt
1245
+ True
1246
+ sage: tp_krtab.to_rigged_configuration() == rc_elt
1247
+ True
1248
+ """
1249
+
1250
+ def __init__(self, parent, rigged_partitions=[], **options):
1251
+ r"""
1252
+ Construct a rigged configuration element.
1253
+
1254
+ EXAMPLES::
1255
+
1256
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
1257
+ sage: RC(partition_list=[[], [], [], []])
1258
+ <BLANKLINE>
1259
+ (/)
1260
+ <BLANKLINE>
1261
+ (/)
1262
+ <BLANKLINE>
1263
+ (/)
1264
+ <BLANKLINE>
1265
+ (/)
1266
+ <BLANKLINE>
1267
+ sage: RC(partition_list=[[1], [1], [], []])
1268
+ <BLANKLINE>
1269
+ -1[ ]-1
1270
+ <BLANKLINE>
1271
+ 0[ ]0
1272
+ <BLANKLINE>
1273
+ (/)
1274
+ <BLANKLINE>
1275
+ (/)
1276
+ <BLANKLINE>
1277
+ sage: elt = RC(partition_list=[[1], [1], [], []], rigging_list=[[-1], [0], [], []]); elt
1278
+ <BLANKLINE>
1279
+ -1[ ]-1
1280
+ <BLANKLINE>
1281
+ 0[ ]0
1282
+ <BLANKLINE>
1283
+ (/)
1284
+ <BLANKLINE>
1285
+ (/)
1286
+ <BLANKLINE>
1287
+ sage: TestSuite(elt).run()
1288
+ """
1289
+ n = len(parent._rc_index)
1290
+ if "KT_constructor" in options:
1291
+ # Used only by the Kleber tree
1292
+ # Not recommended to be called by the user since it avoids safety
1293
+ # checks for speed
1294
+ data = options["KT_constructor"]
1295
+ shape_data = data[0]
1296
+ rigging_data = data[1]
1297
+ vac_data = data[2]
1298
+ nu = [RiggedPartition(a, b, c)
1299
+ for a, b, c in zip(shape_data, rigging_data, vac_data)]
1300
+ # Special display case
1301
+ if parent.cartan_type().type() == 'B':
1302
+ nu[-1] = RiggedPartitionTypeB(nu[-1])
1303
+ ClonableArray.__init__(self, parent, nu)
1304
+ return
1305
+ RiggedConfigurationElement.__init__(self, parent, rigged_partitions, n=n, **options)
1306
+ # Special display case
1307
+ if parent.cartan_type().type() == 'B':
1308
+ self._set_mutable()
1309
+ self[-1] = RiggedPartitionTypeB(self[-1])
1310
+ self.set_immutable()
1311
+
1312
+ def check(self):
1313
+ """
1314
+ Make sure all of the riggings are less than or equal to the
1315
+ vacancy number.
1316
+
1317
+ TESTS::
1318
+
1319
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
1320
+ sage: elt = RC(partition_list=[[1], [1], [], []])
1321
+ sage: elt.check()
1322
+ """
1323
+ for partition in self:
1324
+ for i, vac_num in enumerate(partition.vacancy_numbers):
1325
+ if vac_num < partition.rigging[i]:
1326
+ raise ValueError("rigging can be at most the vacancy number")
1327
+
1328
+ def e(self, a):
1329
+ r"""
1330
+ Return the action of the crystal operator `e_a` on ``self``.
1331
+
1332
+ For the classical operators, this implements the method defined
1333
+ in [CrysStructSchilling06]_. For `e_0`, this converts the class to
1334
+ a tensor product of KR tableaux and does the corresponding `e_0`
1335
+ and pulls back.
1336
+
1337
+ .. TODO::
1338
+
1339
+ Implement `e_0` without appealing to tensor product of
1340
+ KR tableaux.
1341
+
1342
+ INPUT:
1343
+
1344
+ - ``a`` -- the index of the partition to remove a box
1345
+
1346
+ OUTPUT: the resulting rigged configuration element
1347
+
1348
+ EXAMPLES::
1349
+
1350
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
1351
+ sage: elt = RC(partition_list=[[1], [1], [1], [1]])
1352
+ sage: elt.e(3)
1353
+ sage: elt.e(1)
1354
+ <BLANKLINE>
1355
+ (/)
1356
+ <BLANKLINE>
1357
+ 0[ ]0
1358
+ <BLANKLINE>
1359
+ 0[ ]0
1360
+ <BLANKLINE>
1361
+ -1[ ]-1
1362
+ <BLANKLINE>
1363
+ """
1364
+ if a not in self.parent()._cartan_type.index_set():
1365
+ raise ValueError("{} is not in the index set".format(a))
1366
+ if a == self.parent()._cartan_type.special_node():
1367
+ try:
1368
+ ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().e(a)
1369
+ if ret is None:
1370
+ return None
1371
+ return ret.to_rigged_configuration()
1372
+ except NotImplementedError:
1373
+ # We haven't implemented the bijection yet, so return None
1374
+ # This is to make sure we can at least view it as a classical
1375
+ # crystal if there is no bijection.
1376
+ return None
1377
+
1378
+ return RiggedConfigurationElement.e(self, a)
1379
+
1380
+ def f(self, a):
1381
+ r"""
1382
+ Return the action of the crystal operator `f_a` on ``self``.
1383
+
1384
+ For the classical operators, this implements the method defined
1385
+ in [CrysStructSchilling06]_. For `f_0`, this converts the class to
1386
+ a tensor product of KR tableaux and does the corresponding `f_0`
1387
+ and pulls back.
1388
+
1389
+ .. TODO::
1390
+
1391
+ Implement `f_0` without appealing to tensor product of
1392
+ KR tableaux.
1393
+
1394
+ INPUT:
1395
+
1396
+ - ``a`` -- the index of the partition to add a box
1397
+
1398
+ OUTPUT: the resulting rigged configuration element
1399
+
1400
+ EXAMPLES::
1401
+
1402
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
1403
+ sage: elt = RC(partition_list=[[1], [1], [1], [1]])
1404
+ sage: elt.f(1)
1405
+ sage: elt.f(2)
1406
+ <BLANKLINE>
1407
+ 0[ ]0
1408
+ <BLANKLINE>
1409
+ -1[ ]-1
1410
+ -1[ ]-1
1411
+ <BLANKLINE>
1412
+ 1[ ]1
1413
+ <BLANKLINE>
1414
+ -1[ ]-1
1415
+ <BLANKLINE>
1416
+ """
1417
+ ct = self.parent()._cartan_type
1418
+ if a not in ct.index_set():
1419
+ raise ValueError("{} is not in the index set".format(a))
1420
+ if a == ct.special_node():
1421
+ try:
1422
+ ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().f(a)
1423
+ if ret is None:
1424
+ return None
1425
+ return ret.to_rigged_configuration()
1426
+ except NotImplementedError:
1427
+ # We haven't implemented the bijection yet, so return None
1428
+ # This is to make sure we can at least view it as a classical
1429
+ # crystal if there is no bijection.
1430
+ return None
1431
+
1432
+ if not self.phi(a):
1433
+ return None
1434
+
1435
+ return RiggedConfigurationElement.f(self, a)
1436
+
1437
+ def epsilon(self, a):
1438
+ r"""
1439
+ Return `\varepsilon_a` of ``self``.
1440
+
1441
+ EXAMPLES::
1442
+
1443
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
1444
+ sage: I = RC.index_set()
1445
+ sage: matrix([[mg.epsilon(i) for i in I] for mg in RC.module_generators])
1446
+ [4 0 0 0 0]
1447
+ [3 0 0 0 0]
1448
+ [2 0 0 0 0]
1449
+ """
1450
+ if a == self.parent()._cartan_type.special_node():
1451
+ return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().epsilon(a)
1452
+ return RiggedConfigurationElement.epsilon(self, a)
1453
+
1454
+ def phi(self, a):
1455
+ r"""
1456
+ Return `\varphi_a` of ``self``.
1457
+
1458
+ EXAMPLES::
1459
+
1460
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
1461
+ sage: I = RC.index_set()
1462
+ sage: matrix([[mg.phi(i) for i in I] for mg in RC.module_generators])
1463
+ [0 0 2 0 0]
1464
+ [1 0 1 0 0]
1465
+ [2 0 0 0 0]
1466
+ """
1467
+ if a == self.parent()._cartan_type.special_node():
1468
+ return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().phi(a)
1469
+ return RiggedConfigurationElement.phi(self, a)
1470
+
1471
+ def weight(self):
1472
+ """
1473
+ Return the weight of ``self``.
1474
+
1475
+ EXAMPLES::
1476
+
1477
+ sage: RC = RiggedConfigurations(['E', 6, 1], [[2,2]])
1478
+ sage: [x.weight() for x in RC.module_generators]
1479
+ [-4*Lambda[0] + 2*Lambda[2], -2*Lambda[0] + Lambda[2], 0]
1480
+ sage: KR = crystals.KirillovReshetikhin(['E',6,1], 2,2)
1481
+ sage: [x.weight() for x in KR.module_generators] # long time
1482
+ [0, -2*Lambda[0] + Lambda[2], -4*Lambda[0] + 2*Lambda[2]]
1483
+
1484
+ sage: RC = RiggedConfigurations(['D', 6, 1], [[4,2]])
1485
+ sage: [x.weight() for x in RC.module_generators]
1486
+ [-4*Lambda[0] + 2*Lambda[4], -4*Lambda[0] + Lambda[2] + Lambda[4],
1487
+ -2*Lambda[0] + Lambda[4], -4*Lambda[0] + 2*Lambda[2],
1488
+ -2*Lambda[0] + Lambda[2], 0]
1489
+ """
1490
+ WLR = self.parent().weight_lattice_realization()
1491
+ La = WLR.fundamental_weights()
1492
+ cl_index = self.parent()._rc_index
1493
+ wt = WLR.sum((self.phi(i) - self.epsilon(i)) * La[i] for i in cl_index)
1494
+ return -wt.level() * La[0] + wt
1495
+
1496
+ @cached_method
1497
+ def classical_weight(self):
1498
+ r"""
1499
+ Return the classical weight of ``self``.
1500
+
1501
+ The classical weight `\Lambda` of a rigged configuration is
1502
+
1503
+ .. MATH::
1504
+
1505
+ \Lambda = \sum_{a \in \overline{I}} \sum_{i > 0}
1506
+ i L_i^{(a)} \Lambda_a - \sum_{a \in \overline{I}} \sum_{i > 0}
1507
+ i m_i^{(a)} \alpha_a.
1508
+
1509
+ EXAMPLES::
1510
+
1511
+ sage: RC = RiggedConfigurations(['D',4,1], [[2,2]])
1512
+ sage: elt = RC(partition_list=[[2],[2,1],[1],[1]])
1513
+ sage: elt.classical_weight()
1514
+ (0, 1, 1, 0)
1515
+
1516
+ This agrees with the corresponding classical weight as KR tableaux::
1517
+
1518
+ sage: krt = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); krt
1519
+ [[2, 1], [3, -1]]
1520
+ sage: krt.classical_weight() == elt.classical_weight()
1521
+ True
1522
+
1523
+ TESTS:
1524
+
1525
+ We check the classical weights agree in an entire crystal::
1526
+
1527
+ sage: RC = RiggedConfigurations(['A',2,1], [[2,1], [1,1]])
1528
+ sage: for x in RC:
1529
+ ....: y = x.to_tensor_product_of_kirillov_reshetikhin_tableaux()
1530
+ ....: assert x.classical_weight() == y.classical_weight()
1531
+ """
1532
+ F = self.cartan_type().classical().root_system()
1533
+ if F.ambient_space() is None:
1534
+ WLR = F.weight_lattice()
1535
+ else:
1536
+ WLR = F.ambient_space()
1537
+ La = WLR.fundamental_weights()
1538
+ wt = WLR.sum(La[r] * s for r,s in self.parent().dims)
1539
+
1540
+ alpha = WLR.simple_roots()
1541
+ rc_index = self.parent()._rc_index
1542
+ for a, nu in enumerate(self):
1543
+ wt -= sum(nu) * alpha[rc_index[a]]
1544
+ return wt
1545
+
1546
+ def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False, build_graph=False):
1547
+ r"""
1548
+ Perform the bijection from this rigged configuration to a tensor
1549
+ product of Kirillov-Reshetikhin tableaux given in [RigConBijection]_
1550
+ for single boxes and with [BijectionLRT]_ and [BijectionDn]_ for
1551
+ multiple columns and rows.
1552
+
1553
+ .. NOTE::
1554
+
1555
+ This is only proven to be a bijection in types `A_n^{(1)}`
1556
+ and `D_n^{(1)}`, as well as `\bigotimes_i B^{r_i,1}` and
1557
+ `\bigotimes_i B^{1,s_i}` for general affine types.
1558
+
1559
+ INPUT:
1560
+
1561
+ - ``display_steps`` -- boolean (default: ``False``); indicates whether
1562
+ to print each step in the algorithm
1563
+ - ``build_graph`` -- boolean (default: ``False``); indicates whether
1564
+ to construct and return a graph of the bijection whose
1565
+ vertices are rigged configurations obtained at each step and edges
1566
+ are labeled by either the return value of `\delta` or the
1567
+ doubling/halving map
1568
+
1569
+ OUTPUT:
1570
+
1571
+ - The tensor product of KR tableaux element corresponding to this
1572
+ rigged configuration.
1573
+
1574
+ EXAMPLES::
1575
+
1576
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
1577
+ sage: RC(partition_list=[[2], [2,2], [2], [2]]).to_tensor_product_of_kirillov_reshetikhin_tableaux()
1578
+ [[3, 3], [5, 5]]
1579
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
1580
+ sage: elt = RC(partition_list=[[2], [2,2], [1], [1]])
1581
+ sage: tp_krt = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); tp_krt
1582
+ [[2, 3], [3, -2]]
1583
+
1584
+ This is invertible by calling
1585
+ :meth:`~sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element.TensorProductOfKirillovReshetikhinTableauxElement.to_rigged_configuration()`::
1586
+
1587
+ sage: ret = tp_krt.to_rigged_configuration(); ret
1588
+ <BLANKLINE>
1589
+ 0[ ][ ]0
1590
+ <BLANKLINE>
1591
+ -2[ ][ ]-2
1592
+ -2[ ][ ]-2
1593
+ <BLANKLINE>
1594
+ 0[ ]0
1595
+ <BLANKLINE>
1596
+ 0[ ]0
1597
+ <BLANKLINE>
1598
+ sage: elt == ret
1599
+ True
1600
+
1601
+ To view the steps of the bijection in the output, run with
1602
+ the ``display_steps=True`` option::
1603
+
1604
+ sage: elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(True)
1605
+ ====================
1606
+ ...
1607
+ ====================
1608
+ <BLANKLINE>
1609
+ 0[ ]0
1610
+ <BLANKLINE>
1611
+ -2[ ][ ]-2
1612
+ 0[ ]0
1613
+ <BLANKLINE>
1614
+ 0[ ]0
1615
+ <BLANKLINE>
1616
+ 0[ ]0
1617
+ <BLANKLINE>
1618
+ --------------------
1619
+ [[3, 2]]
1620
+ --------------------
1621
+ ...
1622
+ [[2, 3], [3, -2]]
1623
+
1624
+ We can also construct and display a graph of the bijection
1625
+ as follows::
1626
+
1627
+ sage: ret, G = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(build_graph=True)
1628
+ sage: view(G) # not tested
1629
+ """
1630
+ from sage.combinat.rigged_configurations.bijection import RCToKRTBijection
1631
+ bij = RCToKRTBijection(self)
1632
+ ret = bij.run(display_steps, build_graph)
1633
+ if build_graph:
1634
+ return (ret, bij._graph)
1635
+ return ret
1636
+
1637
+ def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False, build_graph=False):
1638
+ r"""
1639
+ Return the corresponding tensor product of Kirillov-Reshetikhin
1640
+ crystals.
1641
+
1642
+ This is a composition of the map to a tensor product of KR tableaux,
1643
+ and then to a tensor product of KR crystals.
1644
+
1645
+ INPUT:
1646
+
1647
+ - ``display_steps`` -- boolean (default: ``False``); indicates whether
1648
+ to print each step in the algorithm
1649
+ - ``build_graph`` -- boolean (default: ``False``); indicates whether
1650
+ to construct and return a graph of the bijection whose
1651
+ vertices are rigged configurations obtained at each step and edges
1652
+ are labeled by either the return value of `\delta` or the
1653
+ doubling/halving map
1654
+
1655
+ EXAMPLES::
1656
+
1657
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
1658
+ sage: elt = RC(partition_list=[[2], [2,2], [1], [1]])
1659
+ sage: krc = elt.to_tensor_product_of_kirillov_reshetikhin_crystals(); krc
1660
+ [[[2, 3], [3, -2]]]
1661
+
1662
+ We can recover the rigged configuration::
1663
+
1664
+ sage: ret = RC(krc); ret
1665
+ <BLANKLINE>
1666
+ 0[ ][ ]0
1667
+ <BLANKLINE>
1668
+ -2[ ][ ]-2
1669
+ -2[ ][ ]-2
1670
+ <BLANKLINE>
1671
+ 0[ ]0
1672
+ <BLANKLINE>
1673
+ 0[ ]0
1674
+ <BLANKLINE>
1675
+ sage: elt == ret
1676
+ True
1677
+
1678
+ We can also construct and display a graph of the bijection
1679
+ as follows::
1680
+
1681
+ sage: ret, G = elt.to_tensor_product_of_kirillov_reshetikhin_crystals(build_graph=True)
1682
+ sage: view(G) # not tested
1683
+ """
1684
+ if build_graph:
1685
+ kr_tab, G = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps, build_graph)
1686
+ return (kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals(), G)
1687
+ kr_tab = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps)
1688
+ return kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals()
1689
+
1690
+ # TODO: Move the morphisms to a lazy attribute of RiggedConfigurations
1691
+ # once #15463 is done
1692
+ def left_split(self):
1693
+ r"""
1694
+ Return the image of ``self`` under the left column splitting
1695
+ map `\beta`.
1696
+
1697
+ Consider the map `\beta : RC(B^{r,s} \otimes B) \to RC(B^{r,1}
1698
+ \otimes B^{r,s-1} \otimes B)` for `s > 1` which is a natural classical
1699
+ crystal injection. On rigged configurations, the map `\beta` does
1700
+ nothing (except possibly changing the vacancy numbers).
1701
+
1702
+ EXAMPLES::
1703
+
1704
+ sage: RC = RiggedConfigurations(['C',4,1], [[3,3]])
1705
+ sage: mg = RC.module_generators[-1]
1706
+ sage: ascii_art(mg)
1707
+ 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
1708
+ 0[ ][ ]0 0[ ][ ]0 0[ ]0
1709
+ 0[ ][ ]0 0[ ]0
1710
+ sage: ascii_art(mg.left_split())
1711
+ 0[ ][ ]0 0[ ][ ]0 1[ ][ ]0 0[ ]0
1712
+ 0[ ][ ]0 1[ ][ ]0 0[ ]0
1713
+ 1[ ][ ]0 0[ ]0
1714
+ """
1715
+ P = self.parent()
1716
+ if P.dims[0][1] == 1:
1717
+ raise ValueError("cannot split a single column")
1718
+ r,s = P.dims[0]
1719
+ B = [[r,1], [r,s-1]]
1720
+ B.extend(P.dims[1:])
1721
+ from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
1722
+ RC = RiggedConfigurations(P._cartan_type, B)
1723
+ return RC(*[x._clone() for x in self]) # Make a deep copy
1724
+
1725
+ def right_split(self):
1726
+ r"""
1727
+ Return the image of ``self`` under the right column splitting
1728
+ map `\beta^*`.
1729
+
1730
+ Let `\theta` denote the
1731
+ :meth:`complement rigging map<complement_rigging>` which reverses
1732
+ the tensor factors and `\beta` denote the
1733
+ :meth:`left splitting map<left_split>`, we define the right
1734
+ splitting map by `\beta^* := \theta \circ \beta \circ \theta`.
1735
+
1736
+ EXAMPLES::
1737
+
1738
+ sage: RC = RiggedConfigurations(['C',4,1], [[3,3]])
1739
+ sage: mg = RC.module_generators[-1]
1740
+ sage: ascii_art(mg)
1741
+ 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
1742
+ 0[ ][ ]0 0[ ][ ]0 0[ ]0
1743
+ 0[ ][ ]0 0[ ]0
1744
+ sage: ascii_art(mg.right_split())
1745
+ 0[ ][ ]0 0[ ][ ]0 1[ ][ ]1 0[ ]0
1746
+ 0[ ][ ]0 1[ ][ ]1 0[ ]0
1747
+ 1[ ][ ]1 0[ ]0
1748
+
1749
+ sage: RC = RiggedConfigurations(['D',4,1], [[2,2],[1,2]])
1750
+ sage: elt = RC(partition_list=[[3,1], [2,2,1], [2,1], [2]])
1751
+ sage: ascii_art(elt)
1752
+ -1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1
1753
+ 0[ ]0 0[ ][ ]0 -1[ ]-1
1754
+ 0[ ]0
1755
+ sage: ascii_art(elt.right_split())
1756
+ -1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1
1757
+ 1[ ]0 0[ ][ ]0 -1[ ]-1
1758
+ 0[ ]0
1759
+
1760
+ We check that the bijection commutes with the right splitting map::
1761
+
1762
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[1,1], [2,2]])
1763
+ sage: all(rc.right_split().to_tensor_product_of_kirillov_reshetikhin_tableaux()
1764
+ ....: == rc.to_tensor_product_of_kirillov_reshetikhin_tableaux().right_split() for rc in RC)
1765
+ True
1766
+ """
1767
+ return self.complement_rigging(True).left_split().complement_rigging(True)
1768
+
1769
+ def left_box(self, return_b=False):
1770
+ r"""
1771
+ Return the image of ``self`` under the left box removal map `\delta`.
1772
+
1773
+ The map `\delta : RC(B^{r,1} \otimes B) \to RC(B^{r-1,1}
1774
+ \otimes B)` (if `r = 1`, then we remove the left-most factor) is the
1775
+ basic map in the bijection `\Phi` between rigged configurations and
1776
+ tensor products of Kirillov-Reshetikhin tableaux. For more
1777
+ information, see
1778
+ :meth:`to_tensor_product_of_kirillov_reshetikhin_tableaux()`.
1779
+ We can extend `\delta` when the left-most factor is not a single
1780
+ column by precomposing with a :meth:`left_split()`.
1781
+
1782
+ .. NOTE::
1783
+
1784
+ Due to the special nature of the bijection for the spinor cases in
1785
+ types `D_n^{(1)}`, `B_n^{(1)}`, and `A_{2n-1}^{(2)}`, this map is
1786
+ not defined in these cases.
1787
+
1788
+ INPUT:
1789
+
1790
+ - ``return_b`` -- boolean (default: ``False``); whether to return the
1791
+ resulting letter from `\delta`
1792
+
1793
+ OUTPUT:
1794
+
1795
+ The resulting rigged configuration or if ``return_b`` is ``True``,
1796
+ then a tuple of the resulting rigged configuration and the letter.
1797
+
1798
+ EXAMPLES::
1799
+
1800
+ sage: RC = RiggedConfigurations(['C',4,1], [[3,2]])
1801
+ sage: mg = RC.module_generators[-1]
1802
+ sage: ascii_art(mg)
1803
+ 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
1804
+ 0[ ][ ]0 0[ ][ ]0 0[ ]0
1805
+ 0[ ][ ]0 0[ ]0
1806
+ sage: ascii_art(mg.left_box())
1807
+ 0[ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
1808
+ 0[ ]0 0[ ][ ]0 0[ ]0
1809
+ sage: x,b = mg.left_box(True)
1810
+ sage: b
1811
+ -1
1812
+ sage: b.parent()
1813
+ The crystal of letters for type ['C', 4]
1814
+ """
1815
+ # Don't do spinor cases
1816
+ P = self.parent()
1817
+ ct = P.cartan_type()
1818
+ if ct.type() == 'D':
1819
+ if P.dims[0][0] >= ct.rank() - 2:
1820
+ raise ValueError("only for non-spinor cases")
1821
+ elif ct.type() == 'B' or ct.dual().type() == 'B':
1822
+ if P.dims[0][0] == ct.rank() - 1:
1823
+ raise ValueError("only for non-spinor cases")
1824
+
1825
+ from sage.combinat.rigged_configurations.bijection import RCToKRTBijection
1826
+ rc = self
1827
+ if P.dims[0][1] != 1:
1828
+ rc = self.left_split()
1829
+ bij = RCToKRTBijection(rc)
1830
+ ht = bij.cur_dims[0][0]
1831
+ bij.cur_dims[0][0] = bij._next_index(ht)
1832
+ b = bij.next_state(ht)
1833
+ if bij.cur_dims[0][0] == 0:
1834
+ bij.cur_dims.pop(0)
1835
+ from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
1836
+ RC = RiggedConfigurations(ct, bij.cur_dims)
1837
+ rc = RC(*bij.cur_partitions)
1838
+ if return_b:
1839
+ from sage.combinat.crystals.letters import CrystalOfLetters
1840
+ L = CrystalOfLetters(self.parent()._cartan_type.classical())
1841
+ return (rc, L(b))
1842
+ return rc
1843
+
1844
+ delta = left_box
1845
+
1846
+ def left_column_box(self):
1847
+ r"""
1848
+ Return the image of ``self`` under the left column box splitting
1849
+ map `\gamma`.
1850
+
1851
+ Consider the map `\gamma : RC(B^{r,1} \otimes B) \to RC(B^{1,1}
1852
+ \otimes B^{r-1,1} \otimes B)` for `r > 1`, which is a natural strict
1853
+ classical crystal injection. On rigged configurations, the map
1854
+ `\gamma` adds a singular string of length `1` to `\nu^{(a)}`.
1855
+
1856
+ We can extend `\gamma` when the left-most factor is not a single
1857
+ column by precomposing with a :meth:`left_split()`.
1858
+
1859
+ EXAMPLES::
1860
+
1861
+ sage: RC = RiggedConfigurations(['C',3,1], [[3,1], [2,1]])
1862
+ sage: mg = RC.module_generators[-1]
1863
+ sage: ascii_art(mg)
1864
+ 0[ ]0 0[ ][ ]0 0[ ]0
1865
+ 0[ ]0 0[ ]0
1866
+ sage: ascii_art(mg.left_column_box())
1867
+ 0[ ]0 0[ ][ ]0 0[ ]0
1868
+ 0[ ]0 0[ ]0 0[ ]0
1869
+ 0[ ]0
1870
+
1871
+ sage: RC = RiggedConfigurations(['C',3,1], [[2,1], [1,1], [3,1]])
1872
+ sage: mg = RC.module_generators[7]
1873
+ sage: ascii_art(mg)
1874
+ 1[ ]0 0[ ][ ]0 0[ ]0
1875
+ 0[ ]0 0[ ]0
1876
+ sage: ascii_art(mg.left_column_box())
1877
+ 1[ ]1 0[ ][ ]0 0[ ]0
1878
+ 1[ ]0 0[ ]0 0[ ]0
1879
+ """
1880
+ P = self.parent()
1881
+ r = P.dims[0][0]
1882
+ if r == 1:
1883
+ raise ValueError("cannot split a single box")
1884
+ ct = P.cartan_type()
1885
+ if ct.type() == 'D':
1886
+ if P.dims[0][0] >= ct.rank() - 2:
1887
+ raise ValueError("only for non-spinor cases")
1888
+ elif ct.type() == 'B' or ct.dual().type() == 'B':
1889
+ if P.dims[0][0] == ct.rank() - 1:
1890
+ raise ValueError("only for non-spinor cases")
1891
+
1892
+ if P.dims[0][1] > 1:
1893
+ return self.left_split().left_column_box()
1894
+
1895
+ B = [[1,1], [r-1,1]]
1896
+ B.extend(P.dims[1:])
1897
+ from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
1898
+ RC = RiggedConfigurations(P._cartan_type, B)
1899
+ parts = [x._clone() for x in self] # Make a deep copy
1900
+ for nu in parts[:r-1]:
1901
+ nu._list.append(1)
1902
+ for a, nu in enumerate(parts[:r-1]):
1903
+ vac_num = RC._calc_vacancy_number(parts, a, 1)
1904
+ i = nu._list.index(1)
1905
+ nu.vacancy_numbers.insert(i, vac_num)
1906
+ nu.rigging.insert(i, vac_num)
1907
+ return RC(*parts)
1908
+
1909
+ def right_column_box(self):
1910
+ r"""
1911
+ Return the image of ``self`` under the right column box splitting
1912
+ map `\gamma^*`.
1913
+
1914
+ Consider the map `\gamma^* : RC(B \otimes B^{r,1}) \to RC(B \otimes
1915
+ B^{r-1,1} \otimes B^{1,1})` for `r > 1`, which is a natural strict
1916
+ classical crystal injection. On rigged configurations, the map
1917
+ `\gamma` adds a string of length `1` with rigging 0 to `\nu^{(a)}`
1918
+ for all `a < r` to a classically highest weight element and extended
1919
+ as a classical crystal morphism.
1920
+
1921
+ We can extend `\gamma^*` when the right-most factor is not a single
1922
+ column by precomposing with a :meth:`right_split()`.
1923
+
1924
+ EXAMPLES::
1925
+
1926
+ sage: RC = RiggedConfigurations(['C',3,1], [[2,1], [1,1], [3,1]])
1927
+ sage: mg = RC.module_generators[7]
1928
+ sage: ascii_art(mg)
1929
+ 1[ ]0 0[ ][ ]0 0[ ]0
1930
+ 0[ ]0 0[ ]0
1931
+ sage: ascii_art(mg.right_column_box())
1932
+ 1[ ]0 0[ ][ ]0 0[ ]0
1933
+ 1[ ]0 0[ ]0 0[ ]0
1934
+ 0[ ]0
1935
+ """
1936
+ P = self.parent()
1937
+ r = P.dims[-1][0]
1938
+ if r == 1:
1939
+ raise ValueError("cannot split a single box")
1940
+ ct = P.cartan_type()
1941
+ if ct.type() == 'D':
1942
+ if P.dims[-1][0] >= ct.rank() - 2:
1943
+ raise ValueError("only for non-spinor cases")
1944
+ elif ct.type() == 'B' or ct.dual().type() == 'B':
1945
+ if P.dims[-1][0] == ct.rank() - 1:
1946
+ raise ValueError("only for non-spinor cases")
1947
+
1948
+ if P.dims[-1][1] > 1:
1949
+ return self.right_split().right_column_box()
1950
+
1951
+ rc, e_string = self.to_highest_weight(P._rc_index)
1952
+
1953
+ B = P.dims[:-1] + ([r-1,1], [1,1])
1954
+ from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
1955
+ RC = RiggedConfigurations(P._cartan_type, B)
1956
+ parts = [x._clone() for x in rc] # Make a deep copy
1957
+ for nu in parts[:r-1]:
1958
+ nu._list.append(1)
1959
+ for a, nu in enumerate(parts[:r-1]):
1960
+ vac_num = RC._calc_vacancy_number(parts, a, -1)
1961
+ nu.vacancy_numbers.append(vac_num)
1962
+ nu.rigging.append(0)
1963
+ return RC(*parts).f_string(reversed(e_string))
1964
+
1965
+ def complement_rigging(self, reverse_factors=False):
1966
+ r"""
1967
+ Apply the complement rigging morphism `\theta` to ``self``.
1968
+
1969
+ Consider a highest weight rigged configuration `(\nu, J)`, the
1970
+ complement rigging morphism `\theta : RC(L) \to RC(L)` is given by
1971
+ sending `(\nu, J) \mapsto (\nu, J')`, where `J'` is obtained by
1972
+ taking the coriggings `x' = p_i^{(a)} - x`, and then extending as
1973
+ a crystal morphism. (The name comes from taking the complement
1974
+ partition for the riggings in a `m_i^{(a)} \times p_i^{(a)}` box.)
1975
+
1976
+ INPUT:
1977
+
1978
+ - ``reverse_factors`` -- boolean (default: ``False``); if ``True``, then this
1979
+ returns an element in `RC(B')` where `B'` is the tensor factors
1980
+ of ``self`` in reverse order
1981
+
1982
+ EXAMPLES::
1983
+
1984
+ sage: RC = RiggedConfigurations(['D',4,1], [[1,1],[2,2]])
1985
+ sage: mg = RC.module_generators[-1]
1986
+ sage: ascii_art(mg)
1987
+ 1[ ][ ]1 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0
1988
+ 0[ ][ ]0
1989
+ sage: ascii_art(mg.complement_rigging())
1990
+ 1[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0
1991
+ 0[ ][ ]0
1992
+
1993
+ sage: lw = mg.to_lowest_weight([1,2,3,4])[0]
1994
+ sage: ascii_art(lw)
1995
+ -1[ ][ ]-1 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0
1996
+ -1[ ]-1 0[ ][ ]0 0[ ]0 0[ ]0
1997
+ -1[ ]-1 0[ ]0
1998
+ 0[ ]0
1999
+ sage: ascii_art(lw.complement_rigging())
2000
+ -1[ ][ ][ ]-1 0[ ][ ][ ]0 0[ ][ ][ ]0 0[ ][ ][ ]0
2001
+ -1[ ]-1 0[ ][ ][ ]0
2002
+ sage: lw.complement_rigging() == mg.complement_rigging().to_lowest_weight([1,2,3,4])[0]
2003
+ True
2004
+
2005
+ sage: mg.complement_rigging(True).parent()
2006
+ Rigged configurations of type ['D', 4, 1] and factor(s) ((2, 2), (1, 1))
2007
+
2008
+ We check that the Lusztig involution (under the modification of also
2009
+ mapping to the highest weight element) intertwines with the
2010
+ complement map `\theta` (that reverses the tensor factors)
2011
+ under the bijection `\Phi`::
2012
+
2013
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2], [2, 1], [1, 2]])
2014
+ sage: for mg in RC.module_generators: # long time
2015
+ ....: y = mg.to_tensor_product_of_kirillov_reshetikhin_tableaux()
2016
+ ....: hw = y.lusztig_involution().to_highest_weight([1,2,3,4])[0]
2017
+ ....: c = mg.complement_rigging(True)
2018
+ ....: hwc = c.to_tensor_product_of_kirillov_reshetikhin_tableaux()
2019
+ ....: assert hw == hwc
2020
+
2021
+ TESTS:
2022
+
2023
+ We check that :issue:`18898` is fixed::
2024
+
2025
+ sage: RC = RiggedConfigurations(['D',4,1], [[2,1], [2,1], [2,3]])
2026
+ sage: x = RC(partition_list=[[1], [1,1], [1], [1]], rigging_list=[[0], [2,1], [0], [0]])
2027
+ sage: ascii_art(x)
2028
+ 0[ ]0 2[ ]2 0[ ]0 0[ ]0
2029
+ 2[ ]1
2030
+ sage: ascii_art(x.complement_rigging())
2031
+ 0[ ]0 2[ ]1 0[ ]0 0[ ]0
2032
+ 2[ ]0
2033
+ """
2034
+ P = self.parent()
2035
+ if reverse_factors:
2036
+ from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
2037
+ P = RiggedConfigurations(P._cartan_type, reversed(P.dims))
2038
+
2039
+ mg, e_str = self.to_highest_weight(P._rc_index)
2040
+ nu = []
2041
+ rig = []
2042
+ for a,p in enumerate(mg):
2043
+ nu.append(list(p))
2044
+ vac_nums = p.vacancy_numbers
2045
+ riggings = [vac - p.rigging[i] for i,vac in enumerate(vac_nums)]
2046
+ block = 0
2047
+ for j,i in enumerate(p):
2048
+ if p[block] != i:
2049
+ riggings[block:j] = sorted(riggings[block:j], reverse=True)
2050
+ block = j
2051
+ riggings[block:] = sorted(riggings[block:], reverse=True)
2052
+ rig.append(riggings)
2053
+
2054
+ rc = P(partition_list=nu, rigging_list=rig)
2055
+ return rc.f_string(reversed(e_str))
2056
+
2057
+
2058
+ class KRRCSimplyLacedElement(KRRiggedConfigurationElement):
2059
+ r"""
2060
+ `U_q^{\prime}(\mathfrak{g})` rigged configurations in simply-laced types.
2061
+
2062
+ TESTS::
2063
+
2064
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [2,1], [1,1]])
2065
+ sage: elt = RC(partition_list=[[1], [1], []]); elt
2066
+ <BLANKLINE>
2067
+ 0[ ]0
2068
+ <BLANKLINE>
2069
+ 0[ ]0
2070
+ <BLANKLINE>
2071
+ (/)
2072
+ <BLANKLINE>
2073
+ sage: TestSuite(elt).run()
2074
+ """
2075
+ @cached_method
2076
+ def cocharge(self):
2077
+ r"""
2078
+ Compute the cocharge statistic of ``self``.
2079
+
2080
+ Computes the cocharge statistic [CrysStructSchilling06]_ on this
2081
+ rigged configuration `(\nu, J)`. The cocharge statistic is defined as:
2082
+
2083
+ .. MATH::
2084
+
2085
+ cc(\nu, J) = \frac{1}{2} \sum_{a, b \in I_0}
2086
+ \sum_{j,k > 0} \left( \alpha_a \mid \alpha_b \right)
2087
+ \min(j, k) m_j^{(a)} m_k^{(b)}
2088
+ + \sum_{a \in I} \sum_{i > 0} \left\lvert J^{(a, i)} \right\rvert.
2089
+
2090
+ EXAMPLES::
2091
+
2092
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [2,1], [1,1]])
2093
+ sage: RC(partition_list=[[1], [1], []]).cocharge()
2094
+ 1
2095
+ """
2096
+ cc = 0
2097
+ rigging_sum = 0
2098
+ for a, p in enumerate(self):
2099
+ for pos, i in enumerate(p._list):
2100
+ # Add the rigging
2101
+ rigging_sum += p.rigging[pos]
2102
+ # Add the L matrix contribution
2103
+ for dim in self.parent().dims:
2104
+ if dim[0] == a + 1:
2105
+ cc += min(dim[1], i)
2106
+ # Subtract the vacancy number
2107
+ cc -= p.vacancy_numbers[pos]
2108
+ return cc // 2 + rigging_sum
2109
+
2110
+ cc = cocharge
2111
+
2112
+ @cached_method
2113
+ def charge(self):
2114
+ r"""
2115
+ Compute the charge statistic of ``self``.
2116
+
2117
+ Let `B` denote a set of rigged configurations. The *charge* `c` of
2118
+ a rigged configuration `b` is computed as
2119
+
2120
+ .. MATH::
2121
+
2122
+ c(b) = \max(cc(b) \mid b \in B) - cc(b).
2123
+
2124
+ EXAMPLES::
2125
+
2126
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [2,1], [1,1]])
2127
+ sage: RC(partition_list=[[],[],[]]).charge()
2128
+ 2
2129
+ sage: RC(partition_list=[[1], [1], []]).charge()
2130
+ 1
2131
+ """
2132
+ B = self.parent()
2133
+ if not hasattr(B, "_max_charge"):
2134
+ B._max_charge = max(b.cocharge() for b in B.module_generators)
2135
+ return B._max_charge - self.cocharge()
2136
+
2137
+
2138
+ class KRRCNonSimplyLacedElement(KRRiggedConfigurationElement, RCNonSimplyLacedElement):
2139
+ r"""
2140
+ `U_q^{\prime}(\mathfrak{g})` rigged configurations in non-simply-laced
2141
+ types.
2142
+
2143
+ TESTS::
2144
+
2145
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
2146
+ sage: elt = RC(partition_list=[[3],[2]]); elt
2147
+ <BLANKLINE>
2148
+ 0[ ][ ][ ]0
2149
+ <BLANKLINE>
2150
+ 0[ ][ ]0
2151
+ sage: TestSuite(elt).run()
2152
+ """
2153
+
2154
+ def e(self, a):
2155
+ r"""
2156
+ Return the action of `e_a` on ``self``.
2157
+
2158
+ This works by lifting into the virtual configuration, then applying
2159
+
2160
+ .. MATH::
2161
+
2162
+ e^v_a = \prod_{j \in \iota(a)} \hat{e}_j^{\gamma_j}
2163
+
2164
+ and pulling back.
2165
+
2166
+ EXAMPLES::
2167
+
2168
+ sage: RC = RiggedConfigurations(['A',6,2], [[1,1]]*7)
2169
+ sage: elt = RC(partition_list=[[1]*5,[2,1,1],[3,2]])
2170
+ sage: elt.e(3)
2171
+ <BLANKLINE>
2172
+ 0[ ]0
2173
+ 0[ ]0
2174
+ 0[ ]0
2175
+ 0[ ]0
2176
+ 0[ ]0
2177
+ <BLANKLINE>
2178
+ 0[ ][ ]0
2179
+ 1[ ]1
2180
+ 1[ ]1
2181
+ <BLANKLINE>
2182
+ 1[ ][ ]1
2183
+ 1[ ]0
2184
+ <BLANKLINE>
2185
+ """
2186
+ if a == self.parent()._cartan_type.special_node():
2187
+ try:
2188
+ ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().e(a)
2189
+ if ret is None:
2190
+ return None
2191
+ return ret.to_rigged_configuration()
2192
+ except (NotImplementedError, TypeError):
2193
+ # We haven't implemented the bijection yet, so try by lifting
2194
+ # to the simply-laced case
2195
+ return RCNonSimplyLacedElement.e(self, a)
2196
+
2197
+ if not self.epsilon(a):
2198
+ return None
2199
+ return RCNonSimplyLacedElement.e(self, a)
2200
+
2201
+ def f(self, a):
2202
+ r"""
2203
+ Return the action of `f_a` on ``self``.
2204
+
2205
+ This works by lifting into the virtual configuration, then applying
2206
+
2207
+ .. MATH::
2208
+
2209
+ f^v_a = \prod_{j \in \iota(a)} \hat{f}_j^{\gamma_j}
2210
+
2211
+ and pulling back.
2212
+
2213
+ EXAMPLES::
2214
+
2215
+ sage: RC = RiggedConfigurations(['A',6,2], [[1,1]]*7)
2216
+ sage: elt = RC(partition_list=[[1]*5,[2,1,1],[2,1]], rigging_list=[[0]*5,[0,1,1],[1,0]])
2217
+ sage: elt.f(3)
2218
+ <BLANKLINE>
2219
+ 0[ ]0
2220
+ 0[ ]0
2221
+ 0[ ]0
2222
+ 0[ ]0
2223
+ 0[ ]0
2224
+ <BLANKLINE>
2225
+ 1[ ][ ]1
2226
+ 1[ ]1
2227
+ 1[ ]1
2228
+ <BLANKLINE>
2229
+ -1[ ][ ][ ]-1
2230
+ 0[ ][ ]0
2231
+ <BLANKLINE>
2232
+ """
2233
+ if a == self.parent()._cartan_type.special_node():
2234
+ try:
2235
+ ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().f(a)
2236
+ if ret is None:
2237
+ return None
2238
+ return ret.to_rigged_configuration()
2239
+ except (NotImplementedError, TypeError):
2240
+ # We haven't implemented the bijection yet, so try by lifting
2241
+ # to the simply-laced case
2242
+ return RCNonSimplyLacedElement.f(self, a)
2243
+
2244
+ if not self.phi(a):
2245
+ return None
2246
+ return RCNonSimplyLacedElement.f(self, a)
2247
+
2248
+ @cached_method
2249
+ def cocharge(self):
2250
+ r"""
2251
+ Compute the cocharge statistic.
2252
+
2253
+ Computes the cocharge statistic [OSS03]_ on this
2254
+ rigged configuration `(\nu, J)` by computing the cocharge as a virtual
2255
+ rigged configuration `(\hat{\nu}, \hat{J})` and then using the
2256
+ identity `cc(\hat{\nu}, \hat{J}) = \gamma_0 cc(\nu, J)`.
2257
+
2258
+ EXAMPLES::
2259
+
2260
+ sage: RC = RiggedConfigurations(['C', 3, 1], [[2,1], [1,1]])
2261
+ sage: RC(partition_list=[[1,1],[2,1],[1,1]]).cocharge()
2262
+ 1
2263
+ """
2264
+ # return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0]
2265
+ vct = self.parent()._folded_ct
2266
+ cc = ZZ.zero()
2267
+ rigging_sum = ZZ.zero()
2268
+ sigma = vct.folding_orbit()
2269
+ gamma = vct.scaling_factors()
2270
+ for a, p in enumerate(self):
2271
+ t_check = len(sigma[a + 1]) * gamma[a+1] // gamma[0]
2272
+ for pos, i in enumerate(p._list):
2273
+ # Add the rigging
2274
+ rigging_sum += t_check * p.rigging[pos]
2275
+ # Add the L matrix contribution
2276
+ for dim in self.parent().dims:
2277
+ if dim[0] == a + 1:
2278
+ cc += t_check * min(dim[1], i)
2279
+ # Subtract the vacancy number
2280
+ cc -= t_check * p.vacancy_numbers[pos]
2281
+ return cc // 2 + rigging_sum
2282
+
2283
+ cc = cocharge
2284
+
2285
+
2286
+ class KRRCTypeA2DualElement(KRRCNonSimplyLacedElement):
2287
+ r"""
2288
+ `U_q^{\prime}(\mathfrak{g})` rigged configurations in type
2289
+ `A_{2n}^{(2)\dagger}`.
2290
+ """
2291
+
2292
+ def epsilon(self, a):
2293
+ r"""
2294
+ Return the value of `\varepsilon_a` of ``self``.
2295
+
2296
+ Here we need to modify the usual definition by
2297
+ `\varepsilon_n^{\prime} := 2 \varepsilon_n`.
2298
+
2299
+ EXAMPLES::
2300
+
2301
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1], [2,2]])
2302
+ sage: def epsilon(x, i):
2303
+ ....: x = x.e(i)
2304
+ ....: eps = 0
2305
+ ....: while x is not None:
2306
+ ....: x = x.e(i)
2307
+ ....: eps = eps + 1
2308
+ ....: return eps
2309
+ sage: all(epsilon(rc, 2) == rc.epsilon(2) for rc in RC)
2310
+ True
2311
+ """
2312
+ if a == self.parent()._cartan_type.special_node():
2313
+ return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().epsilon(a)
2314
+
2315
+ a = self.parent()._rc_index_inverse[a]
2316
+ if not self[a]:
2317
+ epsilon = 0
2318
+ else:
2319
+ epsilon = -min(0, *self[a].rigging)
2320
+ n = len(self.parent()._rc_index)
2321
+ if a == n-1: # -1 for indexing
2322
+ epsilon *= 2
2323
+ return Integer(epsilon)
2324
+
2325
+ def phi(self, a):
2326
+ r"""
2327
+ Return the value of `\varphi_a` of ``self``.
2328
+
2329
+ Here we need to modify the usual definition by
2330
+ `\varphi_n^{\prime} := 2 \varphi_n`.
2331
+
2332
+ EXAMPLES::
2333
+
2334
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1], [2,2]])
2335
+ sage: def phi(x, i):
2336
+ ....: x = x.f(i)
2337
+ ....: ph = 0
2338
+ ....: while x is not None:
2339
+ ....: x = x.f(i)
2340
+ ....: ph = ph + 1
2341
+ ....: return ph
2342
+ sage: all(phi(rc, 2) == rc.phi(2) for rc in RC)
2343
+ True
2344
+ """
2345
+ if a == self.parent()._cartan_type.special_node():
2346
+ return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().phi(a)
2347
+
2348
+ a = self.parent()._rc_index_inverse[a]
2349
+ p_inf = self.parent()._calc_vacancy_number(self, a, float("inf"))
2350
+ if not self[a]:
2351
+ phi = p_inf
2352
+ else:
2353
+ phi = p_inf - min(0, *self[a].rigging)
2354
+ n = len(self.parent()._rc_index)
2355
+ if a == n-1: # -1 for indexing
2356
+ phi *= 2
2357
+ return Integer(phi)
2358
+
2359
+ @cached_method
2360
+ def cocharge(self):
2361
+ r"""
2362
+ Compute the cocharge statistic.
2363
+
2364
+ Computes the cocharge statistic [RigConBijection]_ on this
2365
+ rigged configuration `(\nu, J)`. The cocharge statistic is
2366
+ computed as:
2367
+
2368
+ .. MATH::
2369
+
2370
+ cc(\nu, J) = \frac{1}{2} \sum_{a \in I_0} \sum_{i > 0}
2371
+ t_a^{\vee} m_i^{(a)} \left( \sum_{j > 0} \min(i, j) L_j^{(a)}
2372
+ - p_i^{(a)} \right) + \sum_{a \in I} t_a^{\vee} \sum_{i > 0}
2373
+ \left\lvert J^{(a, i)} \right\rvert.
2374
+
2375
+ EXAMPLES::
2376
+
2377
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1],[2,2]])
2378
+ sage: sc = RC.cartan_type().as_folding().scaling_factors()
2379
+ sage: all(mg.cocharge() * sc[0] == mg.to_virtual_configuration().cocharge()
2380
+ ....: for mg in RC.module_generators)
2381
+ True
2382
+ """
2383
+ # return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0]
2384
+ cc = ZZ.zero()
2385
+ rigging_sum = ZZ.zero()
2386
+ # vct = self.parent()._folded_ct
2387
+ # sigma = vct.folding_orbit()
2388
+ # gammatilde = list(vct.scaling_factors())
2389
+ # gammatilde[-1] = 2
2390
+ for a, p in enumerate(self):
2391
+ t_check = 1 # == len(sigma[a+1]) * gammatilde[a+1] / gammatilde[0]
2392
+ for pos, i in enumerate(p._list):
2393
+ # Add the rigging
2394
+ rigging_sum += t_check * p.rigging[pos]
2395
+ # Add the L matrix contribution
2396
+ for dim in self.parent().dims:
2397
+ if dim[0] == a + 1:
2398
+ cc += t_check * min(dim[1], i)
2399
+ # Subtract the vacancy number
2400
+ cc -= t_check * p.vacancy_numbers[pos]
2401
+ return cc / ZZ(2) + rigging_sum
2402
+
2403
+ cc = cocharge