passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  3. passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
  4. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  5. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  6. passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  7. passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
  8. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  9. sage/algebras/all.py +24 -0
  10. sage/algebras/all__sagemath_combinat.py +35 -0
  11. sage/algebras/askey_wilson.py +935 -0
  12. sage/algebras/associated_graded.py +345 -0
  13. sage/algebras/cellular_basis.py +350 -0
  14. sage/algebras/cluster_algebra.py +2766 -0
  15. sage/algebras/down_up_algebra.py +860 -0
  16. sage/algebras/free_algebra.py +1698 -0
  17. sage/algebras/free_algebra_element.py +345 -0
  18. sage/algebras/free_algebra_quotient.py +405 -0
  19. sage/algebras/free_algebra_quotient_element.py +295 -0
  20. sage/algebras/free_zinbiel_algebra.py +885 -0
  21. sage/algebras/hall_algebra.py +783 -0
  22. sage/algebras/hecke_algebras/all.py +4 -0
  23. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  24. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  25. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  28. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  29. sage/algebras/jordan_algebra.py +1773 -0
  30. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  31. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  32. sage/algebras/lie_conformal_algebras/all.py +18 -0
  33. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  34. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  35. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  36. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  37. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  38. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  39. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  40. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  41. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  45. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  46. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  47. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  48. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  49. sage/algebras/nil_coxeter_algebra.py +191 -0
  50. sage/algebras/q_commuting_polynomials.py +673 -0
  51. sage/algebras/q_system.py +608 -0
  52. sage/algebras/quantum_clifford.py +959 -0
  53. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  54. sage/algebras/quantum_groups/all.py +9 -0
  55. sage/algebras/quantum_groups/fock_space.py +2219 -0
  56. sage/algebras/quantum_groups/q_numbers.py +207 -0
  57. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  58. sage/algebras/quantum_groups/representations.py +591 -0
  59. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  60. sage/algebras/quantum_oscillator.py +623 -0
  61. sage/algebras/quaternion_algebra.py +20 -0
  62. sage/algebras/quaternion_algebra_element.py +55 -0
  63. sage/algebras/rational_cherednik_algebra.py +525 -0
  64. sage/algebras/schur_algebra.py +670 -0
  65. sage/algebras/shuffle_algebra.py +1011 -0
  66. sage/algebras/splitting_algebra.py +779 -0
  67. sage/algebras/tensor_algebra.py +709 -0
  68. sage/algebras/yangian.py +1082 -0
  69. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  70. sage/all__sagemath_combinat.py +35 -0
  71. sage/combinat/SJT.py +255 -0
  72. sage/combinat/affine_permutation.py +2405 -0
  73. sage/combinat/algebraic_combinatorics.py +55 -0
  74. sage/combinat/all.py +53 -0
  75. sage/combinat/all__sagemath_combinat.py +195 -0
  76. sage/combinat/alternating_sign_matrix.py +2063 -0
  77. sage/combinat/baxter_permutations.py +346 -0
  78. sage/combinat/bijectionist.py +3220 -0
  79. sage/combinat/binary_recurrence_sequences.py +1180 -0
  80. sage/combinat/blob_algebra.py +685 -0
  81. sage/combinat/catalog_partitions.py +27 -0
  82. sage/combinat/chas/all.py +23 -0
  83. sage/combinat/chas/fsym.py +1180 -0
  84. sage/combinat/chas/wqsym.py +2601 -0
  85. sage/combinat/cluster_complex.py +326 -0
  86. sage/combinat/colored_permutations.py +2039 -0
  87. sage/combinat/colored_permutations_representations.py +964 -0
  88. sage/combinat/composition_signed.py +142 -0
  89. sage/combinat/composition_tableau.py +855 -0
  90. sage/combinat/constellation.py +1729 -0
  91. sage/combinat/core.py +751 -0
  92. sage/combinat/counting.py +12 -0
  93. sage/combinat/crystals/affine.py +742 -0
  94. sage/combinat/crystals/affine_factorization.py +518 -0
  95. sage/combinat/crystals/affinization.py +331 -0
  96. sage/combinat/crystals/alcove_path.py +2013 -0
  97. sage/combinat/crystals/all.py +22 -0
  98. sage/combinat/crystals/bkk_crystals.py +141 -0
  99. sage/combinat/crystals/catalog.py +115 -0
  100. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  101. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  102. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  103. sage/combinat/crystals/crystals.py +257 -0
  104. sage/combinat/crystals/direct_sum.py +260 -0
  105. sage/combinat/crystals/elementary_crystals.py +1251 -0
  106. sage/combinat/crystals/fast_crystals.py +441 -0
  107. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  108. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  109. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  110. sage/combinat/crystals/induced_structure.py +695 -0
  111. sage/combinat/crystals/infinity_crystals.py +730 -0
  112. sage/combinat/crystals/kac_modules.py +863 -0
  113. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  114. sage/combinat/crystals/kyoto_path_model.py +497 -0
  115. sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
  116. sage/combinat/crystals/letters.pxd +79 -0
  117. sage/combinat/crystals/letters.pyx +3056 -0
  118. sage/combinat/crystals/littelmann_path.py +1518 -0
  119. sage/combinat/crystals/monomial_crystals.py +1262 -0
  120. sage/combinat/crystals/multisegments.py +462 -0
  121. sage/combinat/crystals/mv_polytopes.py +467 -0
  122. sage/combinat/crystals/pbw_crystal.py +511 -0
  123. sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
  124. sage/combinat/crystals/pbw_datum.pxd +4 -0
  125. sage/combinat/crystals/pbw_datum.pyx +487 -0
  126. sage/combinat/crystals/polyhedral_realization.py +372 -0
  127. sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/combinat/crystals/spins.pxd +21 -0
  129. sage/combinat/crystals/spins.pyx +756 -0
  130. sage/combinat/crystals/star_crystal.py +290 -0
  131. sage/combinat/crystals/subcrystal.py +464 -0
  132. sage/combinat/crystals/tensor_product.py +1177 -0
  133. sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  135. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  136. sage/combinat/crystals/virtual_crystal.py +420 -0
  137. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  138. sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/combinat/debruijn_sequence.pyx +355 -0
  140. sage/combinat/decorated_permutation.py +270 -0
  141. sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
  142. sage/combinat/degree_sequences.pyx +588 -0
  143. sage/combinat/derangements.py +527 -0
  144. sage/combinat/descent_algebra.py +1008 -0
  145. sage/combinat/diagram.py +1551 -0
  146. sage/combinat/diagram_algebras.py +5886 -0
  147. sage/combinat/dyck_word.py +4349 -0
  148. sage/combinat/e_one_star.py +1623 -0
  149. sage/combinat/enumerated_sets.py +123 -0
  150. sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
  151. sage/combinat/expnums.pyx +148 -0
  152. sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
  153. sage/combinat/fast_vector_partitions.pyx +346 -0
  154. sage/combinat/fqsym.py +1977 -0
  155. sage/combinat/free_dendriform_algebra.py +954 -0
  156. sage/combinat/free_prelie_algebra.py +1141 -0
  157. sage/combinat/fully_commutative_elements.py +1077 -0
  158. sage/combinat/fully_packed_loop.py +1523 -0
  159. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  160. sage/combinat/gray_codes.py +311 -0
  161. sage/combinat/grossman_larson_algebras.py +667 -0
  162. sage/combinat/growth.py +4352 -0
  163. sage/combinat/hall_polynomial.py +188 -0
  164. sage/combinat/hillman_grassl.py +866 -0
  165. sage/combinat/integer_matrices.py +329 -0
  166. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  167. sage/combinat/k_tableau.py +4564 -0
  168. sage/combinat/kazhdan_lusztig.py +215 -0
  169. sage/combinat/key_polynomial.py +885 -0
  170. sage/combinat/knutson_tao_puzzles.py +2286 -0
  171. sage/combinat/lr_tableau.py +311 -0
  172. sage/combinat/matrices/all.py +24 -0
  173. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  174. sage/combinat/matrices/latin.py +2912 -0
  175. sage/combinat/misc.py +401 -0
  176. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  177. sage/combinat/ncsf_qsym/all.py +21 -0
  178. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  179. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  180. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  181. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  182. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  183. sage/combinat/ncsym/all.py +21 -0
  184. sage/combinat/ncsym/bases.py +855 -0
  185. sage/combinat/ncsym/dual.py +593 -0
  186. sage/combinat/ncsym/ncsym.py +2076 -0
  187. sage/combinat/necklace.py +551 -0
  188. sage/combinat/non_decreasing_parking_function.py +634 -0
  189. sage/combinat/nu_dyck_word.py +1474 -0
  190. sage/combinat/output.py +861 -0
  191. sage/combinat/parallelogram_polyomino.py +4326 -0
  192. sage/combinat/parking_functions.py +1602 -0
  193. sage/combinat/partition_algebra.py +1998 -0
  194. sage/combinat/partition_kleshchev.py +1982 -0
  195. sage/combinat/partition_shifting_algebras.py +584 -0
  196. sage/combinat/partition_tuple.py +3114 -0
  197. sage/combinat/path_tableaux/all.py +13 -0
  198. sage/combinat/path_tableaux/catalog.py +29 -0
  199. sage/combinat/path_tableaux/dyck_path.py +380 -0
  200. sage/combinat/path_tableaux/frieze.py +476 -0
  201. sage/combinat/path_tableaux/path_tableau.py +728 -0
  202. sage/combinat/path_tableaux/semistandard.py +510 -0
  203. sage/combinat/perfect_matching.py +779 -0
  204. sage/combinat/plane_partition.py +3300 -0
  205. sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
  206. sage/combinat/q_bernoulli.pyx +128 -0
  207. sage/combinat/quickref.py +81 -0
  208. sage/combinat/recognizable_series.py +2051 -0
  209. sage/combinat/regular_sequence.py +4316 -0
  210. sage/combinat/regular_sequence_bounded.py +543 -0
  211. sage/combinat/restricted_growth.py +81 -0
  212. sage/combinat/ribbon.py +20 -0
  213. sage/combinat/ribbon_shaped_tableau.py +489 -0
  214. sage/combinat/ribbon_tableau.py +1180 -0
  215. sage/combinat/rigged_configurations/all.py +46 -0
  216. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  217. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  218. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  219. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  222. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  223. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  224. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  225. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  226. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  227. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  228. sage/combinat/rigged_configurations/bijection.py +143 -0
  229. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  230. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  231. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  232. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  233. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  234. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  235. sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
  236. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  238. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  240. sage/combinat/rsk.py +3438 -0
  241. sage/combinat/schubert_polynomial.py +508 -0
  242. sage/combinat/set_partition.py +3318 -0
  243. sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  244. sage/combinat/set_partition_iterator.pyx +136 -0
  245. sage/combinat/set_partition_ordered.py +1590 -0
  246. sage/combinat/sf/abreu_nigro.py +346 -0
  247. sage/combinat/sf/all.py +52 -0
  248. sage/combinat/sf/character.py +576 -0
  249. sage/combinat/sf/classical.py +319 -0
  250. sage/combinat/sf/dual.py +996 -0
  251. sage/combinat/sf/elementary.py +549 -0
  252. sage/combinat/sf/hall_littlewood.py +1028 -0
  253. sage/combinat/sf/hecke.py +336 -0
  254. sage/combinat/sf/homogeneous.py +464 -0
  255. sage/combinat/sf/jack.py +1428 -0
  256. sage/combinat/sf/k_dual.py +1458 -0
  257. sage/combinat/sf/kfpoly.py +447 -0
  258. sage/combinat/sf/llt.py +789 -0
  259. sage/combinat/sf/macdonald.py +2019 -0
  260. sage/combinat/sf/monomial.py +525 -0
  261. sage/combinat/sf/multiplicative.py +113 -0
  262. sage/combinat/sf/new_kschur.py +1786 -0
  263. sage/combinat/sf/ns_macdonald.py +964 -0
  264. sage/combinat/sf/orthogonal.py +246 -0
  265. sage/combinat/sf/orthotriang.py +355 -0
  266. sage/combinat/sf/powersum.py +963 -0
  267. sage/combinat/sf/schur.py +880 -0
  268. sage/combinat/sf/sf.py +1653 -0
  269. sage/combinat/sf/sfa.py +7053 -0
  270. sage/combinat/sf/symplectic.py +253 -0
  271. sage/combinat/sf/witt.py +721 -0
  272. sage/combinat/shifted_primed_tableau.py +2735 -0
  273. sage/combinat/shuffle.py +830 -0
  274. sage/combinat/sidon_sets.py +146 -0
  275. sage/combinat/similarity_class_type.py +1721 -0
  276. sage/combinat/sine_gordon.py +618 -0
  277. sage/combinat/six_vertex_model.py +784 -0
  278. sage/combinat/skew_partition.py +2053 -0
  279. sage/combinat/skew_tableau.py +2989 -0
  280. sage/combinat/sloane_functions.py +8935 -0
  281. sage/combinat/specht_module.py +1403 -0
  282. sage/combinat/species/all.py +48 -0
  283. sage/combinat/species/characteristic_species.py +321 -0
  284. sage/combinat/species/composition_species.py +273 -0
  285. sage/combinat/species/cycle_species.py +284 -0
  286. sage/combinat/species/empty_species.py +155 -0
  287. sage/combinat/species/functorial_composition_species.py +148 -0
  288. sage/combinat/species/generating_series.py +673 -0
  289. sage/combinat/species/library.py +148 -0
  290. sage/combinat/species/linear_order_species.py +169 -0
  291. sage/combinat/species/misc.py +83 -0
  292. sage/combinat/species/partition_species.py +290 -0
  293. sage/combinat/species/permutation_species.py +268 -0
  294. sage/combinat/species/product_species.py +423 -0
  295. sage/combinat/species/recursive_species.py +476 -0
  296. sage/combinat/species/set_species.py +192 -0
  297. sage/combinat/species/species.py +820 -0
  298. sage/combinat/species/structure.py +539 -0
  299. sage/combinat/species/subset_species.py +243 -0
  300. sage/combinat/species/sum_species.py +225 -0
  301. sage/combinat/subword.py +564 -0
  302. sage/combinat/subword_complex.py +2122 -0
  303. sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
  304. sage/combinat/subword_complex_c.pyx +119 -0
  305. sage/combinat/super_tableau.py +821 -0
  306. sage/combinat/superpartition.py +1154 -0
  307. sage/combinat/symmetric_group_algebra.py +3774 -0
  308. sage/combinat/symmetric_group_representations.py +1830 -0
  309. sage/combinat/t_sequences.py +877 -0
  310. sage/combinat/tableau.py +9506 -0
  311. sage/combinat/tableau_residues.py +860 -0
  312. sage/combinat/tableau_tuple.py +5353 -0
  313. sage/combinat/tiling.py +2432 -0
  314. sage/combinat/triangles_FHM.py +777 -0
  315. sage/combinat/tutorial.py +1857 -0
  316. sage/combinat/vector_partition.py +337 -0
  317. sage/combinat/words/abstract_word.py +1722 -0
  318. sage/combinat/words/all.py +59 -0
  319. sage/combinat/words/alphabet.py +268 -0
  320. sage/combinat/words/finite_word.py +7201 -0
  321. sage/combinat/words/infinite_word.py +113 -0
  322. sage/combinat/words/lyndon_word.py +652 -0
  323. sage/combinat/words/morphic.py +351 -0
  324. sage/combinat/words/morphism.py +3878 -0
  325. sage/combinat/words/paths.py +2932 -0
  326. sage/combinat/words/shuffle_product.py +278 -0
  327. sage/combinat/words/suffix_trees.py +1873 -0
  328. sage/combinat/words/word.py +769 -0
  329. sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
  330. sage/combinat/words/word_char.pyx +847 -0
  331. sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
  332. sage/combinat/words/word_datatypes.pxd +4 -0
  333. sage/combinat/words/word_datatypes.pyx +1067 -0
  334. sage/combinat/words/word_generators.py +2026 -0
  335. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  336. sage/combinat/words/word_options.py +99 -0
  337. sage/combinat/words/words.py +2396 -0
  338. sage/data_structures/all__sagemath_combinat.py +1 -0
  339. sage/databases/all__sagemath_combinat.py +13 -0
  340. sage/databases/findstat.py +4897 -0
  341. sage/databases/oeis.py +2058 -0
  342. sage/databases/sloane.py +393 -0
  343. sage/dynamics/all__sagemath_combinat.py +14 -0
  344. sage/dynamics/cellular_automata/all.py +7 -0
  345. sage/dynamics/cellular_automata/catalog.py +34 -0
  346. sage/dynamics/cellular_automata/elementary.py +612 -0
  347. sage/dynamics/cellular_automata/glca.py +477 -0
  348. sage/dynamics/cellular_automata/solitons.py +1463 -0
  349. sage/dynamics/finite_dynamical_system.py +1249 -0
  350. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  351. sage/games/all.py +7 -0
  352. sage/games/hexad.py +704 -0
  353. sage/games/quantumino.py +591 -0
  354. sage/games/sudoku.py +889 -0
  355. sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
  356. sage/games/sudoku_backtrack.pyx +189 -0
  357. sage/groups/all__sagemath_combinat.py +1 -0
  358. sage/groups/indexed_free_group.py +489 -0
  359. sage/libs/all__sagemath_combinat.py +6 -0
  360. sage/libs/lrcalc/__init__.py +1 -0
  361. sage/libs/lrcalc/lrcalc.py +525 -0
  362. sage/libs/symmetrica/__init__.py +7 -0
  363. sage/libs/symmetrica/all.py +101 -0
  364. sage/libs/symmetrica/kostka.pxi +168 -0
  365. sage/libs/symmetrica/part.pxi +193 -0
  366. sage/libs/symmetrica/plet.pxi +42 -0
  367. sage/libs/symmetrica/sab.pxi +196 -0
  368. sage/libs/symmetrica/sb.pxi +332 -0
  369. sage/libs/symmetrica/sc.pxi +192 -0
  370. sage/libs/symmetrica/schur.pxi +956 -0
  371. sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
  372. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  373. sage/libs/symmetrica/symmetrica.pyx +39 -0
  374. sage/monoids/all.py +13 -0
  375. sage/monoids/automatic_semigroup.py +1054 -0
  376. sage/monoids/free_abelian_monoid.py +315 -0
  377. sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
  378. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  379. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  380. sage/monoids/free_monoid.py +335 -0
  381. sage/monoids/free_monoid_element.py +431 -0
  382. sage/monoids/hecke_monoid.py +65 -0
  383. sage/monoids/string_monoid.py +817 -0
  384. sage/monoids/string_monoid_element.py +547 -0
  385. sage/monoids/string_ops.py +143 -0
  386. sage/monoids/trace_monoid.py +972 -0
  387. sage/rings/all__sagemath_combinat.py +2 -0
  388. sage/sat/all.py +4 -0
  389. sage/sat/boolean_polynomials.py +405 -0
  390. sage/sat/converters/__init__.py +6 -0
  391. sage/sat/converters/anf2cnf.py +14 -0
  392. sage/sat/converters/polybori.py +611 -0
  393. sage/sat/solvers/__init__.py +5 -0
  394. sage/sat/solvers/cryptominisat.py +287 -0
  395. sage/sat/solvers/dimacs.py +783 -0
  396. sage/sat/solvers/picosat.py +228 -0
  397. sage/sat/solvers/sat_lp.py +156 -0
  398. sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
  399. sage/sat/solvers/satsolver.pxd +3 -0
  400. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,779 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.libs.pari sage.modules
