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,2039 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ r"""
3
+ Colored permutations
4
+
5
+ .. TODO::
6
+
7
+ Much of the colored permutations (and element) class can be
8
+ generalized to `G \wr S_n`
9
+ """
10
+ import itertools
11
+ from random import choice
12
+
13
+ from sage.structure.element import MultiplicativeGroupElement
14
+ from sage.structure.parent import Parent
15
+ from sage.structure.unique_representation import UniqueRepresentation
16
+ from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
17
+ from sage.misc.cachefunc import cached_method
18
+ from sage.misc.lazy_import import lazy_import
19
+ from sage.misc.misc_c import prod
20
+ from sage.arith.functions import lcm
21
+
22
+ from sage.combinat.partition_tuple import PartitionTuples, PartitionTuple
23
+ from sage.combinat.permutation import Permutations
24
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
25
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
26
+ from sage.rings.integer_ring import ZZ
27
+
28
+ lazy_import('sage.matrix.constructor', 'diagonal_matrix')
29
+ lazy_import('sage.rings.number_field.number_field', 'CyclotomicField')
30
+
31
+
32
+ class ColoredPermutation(MultiplicativeGroupElement):
33
+ """
34
+ A colored permutation.
35
+ """
36
+ def __init__(self, parent, colors, perm):
37
+ """
38
+ Initialize ``self``.
39
+
40
+ TESTS::
41
+
42
+ sage: C = ColoredPermutations(4, 3)
43
+ sage: s1,s2,t = C.gens()
44
+ sage: TestSuite(s1*s2*t).run()
45
+ """
46
+ self._colors = tuple(colors)
47
+ self._perm = perm
48
+ MultiplicativeGroupElement.__init__(self, parent=parent)
49
+
50
+ def __hash__(self):
51
+ r"""
52
+ TESTS::
53
+
54
+ sage: C = ColoredPermutations(4, 3)
55
+ sage: s1,s2,t = C.gens()
56
+ sage: for gen in s1,s2,t:
57
+ ....: assert hash(gen) ^^ hash(gen._colors) == hash(gen._perm)
58
+ """
59
+ return hash(self._perm) ^ hash(self._colors)
60
+
61
+ def _repr_(self):
62
+ """
63
+ Return a string representation of ``self``.
64
+
65
+ EXAMPLES::
66
+
67
+ sage: C = ColoredPermutations(4, 3)
68
+ sage: s1,s2,t = C.gens()
69
+ sage: s1*s2*t
70
+ [[1, 0, 0], [3, 1, 2]]
71
+ """
72
+ return repr([list(self._colors), self._perm])
73
+
74
+ def _latex_(self):
75
+ r"""
76
+ Return a latex representation of ``self``.
77
+
78
+ EXAMPLES::
79
+
80
+ sage: C = ColoredPermutations(4, 3)
81
+ sage: s1,s2,t = C.gens()
82
+ sage: latex(s1*s2*t)
83
+ [3_{1}, 1_{0}, 2_{0}]
84
+ """
85
+ ret = "["
86
+ ret += ", ".join("{}_{{{}}}".format(x, c)
87
+ for c, x in zip(self._colors, self._perm))
88
+ return ret + "]"
89
+
90
+ def __len__(self):
91
+ """
92
+ Return the length of the one line form of ``self``.
93
+
94
+ EXAMPLES::
95
+
96
+ sage: C = ColoredPermutations(2, 3)
97
+ sage: s1,s2,t = C.gens()
98
+ sage: len(s1)
99
+ 3
100
+ """
101
+ return len(self._perm)
102
+
103
+ def _mul_(self, other):
104
+ """
105
+ Multiply ``self`` and ``other``.
106
+
107
+ EXAMPLES::
108
+
109
+ sage: C = ColoredPermutations(4, 3)
110
+ sage: s1,s2,t = C.gens()
111
+ sage: s1*s2*s1 == s2*s1*s2
112
+ True
113
+ """
114
+ colors = tuple(c + other._colors[val - 1] # -1 for indexing
115
+ for c, val in zip(self._colors, self._perm))
116
+ p = self._perm._left_to_right_multiply_on_right(other._perm)
117
+ return self.__class__(self.parent(), colors, p)
118
+
119
+ def __invert__(self):
120
+ """
121
+ Return the inverse of ``self``.
122
+
123
+ EXAMPLES::
124
+
125
+ sage: C = ColoredPermutations(4, 3)
126
+ sage: s1,s2,t = C.gens()
127
+ sage: ~t # indirect doctest
128
+ [[0, 0, 3], [1, 2, 3]]
129
+ sage: all(x * ~x == C.one() for x in C.gens())
130
+ True
131
+ """
132
+ ip = ~self._perm
133
+ return self.__class__(self.parent(),
134
+ tuple(-self._colors[i - 1] for i in ip), # -1 for indexing
135
+ ip)
136
+
137
+ def __eq__(self, other):
138
+ """
139
+ Check equality.
140
+
141
+ EXAMPLES::
142
+
143
+ sage: C = ColoredPermutations(4, 3)
144
+ sage: s1,s2,t = C.gens()
145
+ sage: s1*s2*s1 == s2*s1*s2
146
+ True
147
+ sage: t^4 == C.one()
148
+ True
149
+ sage: s1*s2 == s2*s1
150
+ False
151
+ """
152
+ if not isinstance(other, ColoredPermutation):
153
+ return False
154
+ return (self.parent() is other.parent()
155
+ and self._colors == other._colors
156
+ and self._perm == other._perm)
157
+
158
+ def __ne__(self, other):
159
+ """
160
+ Check inequality.
161
+
162
+ EXAMPLES::
163
+
164
+ sage: C = ColoredPermutations(4, 3)
165
+ sage: s1,s2,t = C.gens()
166
+ sage: s1*s2*s1 != s2*s1*s2
167
+ False
168
+ sage: s1*s2 != s2*s1
169
+ True
170
+ """
171
+ return not self == other
172
+
173
+ def __iter__(self):
174
+ """
175
+ Iterate over ``self``.
176
+
177
+ EXAMPLES::
178
+
179
+ sage: C = ColoredPermutations(4, 3)
180
+ sage: s1,s2,t = C.gens()
181
+ sage: x = s1*s2*t
182
+ sage: list(x)
183
+ [(1, 3), (0, 1), (0, 2)]
184
+ """
185
+ yield from zip(self._colors, self._perm)
186
+
187
+ def one_line_form(self):
188
+ """
189
+ Return the one line form of ``self``.
190
+
191
+ EXAMPLES::
192
+
193
+ sage: C = ColoredPermutations(4, 3)
194
+ sage: s1,s2,t = C.gens()
195
+ sage: x = s1*s2*t
196
+ sage: x
197
+ [[1, 0, 0], [3, 1, 2]]
198
+ sage: x.one_line_form()
199
+ [(1, 3), (0, 1), (0, 2)]
200
+ """
201
+ return list(self)
202
+
203
+ def __getitem__(self, key):
204
+ """
205
+ Return the specified element in the one line form of ``self``.
206
+
207
+ EXAMPLES::
208
+
209
+ sage: C = ColoredPermutations(4, 3)
210
+ sage: s1,s2,t = C.gens()
211
+ sage: x = s1*s2*t
212
+ sage: x
213
+ [[1, 0, 0], [3, 1, 2]]
214
+ sage: x[1]
215
+ (0, 1)
216
+ sage: x[1:]
217
+ [(0, 1), (0, 2)]
218
+ """
219
+ if isinstance(key, slice):
220
+ return list(zip(self._colors[key], self._perm[key]))
221
+ return (self._colors[key], self._perm[key])
222
+
223
+ def colors(self):
224
+ """
225
+ Return the colors of ``self``.
226
+
227
+ EXAMPLES::
228
+
229
+ sage: C = ColoredPermutations(4, 3)
230
+ sage: s1,s2,t = C.gens()
231
+ sage: x = s1*s2*t
232
+ sage: x.colors()
233
+ [1, 0, 0]
234
+ """
235
+ return list(self._colors)
236
+
237
+ def permutation(self):
238
+ """
239
+ Return the permutation of ``self``.
240
+
241
+ This is obtained by forgetting the colors.
242
+
243
+ EXAMPLES::
244
+
245
+ sage: C = ColoredPermutations(4, 3)
246
+ sage: s1,s2,t = C.gens()
247
+ sage: x = s1*s2*t
248
+ sage: x.permutation()
249
+ [3, 1, 2]
250
+ """
251
+ return self._perm
252
+
253
+ def to_matrix(self):
254
+ """
255
+ Return a matrix of ``self``.
256
+
257
+ The colors are mapped to roots of unity.
258
+
259
+ EXAMPLES::
260
+
261
+ sage: C = ColoredPermutations(4, 3)
262
+ sage: s1,s2,t = C.gens()
263
+ sage: x = s1*s2*t*s2; x.one_line_form()
264
+ [(1, 2), (0, 1), (0, 3)]
265
+ sage: M = x.to_matrix(); M # needs sage.rings.number_field
266
+ [ 0 1 0]
267
+ [zeta4 0 0]
268
+ [ 0 0 1]
269
+
270
+ The matrix multiplication is in the *opposite* order::
271
+
272
+ sage: M == s2.to_matrix()*t.to_matrix()*s2.to_matrix()*s1.to_matrix() # needs sage.rings.number_field
273
+ True
274
+ """
275
+ Cp = CyclotomicField(self.parent()._m)
276
+ g = Cp.gen()
277
+ D = diagonal_matrix(Cp, [g ** i for i in self._colors])
278
+ return self._perm.to_matrix() * D
279
+
280
+ def has_left_descent(self, i) -> bool:
281
+ r"""
282
+ Return ``True`` if ``i`` is a left descent of ``self``.
283
+
284
+ Let `p = ((s_1, \ldots s_n), \sigma)` be a colored permutation.
285
+ We say `p` has a left `n`-descent if `s_n > 0`. If `i < n`, then
286
+ we say `p` has a left `i`-descent if either
287
+
288
+ - `s_i \neq 0, s_{i+1} = 0` and `\sigma_i < \sigma_{i+1}` or
289
+ - `s_i = s_{i+1}` and `\sigma_i > \sigma_{i+1}`.
290
+
291
+ This notion of a left `i`-descent is done in order to recursively
292
+ construct `w(p) = \sigma_i w(\sigma_i^{-1} p)`, where `w(p)`
293
+ denotes a reduced word of `p`.
294
+
295
+ EXAMPLES::
296
+
297
+ sage: C = ColoredPermutations(2, 4)
298
+ sage: s1,s2,s3,s4 = C.gens()
299
+ sage: x = s4*s1*s2*s3*s4
300
+ sage: [x.has_left_descent(i) for i in C.index_set()]
301
+ [True, False, False, True]
302
+
303
+ sage: C = ColoredPermutations(1, 5)
304
+ sage: s1,s2,s3,s4 = C.gens()
305
+ sage: x = s4*s1*s2*s3*s4
306
+ sage: [x.has_left_descent(i) for i in C.index_set()]
307
+ [True, False, False, True]
308
+
309
+ sage: C = ColoredPermutations(3, 3)
310
+ sage: x = C([[2,1,0],[3,1,2]])
311
+ sage: [x.has_left_descent(i) for i in C.index_set()]
312
+ [False, True, False]
313
+
314
+ sage: C = ColoredPermutations(4, 4)
315
+ sage: x = C([[2,1,0,1],[3,2,4,1]])
316
+ sage: [x.has_left_descent(i) for i in C.index_set()]
317
+ [False, True, False, True]
318
+ """
319
+ if self.parent()._m == 1:
320
+ return self._perm[i - 1] > self._perm[i]
321
+
322
+ if self.parent()._p > 1:
323
+ raise NotImplementedError("only implemented for p = 1")
324
+
325
+ if i == self.parent()._n:
326
+ return self._colors[-1] != 0
327
+ if self._colors[i - 1] != 0:
328
+ return self._colors[i] == 0 or self._perm[i - 1] < self._perm[i]
329
+ return self._colors[i] == 0 and self._perm[i - 1] > self._perm[i]
330
+
331
+ def reduced_word(self):
332
+ r"""
333
+ Return a word in the simple reflections to obtain ``self``.
334
+
335
+ EXAMPLES::
336
+
337
+ sage: C = ColoredPermutations(3, 3)
338
+ sage: x = C([[2,1,0],[3,1,2]])
339
+ sage: x.reduced_word()
340
+ [2, 1, 3, 2, 1, 3, 3]
341
+
342
+ sage: C = ColoredPermutations(4, 4)
343
+ sage: x = C([[2,1,0,1],[3,2,4,1]])
344
+ sage: x.reduced_word()
345
+ [2, 1, 4, 3, 2, 1, 4, 3, 2, 4, 4, 3]
346
+
347
+ TESTS::
348
+
349
+ sage: C = ColoredPermutations(3, 3)
350
+ sage: all(C.from_reduced_word(p.reduced_word()) == p for p in C)
351
+ True
352
+ """
353
+ if self == self.parent().one():
354
+ return []
355
+ I = self.parent().index_set()
356
+ sinv = self.parent()._inverse_simple_reflections()
357
+ for i in I:
358
+ if self.has_left_descent(i):
359
+ return [i] + (sinv[i] * self).reduced_word()
360
+ assert False, "BUG in reduced_word"
361
+
362
+ def length(self):
363
+ r"""
364
+ Return the length of ``self`` in generating reflections.
365
+
366
+ This is the minimal numbers of generating reflections needed
367
+ to obtain ``self``.
368
+
369
+ EXAMPLES::
370
+
371
+ sage: C = ColoredPermutations(3, 3)
372
+ sage: x = C([[2,1,0],[3,1,2]])
373
+ sage: x.length()
374
+ 7
375
+
376
+ sage: C = ColoredPermutations(4, 4)
377
+ sage: x = C([[2,1,0,1],[3,2,4,1]])
378
+ sage: x.length()
379
+ 12
380
+
381
+ TESTS::
382
+
383
+ sage: C = ColoredPermutations(3, 3)
384
+ sage: d = [p.length() for p in C]
385
+ sage: [d.count(i) for i in range(14)]
386
+ [1, 3, 6, 10, 15, 20, 23, 24, 23, 19, 12, 5, 1, 0]
387
+ sage: d = [p.length() for p in ReflectionGroup([3, 1, 3])] # optional - gap3
388
+ sage: [d.count(i) for i in range(14)] # optional - gap3
389
+ [1, 3, 6, 10, 15, 20, 23, 24, 23, 19, 12, 5, 1, 0]
390
+
391
+ sage: C = ColoredPermutations(4, 3)
392
+ sage: d = [p.length() for p in C]
393
+ sage: [d.count(i) for i in range(17)]
394
+ [1, 3, 6, 11, 18, 27, 36, 44, 50, 52, 49, 40, 27, 14, 5, 1, 0]
395
+ sage: d = [p.length() for p in ReflectionGroup([4, 1, 3])] # optional - gap3
396
+ sage: [d.count(i) for i in range(17)] # optional - gap3
397
+ [1, 3, 6, 11, 18, 27, 36, 44, 50, 52, 49, 40, 27, 14, 5, 1, 0]
398
+
399
+ sage: C = ColoredPermutations(3, 4)
400
+ sage: d = [p.length() for p in C]
401
+ sage: [d.count(i) for i in range(22)]
402
+ [1, 4, 10, 20, 35, 56, 82, 112, 144, 174, 197,
403
+ 209, 209, 197, 173, 138, 96, 55, 24, 7, 1, 0]
404
+ sage: d = [p.length() for p in ReflectionGroup([3, 1, 4])] # optional - gap3
405
+ sage: [d.count(i) for i in range(22)] # optional - gap3
406
+ [1, 4, 10, 20, 35, 56, 82, 112, 144, 174, 197,
407
+ 209, 209, 197, 173, 138, 96, 55, 24, 7, 1, 0]
408
+ """
409
+ return ZZ(len(self.reduced_word()))
410
+
411
+ # TODO: Parts of this should be put in the category of complex
412
+ # reflection groups
413
+
414
+
415
+ class ShephardToddFamilyGroup(UniqueRepresentation, Parent):
416
+ r"""
417
+ The Shephard-Todd family complex reflection group `G(m, p, n)`
418
+ realized as a subgroup of :class:`colored permutations
419
+ <sage.combinat.colored_permutations.ColoredPermutations>`.
420
+
421
+ A general complex reflection group is a subgroup of `GL(V)`, where
422
+ `V` is a `\CC` vector space, that is generated by *reflections*,
423
+ diagonalizable matrices with at most one eigenvalue not equal to `1`.
424
+ The group of colored permutations `G(m, 1, n)` are the generalized
425
+ permutation matrices whose entries are `m`-th roots of unity.
426
+ For `p | m`, the group `G(m, p, n)` is the index `p` subgroup
427
+ such that the product of the entries is a `m/p`-th root of unity.
428
+
429
+ By the (Chevalley-)Shephard-Todd classification of irreducible
430
+ finite complex reflection groups, the groups `G(m, p, n)` (with
431
+ `G(2, 2, 2)` being exceptionally reducible since it is the Klein
432
+ four group) form the only infinite family with an additional 34
433
+ exceptional groups `G_k`, where `4 \leq k \leq 37`. To avoid
434
+ ambiguities, we refer to `G(m, p, n)` as the *Shephard-Todd family
435
+ complex reflection group*.
436
+
437
+ INPUT:
438
+
439
+ - ``m`` -- positive integer
440
+ - ``p`` -- positive integer dividing ``m``
441
+ - ``n`` -- positive integer
442
+
443
+ REFERENCES:
444
+
445
+ - :wikipedia:`Complex_reflection_group`
446
+
447
+ EXAMPLES::
448
+
449
+ sage: # needs sage.groups
450
+ sage: groups.misc.ShephardToddFamily(6, 1, 4)
451
+ 6-colored permutations of size 4
452
+ sage: groups.misc.ShephardToddFamily(6, 2, 4)
453
+ Complex reflection group G(6, 2, 4)
454
+ sage: groups.misc.ShephardToddFamily(6, 3, 4)
455
+ Complex reflection group G(6, 3, 4)
456
+ sage: groups.misc.ShephardToddFamily(6, 6, 4)
457
+ Complex reflection group G(6, 6, 4)
458
+ """
459
+ @staticmethod
460
+ def __classcall_private__(cls, m, p, n):
461
+ r"""
462
+ Dispatch to :class:`sage.combinat.colored_permutations.ColoredPermutations`
463
+ when ``p == 1``.
464
+
465
+ EXAMPLES::
466
+
467
+ sage: # needs sage.groups
468
+ sage: G = groups.misc.ShephardToddFamily(6, 1, 3)
469
+ sage: C = ColoredPermutations(6, 3)
470
+ sage: G is C
471
+ True
472
+ """
473
+ if p == 1:
474
+ return ColoredPermutations(m, n)
475
+ return super().__classcall__(cls, m, p, n)
476
+
477
+ def __init__(self, m, p, n):
478
+ r"""
479
+ Initialize ``self``.
480
+
481
+ EXAMPLES::
482
+
483
+ sage: # needs sage.groups
484
+ sage: G = groups.misc.ShephardToddFamily(6, 2, 3)
485
+ sage: TestSuite(G).run()
486
+ sage: G = groups.misc.ShephardToddFamily(8, 4, 1)
487
+ sage: TestSuite(G).run()
488
+
489
+ We skip some of the Coxeter group tests since the left descents
490
+ have not been implemented::
491
+
492
+ sage: # needs sage.groups
493
+ sage: coxeter_tests = ["_test_descents", "_test_has_descent",
494
+ ....: "_test_reduced_word", "_test_simple_projections"]
495
+ sage: G = groups.misc.ShephardToddFamily(2, 2, 3)
496
+ sage: TestSuite(G).run(skip=coxeter_tests)
497
+ sage: G = groups.misc.ShephardToddFamily(4, 4, 2)
498
+ sage: TestSuite(G).run(skip=coxeter_tests)
499
+ """
500
+ if m <= 0:
501
+ raise ValueError("m must be a positive integer")
502
+ self._m = ZZ(m)
503
+ self._p = ZZ(p)
504
+ if not self._p.divides(self._m):
505
+ raise ValueError("{} does not divide {}".format(self._p, self._m))
506
+ self._n = ZZ(n)
507
+ self._C = IntegerModRing(self._m)
508
+ self._P = Permutations(self._n)
509
+
510
+ if (self._p == 1 and (self._m == 1 or self._m == 2)
511
+ or (self._p == 2 and self._m == 2)
512
+ or (self._n == 2 and self._p == self._m)):
513
+ from sage.categories.finite_coxeter_groups import FiniteCoxeterGroups
514
+ category = FiniteCoxeterGroups()
515
+ if not (self._n == self._m == self._p == 2): # special case of type D_2
516
+ category = category.Irreducible()
517
+ else:
518
+ from sage.categories.complex_reflection_groups import ComplexReflectionGroups
519
+ category = ComplexReflectionGroups().Finite().Irreducible()
520
+ if self._p in [1, self._m]:
521
+ category = category.WellGenerated()
522
+ Parent.__init__(self, category=category)
523
+
524
+ def _repr_(self):
525
+ """
526
+ Return a string representation of ``self``.
527
+
528
+ EXAMPLES::
529
+
530
+ sage: groups.misc.ShephardToddFamily(6, 2, 3) # needs sage.groups
531
+ Complex reflection group G(6, 2, 3)
532
+ """
533
+ return "Complex reflection group G({}, {}, {})".format(self._m, self._p, self._n)
534
+
535
+ @cached_method
536
+ def index_set(self):
537
+ r"""
538
+ Return the index set of ``self``.
539
+
540
+ EXAMPLES::
541
+
542
+ sage: C = ColoredPermutations(3, 4)
543
+ sage: C.index_set()
544
+ (1, 2, 3, 4)
545
+
546
+ sage: C = ColoredPermutations(1, 4)
547
+ sage: C.index_set()
548
+ (1, 2, 3)
549
+
550
+ sage: G = groups.misc.ShephardToddFamily(6, 6, 4) # needs sage.groups
551
+ sage: G.index_set() # needs sage.groups
552
+ (1, 2, 3, 4)
553
+
554
+ sage: G = groups.misc.ShephardToddFamily(6, 2, 4) # needs sage.groups
555
+ sage: G.index_set() # needs sage.groups
556
+ (1, 2, 3, 4, 5)
557
+
558
+ sage: G = groups.misc.ShephardToddFamily(6, 6, 1) # needs sage.groups
559
+ sage: G.index_set() # needs sage.groups
560
+ ()
561
+
562
+ sage: G = groups.misc.ShephardToddFamily(6, 2, 1) # needs sage.groups
563
+ sage: G.index_set() # needs sage.groups
564
+ (1,)
565
+
566
+ TESTS::
567
+
568
+ sage: S = SignedPermutations(4)
569
+ sage: S.index_set()
570
+ (1, 2, 3, 4)
571
+ """
572
+ n = self._n
573
+ if self._m != 1 and self._n > 1:
574
+ n += 1
575
+ if self._p != 1 and self._p != self._m:
576
+ n += 1
577
+ return tuple(range(1, n))
578
+
579
+ def coxeter_matrix(self):
580
+ r"""
581
+ Return the Coxeter matrix of ``self``.
582
+
583
+ When the group is imprimitive and not a Coxeter group,
584
+ this returns ``None``.
585
+
586
+ EXAMPLES::
587
+
588
+ sage: C = ColoredPermutations(3, 4)
589
+ sage: C.coxeter_matrix() # needs sage.graphs sage.modules
590
+ [1 3 2 2]
591
+ [3 1 3 2]
592
+ [2 3 1 4]
593
+ [2 2 4 1]
594
+
595
+ sage: C = ColoredPermutations(1, 4)
596
+ sage: C.coxeter_matrix() # needs sage.graphs sage.modules
597
+ [1 3 2]
598
+ [3 1 3]
599
+ [2 3 1]
600
+
601
+ sage: G = groups.misc.ShephardToddFamily(2, 2, 3) # needs sage.groups
602
+ sage: G.coxeter_matrix() # needs sage.groups
603
+ [1 3 3]
604
+ [3 1 2]
605
+ [3 2 1]
606
+
607
+ sage: G = groups.misc.ShephardToddFamily(2, 2, 2) # needs sage.groups
608
+ sage: G.coxeter_matrix() # needs sage.groups
609
+ [1 2]
610
+ [2 1]
611
+
612
+ sage: G = groups.misc.ShephardToddFamily(2, 2, 1) # needs sage.groups
613
+ sage: G.coxeter_matrix() # needs sage.groups
614
+ [1]
615
+
616
+ sage: G = groups.misc.ShephardToddFamily(5, 5, 1) # needs sage.groups
617
+ sage: G.coxeter_matrix() # needs sage.groups
618
+ []
619
+
620
+ sage: G = groups.misc.ShephardToddFamily(4, 4, 2) # needs sage.groups
621
+ sage: G.coxeter_matrix() # needs sage.groups
622
+ [1 4]
623
+ [4 1]
624
+
625
+ sage: G = groups.misc.ShephardToddFamily(7, 7, 2) # needs sage.groups
626
+ sage: G.coxeter_matrix() # needs sage.groups
627
+ [1 7]
628
+ [7 1]
629
+
630
+ sage: G = groups.misc.ShephardToddFamily(6, 3, 1) # needs sage.groups
631
+ sage: G.coxeter_matrix() is None # needs sage.groups
632
+ True
633
+ sage: G = groups.misc.ShephardToddFamily(6, 3, 4) # needs sage.groups
634
+ sage: G.coxeter_matrix() is None # needs sage.groups
635
+ True
636
+
637
+ TESTS::
638
+
639
+ sage: S = SignedPermutations(4)
640
+ sage: S.coxeter_matrix() # needs sage.graphs sage.modules
641
+ [1 3 2 2]
642
+ [3 1 3 2]
643
+ [2 3 1 4]
644
+ [2 2 4 1]
645
+ """
646
+ from sage.combinat.root_system.cartan_type import CartanType
647
+ if self._p == 1:
648
+ if self._m == 1:
649
+ return CartanType(['A', self._n - 1]).coxeter_matrix()
650
+ return CartanType(['B', self._n]).coxeter_matrix()
651
+ if self._p == 2 and self._m == 2:
652
+ if self._n == 1:
653
+ return CartanType(['A', self._n]).coxeter_matrix()
654
+ return CartanType(['D', self._n]).coxeter_matrix()
655
+ if self._n == 2 and self._p == self._m:
656
+ return CartanType(['I', self._m]).coxeter_matrix()
657
+ if self._p == self._m and self._n == 1:
658
+ return CartanType(['A', 0]).coxeter_matrix()
659
+
660
+ @cached_method
661
+ def one(self):
662
+ """
663
+ Return the identity element of ``self``.
664
+
665
+ EXAMPLES::
666
+
667
+ sage: C = ColoredPermutations(4, 3)
668
+ sage: C.one()
669
+ [[0, 0, 0], [1, 2, 3]]
670
+ """
671
+ return self.element_class(self, [self._C.zero()] * self._n,
672
+ self._P.identity())
673
+
674
+ def random_element(self):
675
+ r"""
676
+ Return an element of ``self`` at random.
677
+
678
+ EXAMPLES::
679
+
680
+ sage: C = ColoredPermutations(4, 3)
681
+ sage: s = C.random_element(); s # random
682
+ [[0, 2, 1], [2, 1, 3]]
683
+ sage: s in C
684
+ True
685
+ """
686
+ colors = [self._C.random_element() for _ in range(self._n)]
687
+ if self._p > 1:
688
+ while sum(colors) % self._p:
689
+ colors = [self._C.random_element() for _ in range(self._n)]
690
+ return self.element_class(self, colors, self._P.random_element())
691
+
692
+ def simple_reflection(self, i):
693
+ r"""
694
+ Return the ``i``-th simple reflection of ``self``.
695
+
696
+ EXAMPLES::
697
+
698
+ sage: C = ColoredPermutations(4, 3)
699
+ sage: C.gens()
700
+ ([[0, 0, 0], [2, 1, 3]], [[0, 0, 0], [1, 3, 2]], [[0, 0, 1], [1, 2, 3]])
701
+ sage: C.simple_reflection(2)
702
+ [[0, 0, 0], [1, 3, 2]]
703
+ sage: C.simple_reflection(3)
704
+ [[0, 0, 1], [1, 2, 3]]
705
+
706
+ sage: S = SignedPermutations(4)
707
+ sage: S.simple_reflection(1)
708
+ [2, 1, 3, 4]
709
+ sage: S.simple_reflection(4)
710
+ [1, 2, 3, -4]
711
+
712
+ sage: G = groups.misc.ShephardToddFamily(4, 2, 3) # needs sage.groups
713
+ sage: list(G.simple_reflections()) # needs sage.groups
714
+ [[[0, 0, 0], [2, 1, 3]],
715
+ [[0, 0, 0], [1, 3, 2]],
716
+ [[0, 1, 3], [1, 3, 2]],
717
+ [[0, 0, 2], [1, 2, 3]]]
718
+
719
+ sage: G = groups.misc.ShephardToddFamily(8, 4, 1) # needs sage.groups
720
+ sage: G.simple_reflections() # needs sage.groups
721
+ Finite family {1: [[4], [1]]}
722
+
723
+ sage: G = groups.misc.ShephardToddFamily(8, 8, 1) # needs sage.groups
724
+ sage: G.simple_reflections() # needs sage.groups
725
+ Finite family {}
726
+ """
727
+ if i not in self.index_set():
728
+ raise ValueError("i must be in the index set")
729
+ colors = [self._C.zero()] * self._n
730
+ if i < self._n:
731
+ p = list(range(1, self._n + 1))
732
+ p[i - 1] = i + 1
733
+ p[i] = i
734
+ return self.element_class(self, colors, self._P(p))
735
+
736
+ colors[-1] = self._C.one()
737
+ sn = self.element_class(self, colors, self._P.identity())
738
+ if self._p == 1:
739
+ return sn
740
+
741
+ if i == self._n + 1 or self._n == 1:
742
+ return sn ** self._p
743
+
744
+ snm = self.simple_reflection(self._n-1)
745
+ return sn**(self._m-1) * snm * sn
746
+
747
+ @cached_method
748
+ def _inverse_simple_reflections(self):
749
+ """
750
+ Return the inverse of the simple reflections of ``self``.
751
+
752
+ .. WARNING::
753
+
754
+ This returns a ``dict`` that should not be mutated since
755
+ the result is cached.
756
+
757
+ EXAMPLES::
758
+
759
+ sage: C = ColoredPermutations(4, 3)
760
+ sage: C._inverse_simple_reflections()
761
+ {1: [[0, 0, 0], [2, 1, 3]],
762
+ 2: [[0, 0, 0], [1, 3, 2]],
763
+ 3: [[0, 0, 3], [1, 2, 3]]}
764
+ """
765
+ s = self.simple_reflections()
766
+ return {i: ~s[i] for i in self.index_set()}
767
+
768
+ @cached_method
769
+ def gens(self) -> tuple:
770
+ """
771
+ Return the generators of ``self``.
772
+
773
+ EXAMPLES::
774
+
775
+ sage: C = ColoredPermutations(4, 3)
776
+ sage: C.gens()
777
+ ([[0, 0, 0], [2, 1, 3]],
778
+ [[0, 0, 0], [1, 3, 2]],
779
+ [[0, 0, 1], [1, 2, 3]])
780
+
781
+ sage: S = SignedPermutations(4)
782
+ sage: S.gens()
783
+ ([2, 1, 3, 4], [1, 3, 2, 4], [1, 2, 4, 3], [1, 2, 3, -4])
784
+ """
785
+ return tuple(self.simple_reflection(i) for i in self.index_set())
786
+
787
+ def matrix_group(self):
788
+ """
789
+ Return the matrix group corresponding to ``self``.
790
+
791
+ EXAMPLES::
792
+
793
+ sage: C = ColoredPermutations(4, 3)
794
+ sage: C.matrix_group() # needs sage.modules sage.rings.number_field
795
+ Matrix group over Cyclotomic Field of order 4 and degree 2 with 3 generators (
796
+ [0 1 0] [1 0 0] [ 1 0 0]
797
+ [1 0 0] [0 0 1] [ 0 1 0]
798
+ [0 0 1], [0 1 0], [ 0 0 zeta4]
799
+ )
800
+ """
801
+ from sage.groups.matrix_gps.finitely_generated import MatrixGroup
802
+ return MatrixGroup([g.to_matrix() for g in self.gens()])
803
+
804
+ def as_permutation_group(self):
805
+ r"""
806
+ Return the permutation group corresponding to ``self``.
807
+
808
+ EXAMPLES::
809
+
810
+ sage: C = ColoredPermutations(4, 3)
811
+ sage: C.as_permutation_group() # needs sage.groups
812
+ Complex reflection group G(4, 1, 3) as a permutation group
813
+ """
814
+ from sage.groups.perm_gps.permgroup_named import ComplexReflectionGroup
815
+ return ComplexReflectionGroup(self._m, self._p, self._n)
816
+
817
+ def _element_constructor_(self, x):
818
+ r"""
819
+ Construct an element of ``self`` from ``x``.
820
+
821
+ INPUT:
822
+
823
+ - ``x`` -- either a list of pairs ``(color, element)`` or a pair of
824
+ lists ``(colors, elements)``
825
+
826
+ TESTS::
827
+
828
+ sage: C = ColoredPermutations(4, 3)
829
+ sage: x = C([(2,1), (3,3), (3,2)]); x
830
+ [[2, 3, 3], [1, 3, 2]]
831
+ sage: x == C([[2,3,3], [1,3,2]])
832
+ True
833
+ """
834
+ if isinstance(x, self.element_class) and x.parent() is self:
835
+ return self
836
+ x = list(x)
837
+ if isinstance(x[0], tuple):
838
+ c = []
839
+ p = []
840
+ for k in x:
841
+ if len(k) != 2:
842
+ raise ValueError("input must be pairs (color, element)")
843
+ c.append(self._C(k[0]))
844
+ p.append(k[1])
845
+ if self._p > 1 and sum(c) % self._p:
846
+ raise ValueError("{} is not an element".format([c, p]))
847
+ return self.element_class(self, c, self._P(p))
848
+
849
+ if len(x) != 2:
850
+ raise ValueError("input must be a pair of a list of colors and a permutation")
851
+ if self._p > 1 and sum(x[0]) % self._p:
852
+ raise ValueError("{} is not an element".format(x))
853
+ return self.element_class(self, [self._C(v) for v in x[0]], self._P(x[1]))
854
+
855
+ def _coerce_map_from_(self, C):
856
+ r"""
857
+ Return a coerce map from ``C`` if it exists and ``None`` otherwise.
858
+
859
+ EXAMPLES::
860
+
861
+ sage: C = ColoredPermutations(2, 3)
862
+ sage: S = SignedPermutations(3)
863
+ sage: C.has_coerce_map_from(S)
864
+ True
865
+
866
+ sage: C = ColoredPermutations(4, 3)
867
+ sage: C.has_coerce_map_from(S)
868
+ False
869
+ sage: S = SignedPermutations(4)
870
+ sage: C.has_coerce_map_from(S)
871
+ False
872
+
873
+ sage: P = Permutations(3)
874
+ sage: C.has_coerce_map_from(P)
875
+ True
876
+ sage: P = Permutations(4)
877
+ sage: C.has_coerce_map_from(P)
878
+ False
879
+ """
880
+ if isinstance(C, Permutations) and C.n == self._n:
881
+ return lambda P, x: P.element_class(P, [P._C.zero()] * P._n, x)
882
+ if self._m == 2 and self._p == 1 and isinstance(C, SignedPermutations) and C._n == self._n:
883
+ return lambda P, x: P.element_class(P,
884
+ [P._C.zero() if v == 1 else P._C.one()
885
+ for v in x._colors],
886
+ x._perm)
887
+ return super()._coerce_map_from_(C)
888
+
889
+ def __iter__(self):
890
+ r"""
891
+ Iterate over ``self``.
892
+
893
+ EXAMPLES::
894
+
895
+ sage: G = groups.misc.ShephardToddFamily(6, 3, 2) # needs sage.groups
896
+ sage: [x for x in G] # needs sage.groups
897
+ [[[0, 0], [1, 2]],
898
+ [[0, 0], [2, 1]],
899
+ [[0, 3], [1, 2]],
900
+ [[0, 3], [2, 1]],
901
+ [[1, 2], [1, 2]],
902
+ [[1, 2], [2, 1]],
903
+ [[1, 5], [1, 2]],
904
+ [[1, 5], [2, 1]],
905
+ [[2, 1], [1, 2]],
906
+ [[2, 1], [2, 1]],
907
+ [[2, 4], [1, 2]],
908
+ [[2, 4], [2, 1]],
909
+ [[3, 0], [1, 2]],
910
+ [[3, 0], [2, 1]],
911
+ [[3, 3], [1, 2]],
912
+ [[3, 3], [2, 1]],
913
+ [[4, 2], [1, 2]],
914
+ [[4, 2], [2, 1]],
915
+ [[4, 5], [1, 2]],
916
+ [[4, 5], [2, 1]],
917
+ [[5, 1], [1, 2]],
918
+ [[5, 1], [2, 1]],
919
+ [[5, 4], [1, 2]],
920
+ [[5, 4], [2, 1]]]
921
+ """
922
+ for c in itertools.product(self._C, repeat=self._n):
923
+ if sum(c) % self._p:
924
+ continue
925
+ for perm in self._P:
926
+ yield self.element_class(self, c, perm)
927
+
928
+ def cardinality(self):
929
+ r"""
930
+ Return the cardinality of ``self``.
931
+
932
+ EXAMPLES::
933
+
934
+ sage: C = ColoredPermutations(4, 3)
935
+ sage: C.cardinality()
936
+ 384
937
+ sage: C.cardinality() == 4**3 * factorial(3)
938
+ True
939
+ """
940
+ ret = self._m ** self._n * self._P.cardinality()
941
+ if self._p == 1:
942
+ return ret
943
+ return ret // self._p
944
+
945
+ order = cardinality
946
+
947
+ def rank(self):
948
+ """
949
+ Return the rank of ``self``.
950
+
951
+ The rank of a complex reflection group is equal to the dimension
952
+ of the complex vector space the group acts on.
953
+
954
+ EXAMPLES::
955
+
956
+ sage: C = ColoredPermutations(4, 12)
957
+ sage: C.rank()
958
+ 12
959
+ sage: C = ColoredPermutations(7, 4)
960
+ sage: C.rank()
961
+ 4
962
+ sage: C = ColoredPermutations(1, 4)
963
+ sage: C.rank()
964
+ 3
965
+ """
966
+ if self._m == 1:
967
+ return self._n - 1
968
+ return self._n
969
+
970
+ def degrees(self) -> tuple:
971
+ r"""
972
+ Return the degrees of ``self``.
973
+
974
+ The degrees of a complex reflection group are the degrees of
975
+ the fundamental invariants of the ring of polynomial invariants.
976
+
977
+ If `m = 1`, then we are in the special case of the symmetric group
978
+ and the degrees are `(2, 3, \ldots, n, n+1)`. Otherwise the degrees
979
+ are `(m, 2m, \ldots, nm)`.
980
+
981
+ EXAMPLES::
982
+
983
+ sage: C = ColoredPermutations(4, 3)
984
+ sage: C.degrees()
985
+ (4, 8, 12)
986
+ sage: S = ColoredPermutations(1, 3)
987
+ sage: S.degrees()
988
+ (2, 3)
989
+ sage: G = groups.misc.ShephardToddFamily(6, 2, 3) # needs sage.groups
990
+ sage: G.degrees() # needs sage.groups
991
+ (6, 9, 12)
992
+
993
+ We now check that the product of the degrees is equal to the
994
+ cardinality of ``self``::
995
+
996
+ sage: prod(C.degrees()) == C.cardinality()
997
+ True
998
+ sage: prod(S.degrees()) == S.cardinality()
999
+ True
1000
+ sage: prod(G.degrees()) == G.cardinality() # needs sage.groups
1001
+ True
1002
+ """
1003
+ # For the usual symmetric group (self._m=1) we need to start at 2
1004
+ start = 2 if self._m == 1 else 1
1005
+ degrees = [self._m * i for i in range(start, self._n)]
1006
+ degrees.append(self._m * self._n // self._p)
1007
+ return tuple(sorted(degrees))
1008
+
1009
+ def codegrees(self) -> tuple:
1010
+ r"""
1011
+ Return the codegrees of ``self``.
1012
+
1013
+ Let `G` be a complex reflection group. The codegrees
1014
+ `d_1^* \leq d_2^* \leq \cdots \leq d_{\ell}^*` of `G` can be
1015
+ defined by:
1016
+
1017
+ .. MATH::
1018
+
1019
+ \prod_{i=1}^{\ell} (q - d_i^* - 1)
1020
+ = \sum_{g \in G} \det(g) q^{\dim(V^g)},
1021
+
1022
+ where `V` is the natural complex vector space that `G` acts on
1023
+ and `\ell` is the :meth:`rank`.
1024
+
1025
+ If `m = 1`, then we are in the special case of the symmetric group
1026
+ and the codegrees are `(n-2, n-3, \ldots 1, 0)`. Otherwise the degrees
1027
+ are `((n-1)m, (n-2)m, \ldots, m, 0)`.
1028
+
1029
+ EXAMPLES::
1030
+
1031
+ sage: C = ColoredPermutations(4, 3)
1032
+ sage: C.codegrees()
1033
+ (8, 4, 0)
1034
+ sage: S = ColoredPermutations(1, 3)
1035
+ sage: S.codegrees()
1036
+ (1, 0)
1037
+ sage: G = groups.misc.ShephardToddFamily(6, 2, 3) # needs sage.groups
1038
+ sage: G.codegrees() # needs sage.groups
1039
+ (12, 6, 0)
1040
+
1041
+ TESTS:
1042
+
1043
+ We check the polynomial identity::
1044
+
1045
+ sage: R.<q> = ZZ[]
1046
+ sage: C = ColoredPermutations(3, 2)
1047
+ sage: f = prod(q - ds - 1 for ds in C.codegrees())
1048
+ sage: d = lambda x: sum(1 for e in x.to_matrix().eigenvalues() if e == 1)
1049
+ sage: g = sum(det(x.to_matrix()) * q**d(x) for x in C) # needs sage.modules sage.rings.number_field
1050
+ sage: f == g # needs sage.modules sage.rings.number_field
1051
+ True
1052
+ """
1053
+ # Special case for the usual symmetric group
1054
+ if self._m == 1:
1055
+ return tuple([ZZ(v) for v in reversed(range(self._n-1))])
1056
+ if self._p < self._m:
1057
+ return tuple([self._m * i for i in reversed(range(self._n))])
1058
+ codegrees = [self._m * i for i in reversed(range(self._n-1))]
1059
+ codegrees.append((self._n-1)*self._m - self._n)
1060
+ return tuple(sorted(codegrees, reverse=True))
1061
+
1062
+ def number_of_reflection_hyperplanes(self):
1063
+ """
1064
+ Return the number of reflection hyperplanes of ``self``.
1065
+
1066
+ The number of reflection hyperplanes of a complex reflection
1067
+ group is equal to the sum of the codegrees plus the rank.
1068
+
1069
+ EXAMPLES::
1070
+
1071
+ sage: C = ColoredPermutations(1, 2)
1072
+ sage: C.number_of_reflection_hyperplanes()
1073
+ 1
1074
+ sage: C = ColoredPermutations(1, 3)
1075
+ sage: C.number_of_reflection_hyperplanes()
1076
+ 3
1077
+ sage: C = ColoredPermutations(4, 12)
1078
+ sage: C.number_of_reflection_hyperplanes()
1079
+ 276
1080
+ """
1081
+ return sum(self.codegrees()) + self.rank()
1082
+
1083
+ def fixed_point_polynomial(self, q=None):
1084
+ r"""
1085
+ The fixed point polynomial of ``self``.
1086
+
1087
+ The fixed point polynomial `f_G` of a complex reflection group `G`
1088
+ is counting the dimensions of fixed points subspaces:
1089
+
1090
+ .. MATH::
1091
+
1092
+ f_G(q) = \sum_{w \in W} q^{\dim V^w}.
1093
+
1094
+ Furthermore, let `d_1, d_2, \ldots, d_{\ell}` be the degrees of `G`,
1095
+ where `\ell` is the :meth:`rank`. Then the fixed point polynomial
1096
+ is given by
1097
+
1098
+ .. MATH::
1099
+
1100
+ f_G(q) = \prod_{i=1}^{\ell} (q + d_i - 1).
1101
+
1102
+ INPUT:
1103
+
1104
+ - ``q`` -- (default: the generator of ``ZZ['q']``) the parameter `q`
1105
+
1106
+ EXAMPLES::
1107
+
1108
+ sage: C = ColoredPermutations(4, 3)
1109
+ sage: C.fixed_point_polynomial()
1110
+ q^3 + 21*q^2 + 131*q + 231
1111
+
1112
+ sage: S = ColoredPermutations(1, 3)
1113
+ sage: S.fixed_point_polynomial()
1114
+ q^2 + 3*q + 2
1115
+
1116
+ TESTS:
1117
+
1118
+ We check the against the degrees and codegrees::
1119
+
1120
+ sage: R.<q> = ZZ[]
1121
+ sage: C = ColoredPermutations(4, 3)
1122
+ sage: C.fixed_point_polynomial(q) == prod(q + d - 1 for d in C.degrees())
1123
+ True
1124
+ """
1125
+ if q is None:
1126
+ q = PolynomialRing(ZZ, 'q').gen(0)
1127
+ return prod(q + d - 1 for d in self.degrees())
1128
+
1129
+ def is_well_generated(self):
1130
+ r"""
1131
+ Return if ``self`` is a well-generated complex reflection group.
1132
+
1133
+ A complex reflection group `G` is well-generated if it is
1134
+ generated by `\ell` reflections. Equivalently, `G` is well-generated
1135
+ if `d_i + d_i^* = d_{\ell}` for all `1 \leq i \leq \ell`.
1136
+
1137
+ EXAMPLES::
1138
+
1139
+ sage: C = ColoredPermutations(4, 3)
1140
+ sage: C.is_well_generated()
1141
+ True
1142
+ sage: C = ColoredPermutations(2, 8)
1143
+ sage: C.is_well_generated()
1144
+ True
1145
+ sage: C = ColoredPermutations(1, 4)
1146
+ sage: C.is_well_generated()
1147
+ True
1148
+ """
1149
+ if self._p not in [1, self._m]:
1150
+ return False
1151
+ deg = self.degrees()
1152
+ codeg = self.codegrees()
1153
+ return all(deg[-1] == d + dstar for d, dstar in zip(deg, codeg))
1154
+
1155
+ Element = ColoredPermutation
1156
+
1157
+
1158
+ class ColoredPermutations(ShephardToddFamilyGroup):
1159
+ r"""
1160
+ The group of `m`-colored permutations on `\{1, 2, \ldots, n\}`.
1161
+
1162
+ Let `S_n` be the symmetric group on `n` letters and `C_m` be the cyclic
1163
+ group of order `m`. The `m`-colored permutation group on `n` letters
1164
+ is given by `P_n^m = C_m \wr S_n`. This is also the complex reflection
1165
+ group `G(m, 1, n)`.
1166
+
1167
+ We define our multiplication by
1168
+
1169
+ .. MATH::
1170
+
1171
+ ((s_1, \ldots s_n), \sigma) \cdot ((t_1, \ldots, t_n), \tau)
1172
+ = ((s_1 t_{\sigma(1)}, \ldots, s_n t_{\sigma(n)}), \tau \sigma).
1173
+
1174
+ EXAMPLES::
1175
+
1176
+ sage: C = ColoredPermutations(4, 3); C
1177
+ 4-colored permutations of size 3
1178
+ sage: s1,s2,t = C.gens()
1179
+ sage: (s1, s2, t)
1180
+ ([[0, 0, 0], [2, 1, 3]], [[0, 0, 0], [1, 3, 2]], [[0, 0, 1], [1, 2, 3]])
1181
+ sage: s1*s2
1182
+ [[0, 0, 0], [3, 1, 2]]
1183
+ sage: s1*s2*s1 == s2*s1*s2
1184
+ True
1185
+ sage: t^4 == C.one()
1186
+ True
1187
+ sage: s2*t*s2
1188
+ [[0, 1, 0], [1, 2, 3]]
1189
+
1190
+ We can also create a colored permutation by passing
1191
+ an iterable consisting of tuples consisting of ``(color, element)``::
1192
+
1193
+ sage: x = C([(2,1), (3,3), (3,2)]); x
1194
+ [[2, 3, 3], [1, 3, 2]]
1195
+
1196
+ or a list of colors and a permutation::
1197
+
1198
+ sage: C([[3,3,1], [1,3,2]])
1199
+ [[3, 3, 1], [1, 3, 2]]
1200
+ sage: C(([3,3,1], [1,3,2]))
1201
+ [[3, 3, 1], [1, 3, 2]]
1202
+
1203
+ There is also the natural lift from permutations::
1204
+
1205
+ sage: P = Permutations(3)
1206
+ sage: C(P.an_element())
1207
+ [[0, 0, 0], [3, 1, 2]]
1208
+
1209
+ A colored permutation::
1210
+
1211
+ sage: C(C.an_element()) == C.an_element()
1212
+ True
1213
+
1214
+ REFERENCES:
1215
+
1216
+ - :wikipedia:`Generalized_symmetric_group`
1217
+ - :wikipedia:`Complex_reflection_group`
1218
+ """
1219
+ def __init__(self, m, n):
1220
+ r"""
1221
+ Initialize ``self``.
1222
+
1223
+ EXAMPLES::
1224
+
1225
+ sage: C = ColoredPermutations(4, 3)
1226
+ sage: TestSuite(C).run()
1227
+ sage: C = ColoredPermutations(2, 3)
1228
+ sage: TestSuite(C).run()
1229
+ sage: C = ColoredPermutations(1, 3)
1230
+ sage: TestSuite(C).run()
1231
+ """
1232
+ ShephardToddFamilyGroup.__init__(self, m, 1, n)
1233
+
1234
+ def _repr_(self):
1235
+ """
1236
+ Return a string representation of ``self``.
1237
+
1238
+ EXAMPLES::
1239
+
1240
+ sage: ColoredPermutations(4, 3)
1241
+ 4-colored permutations of size 3
1242
+ """
1243
+ return "{}-colored permutations of size {}".format(self._m, self._n)
1244
+
1245
+ def __iter__(self):
1246
+ """
1247
+ Iterate over ``self``.
1248
+
1249
+ EXAMPLES::
1250
+
1251
+ sage: C = ColoredPermutations(2, 2)
1252
+ sage: [x for x in C]
1253
+ [[[0, 0], [1, 2]],
1254
+ [[0, 1], [1, 2]],
1255
+ [[1, 0], [1, 2]],
1256
+ [[1, 1], [1, 2]],
1257
+ [[0, 0], [2, 1]],
1258
+ [[0, 1], [2, 1]],
1259
+ [[1, 0], [2, 1]],
1260
+ [[1, 1], [2, 1]]]
1261
+ """
1262
+ for perm in self._P:
1263
+ for c in itertools.product(self._C, repeat=self._n):
1264
+ yield self.element_class(self, c, perm)
1265
+
1266
+
1267
+ #####################################################################
1268
+ # Signed permutations
1269
+
1270
+
1271
+ class SignedPermutation(ColoredPermutation,
1272
+ metaclass=InheritComparisonClasscallMetaclass):
1273
+ """
1274
+ A signed permutation.
1275
+ """
1276
+ @staticmethod
1277
+ def __classcall_private__(cls, pi):
1278
+ """
1279
+ Create a signed permutation.
1280
+
1281
+ EXAMPLES::
1282
+
1283
+ sage: SignedPermutation([2, 1, 3])
1284
+ [2, 1, 3]
1285
+
1286
+ sage: SignedPermutation([2, 1, -3])
1287
+ [2, 1, -3]
1288
+
1289
+ sage: SignedPermutation((2,1,-3))
1290
+ [2, 1, -3]
1291
+
1292
+ sage: SignedPermutation(range(1,4))
1293
+ [1, 2, 3]
1294
+ """
1295
+ return SignedPermutations(len(list(pi)))(pi)
1296
+
1297
+ def _repr_(self):
1298
+ """
1299
+ Return a string representation of ``self``.
1300
+
1301
+ EXAMPLES::
1302
+
1303
+ sage: S = SignedPermutations(4)
1304
+ sage: s1,s2,s3,s4 = S.gens()
1305
+ sage: s4*s1*s2*s3*s4
1306
+ [-4, 1, 2, -3]
1307
+ """
1308
+ return repr(list(self))
1309
+
1310
+ _latex_ = _repr_
1311
+
1312
+ def _mul_(self, other):
1313
+ """
1314
+ Multiply ``self`` and ``other``.
1315
+
1316
+ EXAMPLES::
1317
+
1318
+ sage: S = SignedPermutations(4)
1319
+ sage: s1,s2,s3,s4 = S.gens()
1320
+ sage: x = s4*s1*s2*s3*s4; x
1321
+ [-4, 1, 2, -3]
1322
+ sage: x * x
1323
+ [3, -4, 1, -2]
1324
+
1325
+ ::
1326
+
1327
+ sage: s1*s2*s1 == s1*s2*s1
1328
+ True
1329
+ sage: s3*s4*s3*s4 == s4*s3*s4*s3
1330
+ True
1331
+ """
1332
+ colors = tuple(c * other._colors[val - 1] # -1 for indexing
1333
+ for c, val in zip(self._colors, self._perm))
1334
+ p = self._perm._left_to_right_multiply_on_right(other._perm)
1335
+ return self.__class__(self.parent(), colors, p)
1336
+
1337
+ def __invert__(self):
1338
+ """
1339
+ Return the inverse of ``self``.
1340
+
1341
+ EXAMPLES::
1342
+
1343
+ sage: S = SignedPermutations(4)
1344
+ sage: s1,s2,s3,s4 = S.gens()
1345
+ sage: x = s4*s1*s2*s3*s4
1346
+ sage: ~x # indirect doctest
1347
+ [2, 3, -4, -1]
1348
+ sage: x * ~x == S.one()
1349
+ True
1350
+ """
1351
+ ip = ~self._perm
1352
+ return self.__class__(self.parent(),
1353
+ tuple(self._colors[i - 1] for i in ip), # -1 for indexing
1354
+ ip)
1355
+
1356
+ def __iter__(self):
1357
+ """
1358
+ Iterate over ``self``.
1359
+
1360
+ EXAMPLES::
1361
+
1362
+ sage: S = SignedPermutations(4)
1363
+ sage: s1,s2,s3,s4 = S.gens()
1364
+ sage: x = s4*s1*s2*s3*s4
1365
+ sage: [a for a in x]
1366
+ [-4, 1, 2, -3]
1367
+ """
1368
+ for c, p in zip(self._colors, self._perm):
1369
+ yield c * p
1370
+
1371
+ def __getitem__(self, key):
1372
+ """
1373
+ Return the specified element in the one line form of ``self``.
1374
+
1375
+ EXAMPLES::
1376
+
1377
+ sage: pi = SignedPermutation([-4, 5, -1, 2, -3])
1378
+ sage: pi[-1]
1379
+ -3
1380
+ sage: pi[1::2]
1381
+ [5, 2]
1382
+ """
1383
+ if isinstance(key, slice):
1384
+ return [c * v for c, v in zip(self._colors[key], self._perm[key])]
1385
+ return self._colors[key] * self._perm[key]
1386
+
1387
+ def __call__(self, i):
1388
+ """
1389
+ Return the image of the integer ``i`` in ``self``.
1390
+
1391
+ EXAMPLES::
1392
+
1393
+ sage: pi = SignedPermutations(7)([2,-1,4,-6,-5,-3,7])
1394
+ sage: pi(2)
1395
+ -1
1396
+ sage: pi(-2)
1397
+ 1
1398
+ sage: pi(7)
1399
+ 7
1400
+ sage: pi(-7)
1401
+ -7
1402
+ sage: [pi(i) for i in range(1,8)]
1403
+ [2, -1, 4, -6, -5, -3, 7]
1404
+ sage: [pi(-i) for i in range(1,8)]
1405
+ [-2, 1, -4, 6, 5, 3, -7]
1406
+ """
1407
+ if i in ZZ and 1 <= abs(i) <= len(self):
1408
+ i = ZZ(i)
1409
+ if i < 0:
1410
+ return -self._colors[-i - 1] * self._perm[-i - 1]
1411
+ return self._colors[i - 1] * self._perm[i - 1]
1412
+
1413
+ raise TypeError("i (= %s) must equal +/- an integer between %s and %s"
1414
+ % (i, 1, len(self)))
1415
+
1416
+ def to_matrix(self):
1417
+ """
1418
+ Return a matrix of ``self``.
1419
+
1420
+ EXAMPLES::
1421
+
1422
+ sage: S = SignedPermutations(4)
1423
+ sage: s1,s2,s3,s4 = S.gens()
1424
+ sage: x = s4*s1*s2*s3*s4
1425
+ sage: M = x.to_matrix(); M # needs sage.modules
1426
+ [ 0 1 0 0]
1427
+ [ 0 0 1 0]
1428
+ [ 0 0 0 -1]
1429
+ [-1 0 0 0]
1430
+
1431
+ The matrix multiplication is in the *opposite* order::
1432
+
1433
+ sage: m1,m2,m3,m4 = [g.to_matrix() for g in S.gens()] # needs sage.modules
1434
+ sage: M == m4 * m3 * m2 * m1 * m4 # needs sage.modules
1435
+ True
1436
+ """
1437
+ return self._perm.to_matrix() * diagonal_matrix(self._colors)
1438
+
1439
+ def has_left_descent(self, i) -> bool:
1440
+ """
1441
+ Return ``True`` if ``i`` is a left descent of ``self``.
1442
+
1443
+ EXAMPLES::
1444
+
1445
+ sage: S = SignedPermutations(4)
1446
+ sage: s1,s2,s3,s4 = S.gens()
1447
+ sage: x = s4*s1*s2*s3*s4
1448
+ sage: [x.has_left_descent(i) for i in S.index_set()]
1449
+ [True, False, False, True]
1450
+ """
1451
+ n = self.parent()._n
1452
+ if i == n:
1453
+ return self._colors[-1] == -1
1454
+ if self._colors[i - 1] == -1:
1455
+ return self._colors[i] == 1 or self._perm[i - 1] < self._perm[i]
1456
+ return self._colors[i] == 1 and self._perm[i - 1] > self._perm[i]
1457
+
1458
+ def to_cycles(self, singletons=True, use_min=True, negative_cycles=True):
1459
+ r"""
1460
+ Return the signed permutation ``self`` as a list of disjoint cycles.
1461
+
1462
+ The cycles are returned in the order of increasing smallest
1463
+ elements, and each cycle is returned as a tuple which starts
1464
+ with its smallest positive element.
1465
+
1466
+ INPUT:
1467
+
1468
+ - ``singletons`` -- boolean (default: ``True``); whether to include
1469
+ singleton cycles or not
1470
+ - ``use_min`` -- boolean (default: ``True``); if ``False``, the cycles
1471
+ are returned in the order of increasing *largest* (not smallest)
1472
+ elements, and each cycle starts with its largest element
1473
+ - ``negative_cycles`` -- boolean (default: ``True``); if ``False``, for
1474
+ any two cycles `C^{\pm} = \{\pm c_1, \ldots, \pm c_k\}` such that
1475
+ `C^+ \neq C^-`, this does not include the cycle `C^-`
1476
+
1477
+ .. WARNING::
1478
+
1479
+ The argument ``negative_cycles`` does not refer to the usual
1480
+ definition of a negative cycle; see :meth:`cycle_type`.
1481
+
1482
+ EXAMPLES::
1483
+
1484
+ sage: pi = SignedPermutations(7)([2,-1,4,-6,-5,-3,7])
1485
+ sage: pi.to_cycles()
1486
+ [(1, 2, -1, -2), (3, 4, -6), (-3, -4, 6), (5, -5), (7,), (-7,)]
1487
+ sage: pi.to_cycles(singletons=False)
1488
+ [(1, 2, -1, -2), (3, 4, -6), (-3, -4, 6), (5, -5)]
1489
+ sage: pi.to_cycles(negative_cycles=False)
1490
+ [(1, 2, -1, -2), (3, 4, -6), (5, -5), (7,)]
1491
+ sage: pi.to_cycles(singletons=False, negative_cycles=False)
1492
+ [(1, 2, -1, -2), (3, 4, -6), (5, -5)]
1493
+ sage: pi.to_cycles(use_min=False)
1494
+ [(7,), (-7,), (6, -3, -4), (-6, 3, 4), (5, -5), (2, -1, -2, 1)]
1495
+ sage: pi.to_cycles(singletons=False, use_min=False)
1496
+ [(6, -3, -4), (-6, 3, 4), (5, -5), (2, -1, -2, 1)]
1497
+ """
1498
+ cycles = []
1499
+
1500
+ l = self._perm[:]
1501
+
1502
+ if use_min:
1503
+ groundset = range(len(l))
1504
+ else:
1505
+ groundset = reversed(range(len(l)))
1506
+
1507
+ # Go through until we've considered every number between 1 and len(l)
1508
+ for i in groundset:
1509
+ if not l[i]:
1510
+ continue
1511
+ cycle_first = i + 1
1512
+ cycle = [cycle_first]
1513
+ l[i], next_val = False, l[i]
1514
+ s = self._colors[i]
1515
+ add_neg = True
1516
+ while next_val != cycle_first:
1517
+ cycle.append(s * next_val)
1518
+ s *= self._colors[next_val - 1]
1519
+ l[next_val - 1], next_val = False, l[next_val - 1]
1520
+ if s != 1:
1521
+ cycle.extend([-e for e in cycle])
1522
+ add_neg = False
1523
+
1524
+ # Add the cycle to the list of cycles
1525
+ if singletons or len(cycle) > 1:
1526
+ cycles.append(tuple(cycle))
1527
+ if negative_cycles and add_neg:
1528
+ cycles.append(tuple([-e for e in cycle]))
1529
+
1530
+ return cycles
1531
+
1532
+ def cycle_type(self):
1533
+ r"""
1534
+ Return a pair of partitions of ``len(self)`` corresponding to the
1535
+ signed cycle type of ``self``.
1536
+
1537
+ A *cycle* is a tuple `C = (c_0, \ldots, c_{k-1})` with
1538
+ `\pi(c_i) = c_{i+1}` for `0 \leq i < k` and `\pi(c_{k-1}) = c_0`.
1539
+ If `C` is a cycle, `\overline{C} = (-c_0, \ldots, -c_{k-1})` is
1540
+ also a cycle. A cycle is *negative*, if `C = \overline{C}` up
1541
+ to cyclic reordering. In this case, `k` is necessarily even
1542
+ and the length of `C` is `k/2`. A *positive cycle* is a pair
1543
+ `C \overline{C}`, its length is `k`.
1544
+
1545
+ Let `\alpha` be the partition whose parts are the lengths of the
1546
+ positive cycles and let `\beta` be the partition whose parts are
1547
+ the lengths of the negative cycles. Then `(\alpha, \beta)` is
1548
+ the cycle type of `\pi`.
1549
+
1550
+ EXAMPLES::
1551
+
1552
+ sage: G = SignedPermutations(7)
1553
+ sage: pi = G([2, -1, 4, -6, -5, -3, 7])
1554
+ sage: pi.cycle_type()
1555
+ ([3, 1], [2, 1])
1556
+
1557
+ sage: G = SignedPermutations(5)
1558
+ sage: all(pi.cycle_type().size() == 5 for pi in G)
1559
+ True
1560
+ sage: set(pi.cycle_type() for pi in G) == set(PartitionTuples(2, 5)) # needs sage.libs.flint
1561
+ True
1562
+ """
1563
+ cycles = self.to_cycles(negative_cycles=False)
1564
+ pos_cycles = []
1565
+ neg_cycles = []
1566
+ for C in cycles:
1567
+ if (not len(C) % 2) and C[0] == -C[len(C)//2]:
1568
+ neg_cycles.append(C)
1569
+ else:
1570
+ pos_cycles.append(C)
1571
+ pos_type = [len(C) for C in pos_cycles]
1572
+ pos_type.sort(reverse=True)
1573
+ neg_type = [len(C) // 2 for C in neg_cycles]
1574
+ neg_type.sort(reverse=True)
1575
+ PT = PartitionTuples(2, self.parent()._n)
1576
+ return PT([pos_type, neg_type])
1577
+
1578
+ def order(self):
1579
+ """
1580
+ Return the multiplicative order of the signed permutation.
1581
+
1582
+ EXAMPLES::
1583
+
1584
+ sage: pi = SignedPermutations(7)([2,-1,4,-6,-5,-3,7])
1585
+ sage: pi.to_cycles(singletons=False)
1586
+ [(1, 2, -1, -2), (3, 4, -6), (-3, -4, 6), (5, -5)]
1587
+ sage: pi.order()
1588
+ 12
1589
+ """
1590
+ return lcm(len(c) for c in self.to_cycles(singletons=False, negative_cycles=False))
1591
+
1592
+
1593
+ class SignedPermutations(ColoredPermutations):
1594
+ r"""
1595
+ Group of signed permutations.
1596
+
1597
+ The group of signed permutations is also known as the hyperoctahedral
1598
+ group, the Coxeter group of type `B_n`, and the 2-colored permutation
1599
+ group. Thus it can be constructed as the wreath product `S_2 \wr S_n`.
1600
+
1601
+ EXAMPLES::
1602
+
1603
+ sage: S = SignedPermutations(4)
1604
+ sage: s1,s2,s3,s4 = S.group_generators()
1605
+ sage: x = s4*s1*s2*s3*s4; x
1606
+ [-4, 1, 2, -3]
1607
+ sage: x^4 == S.one()
1608
+ True
1609
+
1610
+ This is a finite Coxeter group of type `B_n`::
1611
+
1612
+ sage: S.canonical_representation() # needs sage.graphs sage.modules sage.rings.number_field
1613
+ Finite Coxeter group over Number Field in a with defining polynomial x^2 - 2
1614
+ with a = 1.414213562373095? with Coxeter matrix:
1615
+ [1 3 2 2]
1616
+ [3 1 3 2]
1617
+ [2 3 1 4]
1618
+ [2 2 4 1]
1619
+ sage: S.long_element()
1620
+ [-1, -2, -3, -4]
1621
+ sage: S.long_element().reduced_word()
1622
+ [1, 2, 1, 3, 2, 1, 4, 3, 2, 1, 4, 3, 2, 4, 3, 4]
1623
+
1624
+ We can also go between the 2-colored permutation group::
1625
+
1626
+ sage: C = ColoredPermutations(2, 3)
1627
+ sage: S = SignedPermutations(3)
1628
+ sage: S.an_element()
1629
+ [-3, 1, 2]
1630
+ sage: C(S.an_element())
1631
+ [[1, 0, 0], [3, 1, 2]]
1632
+ sage: S(C(S.an_element())) == S.an_element()
1633
+ True
1634
+ sage: S(C.an_element())
1635
+ [-3, 1, 2]
1636
+
1637
+ There is also the natural lift from permutations::
1638
+
1639
+ sage: P = Permutations(3)
1640
+ sage: x = S(P.an_element()); x
1641
+ [3, 1, 2]
1642
+ sage: x.parent()
1643
+ Signed permutations of 3
1644
+
1645
+ REFERENCES:
1646
+
1647
+ - :wikipedia:`Hyperoctahedral_group`
1648
+ """
1649
+ def __init__(self, n):
1650
+ """
1651
+ Initialize ``self``.
1652
+
1653
+ EXAMPLES::
1654
+
1655
+ sage: S = SignedPermutations(4)
1656
+ sage: TestSuite(S).run()
1657
+ """
1658
+ ColoredPermutations.__init__(self, 2, n)
1659
+
1660
+ def _repr_(self):
1661
+ """
1662
+ Return a string representation of ``self``.
1663
+
1664
+ EXAMPLES::
1665
+
1666
+ sage: SignedPermutations(4)
1667
+ Signed permutations of 4
1668
+ """
1669
+ return "Signed permutations of {}".format(self._n)
1670
+
1671
+ @cached_method
1672
+ def one(self):
1673
+ """
1674
+ Return the identity element of ``self``.
1675
+
1676
+ EXAMPLES::
1677
+
1678
+ sage: S = SignedPermutations(4)
1679
+ sage: S.one()
1680
+ [1, 2, 3, 4]
1681
+ """
1682
+ return self.element_class(self, [ZZ.one()] * self._n,
1683
+ self._P.identity())
1684
+
1685
+ def random_element(self):
1686
+ """
1687
+ Return an element drawn uniformly at random.
1688
+
1689
+ EXAMPLES::
1690
+
1691
+ sage: C = SignedPermutations(7)
1692
+ sage: s = C.random_element(); s # random
1693
+ [7, 6, -4, -5, 2, 3, -1]
1694
+ sage: s in C
1695
+ True
1696
+ """
1697
+ return self.element_class(self,
1698
+ [choice([ZZ.one(), -ZZ.one()])
1699
+ for _ in range(self._n)],
1700
+ self._P.random_element())
1701
+
1702
+ def simple_reflection(self, i):
1703
+ r"""
1704
+ Return the ``i``-th simple reflection of ``self``.
1705
+
1706
+ EXAMPLES::
1707
+
1708
+ sage: S = SignedPermutations(4)
1709
+ sage: S.simple_reflection(1)
1710
+ [2, 1, 3, 4]
1711
+ sage: S.simple_reflection(4)
1712
+ [1, 2, 3, -4]
1713
+ """
1714
+ if i not in self.index_set():
1715
+ raise ValueError("i must be in the index set")
1716
+ if i < self._n:
1717
+ p = list(range(1, self._n + 1))
1718
+ p[i - 1] = i + 1
1719
+ p[i] = i
1720
+ return self.element_class(self, [ZZ.one()] * self._n, self._P(p))
1721
+ temp = [ZZ.one()] * self._n
1722
+ temp[-1] = -ZZ.one()
1723
+ return self.element_class(self, temp, self._P.identity())
1724
+
1725
+ def _element_constructor_(self, x):
1726
+ """
1727
+ Construct an element of ``self`` from ``x``.
1728
+
1729
+ TESTS::
1730
+
1731
+ sage: S = SignedPermutations(3)
1732
+ sage: x = S([(+1,1), (-1,3), (-1,2)]); x
1733
+ [1, -3, -2]
1734
+ sage: x == S([[+1,-1,-1], [1,3,2]])
1735
+ True
1736
+ sage: x == S([1, -3, -2])
1737
+ True
1738
+
1739
+ sage: S = SignedPermutations(0)
1740
+ sage: S([]) == list(S)[0]
1741
+ True
1742
+
1743
+ sage: T = SignedPermutation(range(1,4))
1744
+ sage: SignedPermutations(3)(T)
1745
+ [1, 2, 3]
1746
+ """
1747
+ if isinstance(x, self.element_class) and x.parent() is self:
1748
+ return self
1749
+ x = list(x)
1750
+ if x and isinstance(x[0], tuple):
1751
+ c = []
1752
+ p = []
1753
+ for k in x:
1754
+ if len(k) != 2:
1755
+ raise ValueError("input must be pairs (sign, element)")
1756
+ if k[0] != 1 and k[0] != -1:
1757
+ raise ValueError("the sign must be +1 or -1")
1758
+ c.append(ZZ(k[0]))
1759
+ p.append(k[1])
1760
+ return self.element_class(self, c, self._P(p))
1761
+
1762
+ if len(x) == self._n:
1763
+ c = []
1764
+ p = []
1765
+ one = ZZ.one()
1766
+ for v in x:
1767
+ if v > 0:
1768
+ c.append(one)
1769
+ p.append(v)
1770
+ else:
1771
+ c.append(-one)
1772
+ p.append(-v)
1773
+ return self.element_class(self, c, self._P(p))
1774
+
1775
+ if len(x) != 2:
1776
+ raise ValueError("input must be a pair of a list of signs and a permutation")
1777
+ if any(s != 1 and s != -1 for s in x[0]):
1778
+ raise ValueError("the sign must be +1 or -1")
1779
+ return self.element_class(self, [ZZ(v) for v in x[0]], self._P(x[1]))
1780
+
1781
+ def __iter__(self):
1782
+ """
1783
+ Iterate over ``self``.
1784
+
1785
+ EXAMPLES::
1786
+
1787
+ sage: S = SignedPermutations(2)
1788
+ sage: [x for x in S]
1789
+ [[1, 2], [1, -2], [-1, 2], [-1, -2],
1790
+ [2, 1], [2, -1], [-2, 1], [-2, -1]]
1791
+ """
1792
+ pmone = [ZZ.one(), -ZZ.one()]
1793
+ for p in self._P:
1794
+ for c in itertools.product(pmone, repeat=self._n):
1795
+ yield self.element_class(self, c, p)
1796
+
1797
+ def _coerce_map_from_(self, C):
1798
+ """
1799
+ Return a coerce map from ``C`` if it exists and ``None`` otherwise.
1800
+
1801
+ EXAMPLES::
1802
+
1803
+ sage: C = ColoredPermutations(2, 3)
1804
+ sage: S = SignedPermutations(3)
1805
+ sage: S.has_coerce_map_from(C)
1806
+ True
1807
+
1808
+ sage: C = ColoredPermutations(4, 3)
1809
+ sage: S.has_coerce_map_from(C)
1810
+ False
1811
+
1812
+ sage: P = Permutations(3)
1813
+ sage: C.has_coerce_map_from(P)
1814
+ True
1815
+ sage: P = Permutations(4)
1816
+ sage: C.has_coerce_map_from(P)
1817
+ False
1818
+ """
1819
+ if isinstance(C, Permutations) and C.n == self._n:
1820
+ return lambda P, x: P.element_class(P, [1] * P._n, x)
1821
+ if isinstance(C, ColoredPermutations) and C._n == self._n and C._m == 2:
1822
+ return lambda P, x: P.element_class(P,
1823
+ [1 if v == 0 else -1
1824
+ for v in x._colors],
1825
+ x._perm)
1826
+ return super()._coerce_map_from_(C)
1827
+
1828
+ def tabloid_module(self, shape, base_ring):
1829
+ """
1830
+ Return the tabloid module of ``self`` with shape ``shape``
1831
+ over ``base_ring``.
1832
+
1833
+ EXAMPLES::
1834
+
1835
+ sage: # needs sage.groups sage.modules
1836
+ sage: B4 = SignedPermutations(4)
1837
+ sage: TM = B4.tabloid_module([[2,1], [1]], GF(2))
1838
+ sage: TM.dimension()
1839
+ 96
1840
+ sage: TM = B4.tabloid_module([[], [3,1]], GF(2))
1841
+ sage: TM.dimension()
1842
+ 4
1843
+ """
1844
+ from .colored_permutations_representations import TabloidModule
1845
+ return TabloidModule(self, base_ring, shape)
1846
+
1847
+ def specht_module(self, shape, base_ring):
1848
+ """
1849
+ Return the Specht module of ``self`` with shape ``shape``
1850
+ over ``base_ring``.
1851
+
1852
+ EXAMPLES::
1853
+
1854
+ sage: # needs sage.groups sage.modules
1855
+ sage: B4 = SignedPermutations(4)
1856
+ sage: SM = B4.specht_module([[2,1], [1]], GF(2))
1857
+ sage: SM.dimension()
1858
+ 8
1859
+ sage: SM = B4.specht_module([[], [3,1]], GF(2))
1860
+ sage: SM.dimension()
1861
+ 3
1862
+ """
1863
+ return self.tabloid_module(shape, base_ring).specht_module()
1864
+
1865
+ def simple_module(self, shape, base_ring):
1866
+ """
1867
+ Return the simple module of ``self`` with shape ``shape``
1868
+ over ``base_ring``.
1869
+
1870
+ EXAMPLES::
1871
+
1872
+ sage: # needs sage.groups sage.modules
1873
+ sage: B4 = SignedPermutations(4)
1874
+ sage: L = B4.simple_module([[], [3,1]], GF(2))
1875
+ sage: L.dimension()
1876
+ 2
1877
+ """
1878
+ return self.specht_module(shape, base_ring).simple_module()
1879
+
1880
+ def long_element(self, index_set=None):
1881
+ """
1882
+ Return the longest element of ``self``, or of the
1883
+ parabolic subgroup corresponding to the given ``index_set``.
1884
+
1885
+ INPUT:
1886
+
1887
+ - ``index_set`` -- (optional) a subset (as a list or iterable)
1888
+ of the nodes of the indexing set
1889
+
1890
+ EXAMPLES::
1891
+
1892
+ sage: S = SignedPermutations(4)
1893
+ sage: S.long_element()
1894
+ [-1, -2, -3, -4]
1895
+
1896
+ TESTS:
1897
+
1898
+ Check that this is the element of maximal length (:issue:`25200`)::
1899
+
1900
+ sage: S = SignedPermutations(4)
1901
+ sage: S.long_element().length() == max(x.length() for x in S)
1902
+ True
1903
+ sage: all(SignedPermutations(n).long_element().length() == n^2
1904
+ ....: for n in range(2,10))
1905
+ True
1906
+ """
1907
+ if index_set is not None:
1908
+ return super().long_element()
1909
+ return self.element_class(self, [-ZZ.one()] * self._n, self._P.one())
1910
+
1911
+ def conjugacy_class(self, g):
1912
+ r"""
1913
+ Return the conjugacy class of ``g`` in ``self``.
1914
+
1915
+ INPUT:
1916
+
1917
+ - ``g`` -- a pair of partitions or an element of ``self``
1918
+
1919
+ EXAMPLES::
1920
+
1921
+ sage: # needs sage.groups sage.modules
1922
+ sage: G = SignedPermutations(5)
1923
+ sage: g = G([1,-3,2,5,-4])
1924
+ sage: G.conjugacy_class(g)
1925
+ Conjugacy class of cycle type ([1], [2, 2]) in Signed permutations of 5
1926
+ sage: G.conjugacy_class([[2,1], [1,1]])
1927
+ Conjugacy class of cycle type ([2, 1], [1, 1]) in Signed permutations of 5
1928
+ """
1929
+ from .colored_permutations_representations import SignedPermutationGroupConjugacyClass
1930
+ return SignedPermutationGroupConjugacyClass(self, g)
1931
+
1932
+ def conjugacy_classes(self):
1933
+ """
1934
+ Return the list of conjugacy classes of ``self``.
1935
+
1936
+ EXAMPLES::
1937
+
1938
+ sage: # needs sage.libs.flint
1939
+ sage: G = SignedPermutations(3)
1940
+ sage: G.conjugacy_classes()
1941
+ [Conjugacy class of cycle type ([3], []) in Signed permutations of 3,
1942
+ Conjugacy class of cycle type ([2, 1], []) in Signed permutations of 3,
1943
+ Conjugacy class of cycle type ([1, 1, 1], []) in Signed permutations of 3,
1944
+ Conjugacy class of cycle type ([2], [1]) in Signed permutations of 3,
1945
+ Conjugacy class of cycle type ([1, 1], [1]) in Signed permutations of 3,
1946
+ Conjugacy class of cycle type ([1], [2]) in Signed permutations of 3,
1947
+ Conjugacy class of cycle type ([1], [1, 1]) in Signed permutations of 3,
1948
+ Conjugacy class of cycle type ([], [3]) in Signed permutations of 3,
1949
+ Conjugacy class of cycle type ([], [2, 1]) in Signed permutations of 3,
1950
+ Conjugacy class of cycle type ([], [1, 1, 1]) in Signed permutations of 3]
1951
+ """
1952
+ return [self.conjugacy_class(la) for la in PartitionTuples(2, self._n)]
1953
+
1954
+ def conjugacy_class_representative(self, nu):
1955
+ r"""
1956
+ Return a permutation with (signed) cycle type ``nu``.
1957
+
1958
+ EXAMPLES::
1959
+
1960
+ sage: G = SignedPermutations(4)
1961
+ sage: for nu in PartitionTuples(2, 4): # needs sage.libs.flint
1962
+ ....: print(nu, G.conjugacy_class_representative(nu))
1963
+ ....: assert nu == G.conjugacy_class_representative(nu).cycle_type(), nu
1964
+ ([4], []) [2, 3, 4, 1]
1965
+ ([3, 1], []) [2, 3, 1, 4]
1966
+ ([2, 2], []) [2, 1, 4, 3]
1967
+ ([2, 1, 1], []) [2, 1, 3, 4]
1968
+ ([1, 1, 1, 1], []) [1, 2, 3, 4]
1969
+ ([3], [1]) [2, 3, 1, -4]
1970
+ ([2, 1], [1]) [2, 1, 3, -4]
1971
+ ([1, 1, 1], [1]) [1, 2, 3, -4]
1972
+ ([2], [2]) [2, 1, 4, -3]
1973
+ ([2], [1, 1]) [2, 1, -3, -4]
1974
+ ([1, 1], [2]) [1, 2, 4, -3]
1975
+ ([1, 1], [1, 1]) [1, 2, -3, -4]
1976
+ ([1], [3]) [1, 3, 4, -2]
1977
+ ([1], [2, 1]) [1, 3, -2, -4]
1978
+ ([1], [1, 1, 1]) [1, -2, -3, -4]
1979
+ ([], [4]) [2, 3, 4, -1]
1980
+ ([], [3, 1]) [2, 3, -1, -4]
1981
+ ([], [2, 2]) [2, -1, 4, -3]
1982
+ ([], [2, 1, 1]) [2, -1, -3, -4]
1983
+ ([], [1, 1, 1, 1]) [-1, -2, -3, -4]
1984
+
1985
+ TESTS::
1986
+
1987
+ sage: all(nu == SignedPermutations(n).conjugacy_class_representative(nu).cycle_type() # needs sage.libs.flint
1988
+ ....: for n in range(1, 6) for nu in PartitionTuples(2, n))
1989
+ True
1990
+ """
1991
+ nu = PartitionTuples(2, self._n)(nu)
1992
+ la, mu = nu
1993
+ cyc = []
1994
+ cnt = 0
1995
+
1996
+ for i in la:
1997
+ cyc += [tuple(range(cnt+1, cnt+i+1))] + [tuple(range(-cnt-1, -cnt-i-1, -1))]
1998
+ cnt += i
1999
+ for i in mu:
2000
+ cyc += [tuple(range(cnt+1, cnt+i+1)) + tuple(range(-cnt-1, -cnt-i-1, -1))]
2001
+ cnt += i
2002
+
2003
+ p = [None] * self._n
2004
+ for c in cyc:
2005
+ for i in range(len(c)-1):
2006
+ if c[i] > 0:
2007
+ p[c[i]-1] = c[i+1]
2008
+ if c[-1] > 0:
2009
+ p[c[-1]-1] = c[0]
2010
+
2011
+ return self(p)
2012
+
2013
+ Element = SignedPermutation
2014
+
2015
+ # TODO: Make this a subgroup
2016
+ # class EvenSignedPermutations(SignedPermutations):
2017
+ # """
2018
+ # Group of even signed permutations.
2019
+ # """
2020
+ # def _repr_(self):
2021
+ # """
2022
+ # Return a string representation of ``self``.
2023
+ # """
2024
+ # return "Even signed permutations of {}".format(self._n)
2025
+ #
2026
+ # def __iter__(self):
2027
+ # """
2028
+ # Iterate over ``self``.
2029
+ # """
2030
+ # for s in SignedPermutations.__iter__(self):
2031
+ # total = 0
2032
+ # for pm in s._colors:
2033
+ # if pm == -1:
2034
+ # total += 1
2035
+ #
2036
+ # if total % 2 == 0:
2037
+ # yield s
2038
+
2039
+ # Conjugacy classes, representation theory moved to colored_permutations_representations.py