3
+ r"""
4
+ Splitting Algebras
5
+
6
+ *Splitting algebras* have been considered by Dan Laksov, Anders Thorup,
7
+ Torsten Ekedahl and others (see references below) in order to study
8
+ intersection theory of Grassmann and other flag schemes. Similarly as
9
+ *splitting fields* they can be considered as extensions of rings containing
10
+ all the roots of a given monic polynomial over that ring under the
11
+ assumption that its Galois group is the symmetric group of order equal
12
+ to the polynomial's degree.
13
+
14
+ Thus they can be used as a tool to express elements of a ring generated by
15
+ `n` indeterminates in terms of symmetric functions in these indeterminates.
16
+
17
+ This realization of splitting algebras follows the approach of a recursive
18
+ quotient ring construction splitting off some linear factor of the
19
+ polynomial in each recursive step. Accordingly it is inherited from
20
+ :class:`PolynomialQuotientRing_domain`.
21
+
22
+ AUTHORS:
23
+
24
+ - Sebastian Oehms (April 2020): initial version
25
+ """
26
+
27
+ # ****************************************************************************
28
+ # Copyright (C) 2020 Sebastian Oehms <seb.oehms@gmail.com>
29
+ #
30
+ # This program is free software: you can redistribute it and/or modify
31
+ # it under the terms of the GNU General Public License as published by
32
+ # the Free Software Foundation, either version 2 of the License, or
33
+ # (at your option) any later version.
34
+ # https://www.gnu.org/licenses/
35
+ # ****************************************************************************
36
+
37
+
38
+ from warnings import warn
39
+
40
+ from sage.misc.verbose import verbose
41
+ from sage.misc.cachefunc import cached_method
42
+ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_domain
43
+ from sage.rings.polynomial.polynomial_quotient_ring_element import PolynomialQuotientRingElement
44
+
45
+
46
+ # ------------------------------------------------------------------------------------------------------------------
47
+ # Element class for the splitting algebra
48
+ # --------------------------------------------------------------------------------------------------------
49
+ class SplittingAlgebraElement(PolynomialQuotientRingElement):
50
+ r"""
51
+ Element class for :class:`SplittingAlgebra`.
52
+
53
+ EXAMPLES::
54
+
55
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
56
+ sage: cp6 = cyclotomic_polynomial(6)
57
+ sage: CR6.<e6> = SplittingAlgebra(cp6)
58
+ sage: type(e6)
59
+ <class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category.element_class'>
60
+
61
+ sage: type(CR6(5))
62
+ <class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category.element_class'>
63
+ """
64
+ def __invert__(self):
65
+ r"""
66
+ Return the inverse of ``self``.
67
+
68
+ Support inversion of special elements attached to the construction
69
+ of the parent and which are recorded in the list
70
+ ``self.parent()._invertible_elements``.
71
+
72
+ EXAMPLES::
73
+
74
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
75
+ sage: CR3.<e3> = SplittingAlgebra(cyclotomic_polynomial(3))
76
+ sage: ~e3
77
+ -e3 - 1
78
+ sage: ~(e3 + 5)
79
+ Traceback (most recent call last):
80
+ ...
81
+ ArithmeticError: element is non-invertible
82
+ """
83
+ inv_elements = self.parent()._invertible_elements
84
+ if self in inv_elements:
85
+ return inv_elements[self]
86
+
87
+ return super().__invert__()
88
+
89
+ def is_unit(self):
90
+ r"""
91
+ Return ``True`` if ``self`` is invertible.
92
+
93
+ EXAMPLES::
94
+
95
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
96
+ sage: CR3.<e3> = SplittingAlgebra(cyclotomic_polynomial(3))
97
+ sage: e3.is_unit()
98
+ True
99
+ """
100
+ inv_elements = self.parent()._invertible_elements
101
+ if self in inv_elements:
102
+ return True
103
+
104
+ return super().is_unit()
105
+
106
+ def monomial_coefficients(self, copy=True):
107
+ r"""
108
+ Return the dictionary of ``self`` according to its lift to the cover.
109
+
110
+ EXAMPLES::
111
+
112
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
113
+ sage: CR3.<e3> = SplittingAlgebra(cyclotomic_polynomial(3))
114
+ sage: f = e3 + 42
115
+ sage: f.monomial_coefficients()
116
+ {0: 42, 1: 1}
117
+
118
+ ``dict`` is an alias::
119
+
120
+ sage: f.dict()
121
+ {0: 42, 1: 1}
122
+ """
123
+ return self.lift().monomial_coefficients(copy=copy)
124
+
125
+ dict = monomial_coefficients
126
+
127
+ # ------------------------------------------------------------------------------------------------------------------
128
+ # Parent class of the splitting algebra
129
+ # --------------------------------------------------------------------------------------------------------
130
+
131
+
132
+ class SplittingAlgebra(PolynomialQuotientRing_domain):
133
+ r"""
134
+ For a given monic polynomial `p(t)` of degree `n` over a commutative
135
+ ring `R`, the splitting algebra is the universal `R`-algebra in which
136
+ `p(t)` has `n` roots, or, more precisely, over which `p(t)` factors,
137
+
138
+ .. MATH::
139
+
140
+ p(t) = (t - \xi_1) \cdots (t - \xi_n).
141
+
142
+ This class creates an algebra as extension over the base ring of a
143
+ given polynomial `p` such that `p` splits into linear factors over
144
+ that extension. It is assumed (and not checked in general) that the
145
+ Galois group of `p` is the symmetric Group `S(n)`. The construction
146
+ is recursive (following [LT2012]_, 1.3).
147
+
148
+ INPUT:
149
+
150
+ - ``monic_polynomial`` -- the monic polynomial which should be split
151
+ - ``names`` -- names for the indeterminates to be adjoined to the
152
+ base ring of ``monic_polynomial``
153
+ - ``warning`` -- boolean (default: ``True``); can be used (by setting to
154
+ ``False``) to suppress a warning which will be thrown whenever it cannot
155
+ be checked that the Galois group of ``monic_polynomial`` is maximal
156
+
157
+ EXAMPLES::
158
+
159
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
160
+ sage: Lc.<w> = LaurentPolynomialRing(ZZ)
161
+ sage: PabLc.<u,v> = Lc[]; t = polygen(PabLc)
162
+ sage: S.<x, y> = SplittingAlgebra(t^3 - u*t^2 + v*t - w)
163
+ doctest:...: UserWarning: Assuming x^3 - u*x^2 + v*x - w to have maximal
164
+ Galois group!
165
+
166
+ sage: roots = S.splitting_roots(); roots
167
+ [x, y, -y - x + u]
168
+ sage: all(t^3 -u*t^2 +v*t -w == 0 for t in roots)
169
+ True
170
+ sage: xi = ~x; xi
171
+ (w^-1)*x^2 + ((-w^-1)*u)*x + (w^-1)*v
172
+ sage: ~xi == x
173
+ True
174
+ sage: ~y
175
+ ((-w^-1)*x)*y + (-w^-1)*x^2 + ((w^-1)*u)*x
176
+ sage: zi = ((w^-1)*x)*y; ~zi
177
+ -y - x + u
178
+
179
+ sage: cp3 = cyclotomic_polynomial(3).change_ring(GF(5))
180
+ sage: CR3.<e3> = SplittingAlgebra(cp3)
181
+ sage: CR3.is_field()
182
+ True
183
+ sage: CR3.cardinality()
184
+ 25
185
+ sage: F.<a> = cp3.splitting_field()
186
+ sage: F.cardinality()
187
+ 25
188
+ sage: E3 = cp3.change_ring(F).roots()[0][0]; E3
189
+ 3*a + 3
190
+ sage: f = CR3.hom([E3]); f
191
+ Ring morphism:
192
+ From: Splitting Algebra of x^2 + x + 1
193
+ with roots [e3, 4*e3 + 4]
194
+ over Finite Field of size 5
195
+ To: Finite Field in a of size 5^2
196
+ Defn: e3 |--> 3*a + 3
197
+
198
+ REFERENCES:
199
+
200
+ - [EL2002]_
201
+ - [Lak2010]_
202
+ - [Tho2011]_
203
+ - [LT2012]_
204
+ """
205
+ Element = SplittingAlgebraElement
206
+
207
+ def __init__(self, monic_polynomial, names='X', iterate=True, warning=True):
208
+ r"""
209
+ Python constructor.
210
+
211
+ EXAMPLES::
212
+
213
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
214
+ sage: Lw.<w> = LaurentPolynomialRing(ZZ)
215
+ sage: PuvLw.<u,v> = Lw[]; t = polygen(PuvLw)
216
+ sage: S.<x, y> = SplittingAlgebra(t^3 - u*t^2 + v*t - w, warning=False)
217
+ sage: TestSuite(S).run()
218
+ """
219
+
220
+ # ---------------------------------------------------------------------------------
221
+ # checking input parameters
222
+ # ---------------------------------------------------------------------------------
223
+
224
+ base_ring = monic_polynomial.base_ring()
225
+ if not monic_polynomial.is_monic():
226
+ raise ValueError("given polynomial must be monic")
227
+ deg = monic_polynomial.degree()
228
+
229
+ from sage.structure.category_object import normalize_names
230
+ self._root_names = normalize_names(deg-1, names)
231
+ root_names = list(self._root_names)
232
+ verbose("Create splitting algebra to base ring %s and polynomial %s (%s %s)"
233
+ % (base_ring, monic_polynomial, iterate, warning))
234
+
235
+ self._defining_polynomial = monic_polynomial
236
+ self._iterate = iterate
237
+
238
+ try:
239
+ if not base_ring.is_integral_domain():
240
+ raise TypeError("base_ring must be an integral domain")
241
+ except NotImplementedError:
242
+ from sage.categories.rings import Rings
243
+ if base_ring not in Rings():
244
+ raise TypeError("base_ring must be a ring")
245
+ if warning:
246
+ warn('Assuming %s to be an integral domain!' % base_ring)
247
+
248
+ if deg < 1:
249
+ raise ValueError("the degree of the polynomial must positive")
250
+
251
+ self._splitting_roots = []
252
+ self._coefficients_list = []
253
+ self._invertible_elements = {}
254
+
255
+ if isinstance(base_ring, SplittingAlgebra):
256
+ self._invertible_elements = base_ring._invertible_elements
257
+
258
+ # ------------------------------------------------------------------------------------
259
+ # taking next root_name
260
+ # ------------------------------------------------------------------------------------
261
+ root_name = root_names[0]
262
+ p = monic_polynomial.change_variable_name(root_name)
263
+ P = p.parent()
264
+
265
+ self._set_modulus_irreducible_ = False
266
+ try:
267
+ if not p.is_irreducible():
268
+ raise ValueError("monic_polynomial must be irreducible")
269
+ except (NotImplementedError, AttributeError):
270
+ # assuming this has been checked mathematically before
271
+ self._set_modulus_irreducible_ = True
272
+ if warning:
273
+ warn('Assuming %s to have maximal Galois group!' % (monic_polynomial))
274
+ warning = False # one warning must be enough
275
+
276
+ verbose("P %s defined:" % (P))
277
+
278
+ if deg > 2 and iterate:
279
+ # ------------------------------------------------------------------------------------
280
+ # successive solution via recursion (on base_ring_step)
281
+ # ------------------------------------------------------------------------------------
282
+ base_ring_step = SplittingAlgebra(monic_polynomial, tuple(root_names), iterate=False, warning=False)
283
+ first_root = base_ring_step.gen()
284
+
285
+ verbose("base_ring_step %s defined:" % (base_ring_step))
286
+
287
+ # -------------------------------------------------------------
288
+ # splitting first root off
289
+ # -------------------------------------------------------------
290
+ from copy import copy
291
+ root_names_reduces = copy(root_names)
292
+ root_names_reduces.remove(root_name)
293
+
294
+ P = base_ring_step[root_names_reduces[0]]
295
+ p = P(monic_polynomial.monomial_coefficients())
296
+ q, _ = p.quo_rem(P.gen() - first_root)
297
+
298
+ verbose("Invoking recursion with: %s" % (q,))
299
+
300
+ SplittingAlgebra.__init__(self, q, root_names_reduces, warning=False)
301
+
302
+ splitting_roots = base_ring_step._splitting_roots + self._splitting_roots
303
+ coefficients_list = base_ring_step._coefficients_list + self._coefficients_list
304
+
305
+ verbose("Adding roots: %s" % (splitting_roots))
306
+
307
+ self._splitting_roots = splitting_roots
308
+ self._coefficients_list = coefficients_list
309
+ else:
310
+ PolynomialQuotientRing_domain.__init__(self, P, p, root_name)
311
+
312
+ first_root = self.gen()
313
+ self._splitting_roots.append(first_root)
314
+ self._coefficients_list = [monic_polynomial.coefficients(sparse=False)]
315
+
316
+ if not iterate:
317
+ verbose("pre ring defined splitting_roots: %s" % (self._splitting_roots))
318
+ return
319
+
320
+ verbose("final ring defined splitting_roots: %s" % (self._splitting_roots))
321
+
322
+ if deg == 2:
323
+ coefficients = monic_polynomial.coefficients(sparse=False)
324
+ lin_coeff = coefficients[1]
325
+ self._splitting_roots.append(-lin_coeff - first_root)
326
+
327
+ self._root_names = names
328
+ self._splitting_roots = [self(root) for root in self._splitting_roots]
329
+ verbose("splitting_roots: %s embedded" % (self._splitting_roots))
330
+
331
+ # --------------------------------------------------------------------
332
+ # try to calculate inverses of the roots. This is possible if the original polynomial
333
+ # has an invertible constant term. For example let cf = [-w, v,-u, 1] that is
334
+ # p = h^3 -u*h^2 + v*h -w, than u = x + y + z, v = x*y + x*z + y*z, w = x*y*z. If
335
+ # w is invertible then 1/x = (v -(u-x)*x)/w, 1/y = (v -(u-y)*y)/w, 1/z = (v -(u-z)*z)/w
336
+ # -----------------------------------------------------------------
337
+ # first find the polynomial with invertible constant coefficient
338
+ # -----------------------------------------------------------------
339
+ cf0_inv = None
340
+ for cf in self._coefficients_list:
341
+ cf0 = cf[0]
342
+ try:
343
+ cf0_inv = ~(cf[0])
344
+ cf0_inv = self(cf0_inv)
345
+ verbose("invertible coefficient: %s found" % (cf0_inv))
346
+ break
347
+ except NotImplementedError:
348
+ verbose("constant coefficient: %s not invertibe" % (cf0))
349
+
350
+ # ------------------------------------------------------------------
351
+ # assuming that cf splits into linear factors over self
352
+ # and the _splitting_roots are its roots we can calculate inverses
353
+ # ------------------------------------------------------------------
354
+ if cf0_inv is not None:
355
+ deg_cf = len(cf)-1
356
+ pf = P(cf)
357
+ for root in self._splitting_roots:
358
+ check = self(pf)
359
+ if not check.is_zero():
360
+ continue
361
+ root_inv = self.one()
362
+ for pos in range(deg_cf-1):
363
+ root_inv = (-1)**(pos+1) * cf[deg_cf-pos-1] - root_inv * root
364
+ verbose("inverse %s of root %s" % (root_inv, root))
365
+ root_inv = (-1)**(deg_cf) * cf0_inv * root_inv
366
+ self._invertible_elements.update({root:root_inv})
367
+ verbose("adding inverse %s of root %s" % (root_inv, root))
368
+ invert_items = list(self._invertible_elements.items())
369
+ for k, v in invert_items:
370
+ self._invertible_elements.update({v: k})
371
+ return
372
+
373
+ ########################################################################
374
+ # ----------------------------------------------------------------------
375
+ # overloaded inherited methods
376
+ # ----------------------------------------------------------------------
377
+ ########################################################################
378
+ def __reduce__(self):
379
+ r"""
380
+ Used in pickling.
381
+
382
+ EXAMPLES::
383
+
384
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
385
+ sage: L.<t, u, v, w > = LaurentPolynomialRing(ZZ); x = polygen(L)
386
+ sage: S = SplittingAlgebra(x^4 -t*x^3 - u*x^2 - v*x + w, ('X', 'Y', 'Z'), warning=False)
387
+ sage: S.__reduce__()
388
+ (<class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category'>,
389
+ (x^4 - t*x^3 - u*x^2 - v*x + w, ('X', 'Y', 'Z'), True, False))
390
+ sage: S.base_ring().__reduce__()
391
+ (<class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category'>,
392
+ (Y^3 + (X - t)*Y^2 + (X^2 - t*X - u)*Y + X^3 - t*X^2 - u*X - v,
393
+ ('Y', 'Z'),
394
+ False,
395
+ False))
396
+
397
+ sage: TestSuite(S).run()
398
+ """
399
+ defining_polynomial = self.defining_polynomial()
400
+ definig_coefficients = self._coefficients_list[0]
401
+ if defining_polynomial.coefficients(sparse=False) != definig_coefficients:
402
+ # case of factorization algebra (intermediate construction step)
403
+ par_pol = self.cover_ring()
404
+ defining_polynomial = par_pol(definig_coefficients)
405
+ return self.__class__, (defining_polynomial, self._root_names, self._iterate, False)
406
+
407
+ def _repr_(self):
408
+ r"""
409
+ Return a string representation of ``self``.
410
+
411
+ EXAMPLES::
412
+
413
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
414
+ sage: L.<u, v> = PolynomialRing(ZZ)
415
+ sage: t = polygen(L)
416
+ sage: Spl.<S, T> = SplittingAlgebra(t^3 - (u^2-v)*t^2 + (v+u)*t - 1)
417
+ sage: Spl._repr_()
418
+ 'Splitting Algebra of x^3 + (-u^2 + v)*x^2 + (u + v)*x - 1
419
+ with roots [S, T, -T - S + u^2 - v]
420
+ over Multivariate Polynomial Ring in u, v over Integer Ring'
421
+ sage: Spl.base_ring() # indirect doctest
422
+ Factorization Algebra of x^3 + (-u^2 + v)*x^2 + (u + v)*x - 1
423
+ with roots [S] over Multivariate Polynomial Ring in u, v over Integer Ring
424
+ """
425
+ if self.is_completely_split():
426
+ return ('Splitting Algebra of %s with roots %s over %s'
427
+ % (self.defining_polynomial(), self.splitting_roots(), self.scalar_base_ring()))
428
+ else:
429
+ return ('Factorization Algebra of %s with roots %s over %s'
430
+ % (self.defining_polynomial(), self.splitting_roots(), self.scalar_base_ring()))
431
+
432
+ def _first_ngens(self, n):
433
+ r"""
434
+ Used by the preparser for ``R.<x> = ...``.
435
+
436
+ EXAMPLES::
437
+
438
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
439
+ sage: L.<u, v> = PolynomialRing(ZZ)
440
+ sage: t = polygen(L)
441
+ sage: S.<X, Y> = SplittingAlgebra(t^3 - (u^2-v)*t^2 + (v+u)*t - 1) # indirect doctest
442
+ sage: X.parent()
443
+ Splitting Algebra of x^3 + (-u^2 + v)*x^2 + (u + v)*x - 1
444
+ with roots [X, Y, -Y - X + u^2 - v]
445
+ over Multivariate Polynomial Ring in u, v over Integer Ring
446
+ sage: S._first_ngens(4)
447
+ (X, Y, u, v)
448
+ """
449
+ srts = self.splitting_roots()
450
+ k = len(srts)-1
451
+ gens = srts[:k] + list(self.scalar_base_ring().gens())
452
+ return tuple(gens[:n])
453
+
454
+ def _element_constructor_(self, x):
455
+ r"""
456
+ Make sure ``x`` is a valid member of ``self``, and return the constructed element.
457
+
458
+ TESTS::
459
+
460
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
461
+ sage: L.<u, v, w> = LaurentPolynomialRing(ZZ); x = polygen(L)
462
+ sage: S.<X, Y> = SplittingAlgebra(x^3 - u*x^2 + v*x - w)
463
+ sage: S(u + v)
464
+ u + v
465
+ sage: S(X*Y + X)
466
+ X*Y + X
467
+ sage: TestSuite(S).run() # indirect doctest
468
+ """
469
+ if isinstance(x, SplittingAlgebraElement):
470
+ # coercion from covering fixes pickling problems
471
+ return self(x.lift())
472
+ return super()._element_constructor_(x)
473
+
474
+ def hom(self, im_gens, codomain=None, check=True, base_map=None):
475
+ r"""
476
+ This version keeps track with the special recursive structure
477
+ of :class:`SplittingAlgebra`
478
+
479
+ Type ``Ring.hom?`` to see the general documentation of this method.
480
+ Here you see just special examples for the current class.
481
+
482
+ EXAMPLES::
483
+
484
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
485
+ sage: L.<u, v, w> = LaurentPolynomialRing(ZZ); x = polygen(L)
486
+ sage: S = SplittingAlgebra(x^3 - u*x^2 + v*x - w, ('X', 'Y'))
487
+ sage: P.<x, y, z> = PolynomialRing(ZZ)
488
+ sage: F = FractionField(P)
489
+ sage: im_gens = [F(g) for g in [y, x, x + y + z, x*y+x*z+y*z, x*y*z]]
490
+ sage: f = S.hom(im_gens)
491
+ sage: f(u), f(v), f(w)
492
+ (x + y + z, x*y + x*z + y*z, x*y*z)
493
+ sage: roots = S.splitting_roots(); roots
494
+ [X, Y, -Y - X + u]
495
+ sage: [f(r) for r in roots]
496
+ [x, y, z]
497
+ """
498
+ base_ring = self.base_ring()
499
+
500
+ if not isinstance(im_gens, (list, tuple)):
501
+ im_gens = [im_gens]
502
+
503
+ all_gens = self.gens_dict_recursive()
504
+ if len(im_gens) != len(all_gens):
505
+ return super().hom(im_gens, codomain=codomain, check=check, base_map=base_map)
506
+
507
+ num_gens = len(self.gens())
508
+ im_gens_start = [img for img in im_gens if im_gens.index(img) < num_gens]
509
+ im_gens_end = [img for img in im_gens if im_gens.index(img) >= num_gens]
510
+
511
+ if not im_gens_end:
512
+ return super().hom(im_gens, codomain=codomain, check=check, base_map=base_map)
513
+
514
+ verbose('base %s im_gens_end %s codomain %s check %s base_map %s' % (base_ring, im_gens_end, codomain, check, base_map))
515
+ hom_on_base_recurs = base_ring.hom(im_gens_end, codomain=codomain, check=check, base_map=base_map)
516
+ verbose('hom_on_base_recurs %s' % (hom_on_base_recurs))
517
+
518
+ cover_ring = self.cover_ring()
519
+ hom_from_cover = cover_ring.hom(im_gens_start, codomain=codomain, check=check, base_map=hom_on_base_recurs)
520
+ lift = self.lifting_map()
521
+ return hom_from_cover*lift
522
+
523
+ ###################################################################
524
+ # -----------------------------------------------------------------
525
+ # local methods
526
+ # -----------------------------------------------------------------
527
+ ###################################################################
528
+
529
+ ###################################################################
530
+ # -----------------------------------------------------------------
531
+ # global methods
532
+ # -----------------------------------------------------------------
533
+ ###################################################################
534
+
535
+ def is_completely_split(self):
536
+ r"""
537
+ Return ``True`` if the defining polynomial of ``self`` splits into
538
+ linear factors over ``self``.
539
+
540
+ EXAMPLES::
541
+
542
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
543
+ sage: L.<u, v, w > = LaurentPolynomialRing(ZZ); x = polygen(L)
544
+ sage: S.<a,b> = SplittingAlgebra(x^3 - u*x^2 + v*x - w)
545
+ sage: S.is_completely_split()
546
+ True
547
+ sage: S.base_ring().is_completely_split()
548
+ False
549
+ """
550
+ return len(self.splitting_roots()) >= self.defining_polynomial().degree()
551
+
552
+ @cached_method
553
+ def lifting_map(self):
554
+ r"""
555
+ Return a section map from ``self`` to the cover ring. It is implemented according
556
+ to the same named method of :class:`~sage.rings.quotient_ring.QuotientRing_nc`.
557
+
558
+ EXAMPLES::
559
+
560
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
561
+ sage: x = polygen(ZZ)
562
+ sage: S = SplittingAlgebra(x^2+1, ('I',))
563
+ sage: lift = S.lifting_map()
564
+ sage: lift(5)
565
+ 5
566
+ sage: r1, r2 =S.splitting_roots()
567
+ sage: lift(r1)
568
+ I
569
+ """
570
+ from sage.rings.morphism import RingMap_lift
571
+ return RingMap_lift(self, self.cover_ring())
572
+
573
+ def splitting_roots(self):
574
+ r"""
575
+ Return the roots of the split equation.
576
+
577
+ EXAMPLES::
578
+
579
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
580
+ sage: x = polygen(ZZ)
581
+ sage: S = SplittingAlgebra(x^2+1, ('I',))
582
+ sage: S.splitting_roots()
583
+ [I, -I]
584
+ """
585
+ return self._splitting_roots
586
+
587
+ @cached_method
588
+ def scalar_base_ring(self):
589
+ r"""
590
+ Return the ring of scalars of ``self`` (considered as an algebra).
591
+
592
+ EXAMPLES::
593
+
594
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
595
+ sage: L.<u, v, w > = LaurentPolynomialRing(ZZ)
596
+ sage: x = polygen(L)
597
+ sage: S = SplittingAlgebra(x^3 - u*x^2 + v*x - w, ('X', 'Y'))
598
+ sage: S.base_ring()
599
+ Factorization Algebra of x^3 - u*x^2 + v*x - w with roots [X]
600
+ over Multivariate Laurent Polynomial Ring in u, v, w over Integer Ring
601
+ sage: S.scalar_base_ring()
602
+ Multivariate Laurent Polynomial Ring in u, v, w over Integer Ring
603
+ """
604
+ base_ring = self.base_ring()
605
+ if isinstance(base_ring, SplittingAlgebra):
606
+ if base_ring.is_completely_split():
607
+ # another splitting algebra independent of self
608
+ return base_ring
609
+ else:
610
+ return base_ring.scalar_base_ring()
611
+ return base_ring
612
+
613
+ @cached_method
614
+ def defining_polynomial(self):
615
+ r"""
616
+ Return the defining polynomial of ``self``.
617
+
618
+ EXAMPLES::
619
+
620
+ sage: from sage.algebras.splitting_algebra import SplittingAlgebra
621
+ sage: L.<u, v, w > = LaurentPolynomialRing(ZZ)
622
+ sage: x = polygen(L)
623
+ sage: S = SplittingAlgebra(x^3 - u*x^2 + v*x - w, ('X', 'Y'))
624
+ sage: S.defining_polynomial()
625
+ x^3 - u*x^2 + v*x - w
626
+ """
627
+ base_ring = self.base_ring()
628
+ if isinstance(base_ring, SplittingAlgebra):
629
+ if base_ring.is_completely_split():
630
+ # another splitting algebra independent of self
631
+ return self._defining_polynomial
632
+ else:
633
+ return base_ring.defining_polynomial()
634
+ return self._defining_polynomial
635
+
636
+
637
+ # --------------------------------------------------------------------------------------------
638
+ # ============================================================================================
639
+ # Utility function to create the roots of a polynomial in an appropriate extension ring
640
+ # ============================================================================================
641
+ # --------------------------------------------------------------------------------------------
642
+
643
+ def solve_with_extension(monic_polynomial, root_names=None, var='x', flatten=False, warning=True):
644
+ r"""
645
+ Return all roots of a monic polynomial in its base ring or in an appropriate
646
+ extension ring, as far as possible.
647
+
648
+ INPUT:
649
+
650
+ - ``monic_polynomial`` -- the monic polynomial whose roots should be created
651
+ - ``root_names`` -- names for the indeterminates needed to define the
652
+ splitting algebra of the ``monic_polynomial`` (if necessary and possible)
653
+ - ``var`` -- (default: ``'x'``) for the indeterminate needed to define the
654
+ splitting field of the ``monic_polynomial`` (if necessary and possible)
655
+ - ``flatten`` -- boolean (default: ``True``); if ``True`` the roots will
656
+ not be given as a list of pairs ``(root, multiplicity)`` but as a list of
657
+ roots repeated according to their multiplicity
658
+ - ``warning`` -- boolean (default: ``True``); can be used (by setting to
659
+ ``False``) to suppress a warning which will be thrown whenever it cannot
660
+ be checked that the Galois group of ``monic_polynomial`` is maximal
661
+
662
+ OUTPUT:
663
+
664
+ List of tuples ``(root, multiplicity)`` respectively list of roots repeated
665
+ according to their multiplicity if option ``flatten`` is ``True``.
666
+
667
+ EXAMPLES::
668
+
669
+ sage: from sage.algebras.splitting_algebra import solve_with_extension
670
+ sage: t = polygen(ZZ)
671
+ sage: p = t^2 -2*t +1
672
+ sage: solve_with_extension(p, flatten=True )
673
+ [1, 1]
674
+ sage: solve_with_extension(p)
675
+ [(1, 2)]
676
+
677
+ sage: cp5 = cyclotomic_polynomial(5, var='T').change_ring(UniversalCyclotomicField())
678
+ sage: solve_with_extension(cp5)
679
+ [(E(5), 1), (E(5)^4, 1), (E(5)^2, 1), (E(5)^3, 1)]
680
+ sage: _[0][0].parent()
681
+ Universal Cyclotomic Field
682
+ """
683
+ def create_roots(monic_polynomial, warning=True):
684
+ r"""
685
+ This internal function creates all roots of a polynomial in an
686
+ appropriate extension ring assuming that none of the roots is
687
+ contained its base ring.
688
+
689
+ It first tries to create the splitting field of the given polynomial.
690
+ If this is not faithful the splitting algebra will be created.
691
+
692
+ INPUT:
693
+
694
+ - ``monic_polynomial`` -- the monic polynomial whose roots should
695
+ be created
696
+ - ``warning`` -- boolean (default: ``True``); can be used (by setting
697
+ to ``False``) to suppress a warning which will be thrown whenever it
698
+ cannot be checked that the Galois group of ``monic_polynomial`` is
699
+ maximal
700
+ """
701
+ parent = monic_polynomial.parent()
702
+ base_ring = parent.base_ring()
703
+
704
+ try:
705
+ ext_field, embed = monic_polynomial.splitting_field(var, map=True)
706
+
707
+ if embed.domain() != base_ring:
708
+ # in this case the SplittingAlgebra is preferred
709
+ raise NotImplementedError
710
+
711
+ # -------------------------------------------------------------------------------------
712
+ # in some cases the embedding of the base_ring in ext_field can not be obtained
713
+ # as coercion
714
+ # -------------------------------------------------------------------------------------
715
+ reset_coercion = False
716
+ from sage.rings.number_field.number_field import NumberField_generic
717
+ if isinstance(base_ring, NumberField_generic):
718
+ reset_coercion = True
719
+ elif base_ring.is_finite() and not base_ring.is_prime_field():
720
+ reset_coercion = True
721
+ if reset_coercion:
722
+ ext_field._unset_coercions_used()
723
+ ext_field.register_coercion(embed)
724
+ ext_field.register_conversion(embed)
725
+
726
+ verbose("splitting field %s defined" % (ext_field))
727
+ pol_emb = monic_polynomial.change_ring(ext_field)
728
+ roots = pol_emb.roots()
729
+ except NotImplementedError:
730
+ ext_ring = SplittingAlgebra(monic_polynomial, name_list, warning=warning)
731
+ verbose("splitting algebra %s defined" % (ext_ring))
732
+ roots = [(r, 1) for r in ext_ring.splitting_roots()]
733
+ return roots
734
+
735
+ deg_pol = monic_polynomial.degree()
736
+ if not root_names:
737
+ from sage.structure.category_object import normalize_names
738
+ root_names = normalize_names(deg_pol-1, 'r')
739
+ name_list = list(root_names)
740
+ root_list = []
741
+ try:
742
+ root_list = monic_polynomial.roots()
743
+ except (TypeError, ValueError, NotImplementedError):
744
+ pass
745
+
746
+ if not root_list:
747
+ # --------------------------------------------------------------
748
+ # no roots found: find roots in an appropriate extension ring
749
+ # --------------------------------------------------------------
750
+ verbose("no roots in base_ring")
751
+ if len(name_list) > deg_pol - 1:
752
+ name_list = [name_list[i] for i in range(deg_pol - 1)]
753
+ roots = create_roots(monic_polynomial, warning=warning)
754
+
755
+ else:
756
+ # ------------------------------------------------------------------
757
+ # root calculation was possible but maybe some more roots in
758
+ # an appropriate extension ring can be constructed.
759
+ # ------------------------------------------------------------------
760
+ num_roots = sum(m for r, m in root_list)
761
+ if num_roots < deg_pol:
762
+ h = monic_polynomial.variables()[0]
763
+ divisor = monic_polynomial.base_ring().one()
764
+ for r, m in root_list:
765
+ divisor *= (h - r)**m
766
+ q, r = monic_polynomial.quo_rem(divisor)
767
+ if len(name_list) > deg_pol - num_roots - 1:
768
+ name_list = [name_list[i] for i in range(deg_pol - num_roots - 1)]
769
+ verbose("%d root found in base ring, now solving %s" % (num_roots,q))
770
+ missing_roots = create_roots(q, warning=True)
771
+ roots = root_list + missing_roots
772
+ else:
773
+ roots = root_list
774
+ verbose("all roots in base ring")
775
+
776
+ if flatten:
777
+ from sage.misc.flatten import flatten
778
+ return flatten([[rt]*m for rt, m in roots])
779
+ return roots