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,1721 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.libs.pari sage.modules
3
+ r"""
4
+ Similarity class types of matrices with entries in a finite field
5
+
6
+ The notion of a matrix conjugacy class type was introduced by J. A. Green in
7
+ [Green55]_, in the context of computing the irreducible characters of finite
8
+ general linear groups. The class types are equivalence classes of similarity
9
+ classes of square matrices with entries in a finite field which, roughly
10
+ speaking, have the same qualitative properties.
11
+
12
+ For example, all similarity classes of the same class type have centralizers of
13
+ the same cardinality and the same degrees of elementary divisors. Qualitative
14
+ properties of similarity classes such as semisimplicity and regularity descend
15
+ to class types.
16
+
17
+ The most important feature of similarity class types is that, for any `n`, the
18
+ number of similarity class types of `n\times n` matrices is independent of `q`.
19
+ This makes it possible to perform many combinatorial calculations treating `q`
20
+ as a formal variable.
21
+
22
+ In order to define similarity class types, recall that similarity classes of
23
+ `n\times n` matrices with entries in `\GF{q}` correspond to functions
24
+
25
+ .. MATH::
26
+
27
+ c: \mathrm{Irr}\GF{q[t]} \to \Lambda
28
+
29
+ such that
30
+
31
+ .. MATH::
32
+
33
+ \sum_{f\in \mathrm{Irr}\GF{q[t]}} |c(f)|\deg f = n,
34
+
35
+ where we denote the set of irreducible monic polynomials in `\GF{q[t]}`
36
+ by `\mathrm{Irr}\GF{q[t]}`, the set of all partitions by `\Lambda`, and
37
+ the size of `\lambda \in \Lambda` by `|\lambda|`.
38
+
39
+ Similarity classes indexed by functions `c_1` and `c_2` as above are said to be
40
+ of the same type if there exists a degree-preserving self-bijection `\sigma` of
41
+ `\mathrm{Irr}\GF{q[t]}` such that `c_2 = c_1\circ \sigma`. Thus, the type
42
+ of `c` remembers only the degrees of the polynomials (and not the polynomials
43
+ themselves) for which `c` takes a certain value `\lambda`. Replacing each
44
+ irreducible polynomial of degree `d` for which `c` takes a non-trivial value
45
+ `\lambda` by the pair `(d, \lambda)`, we obtain a multiset of such pairs.
46
+ Clearly, `c_1` and `c_2` have the same type if and only if these multisets are
47
+ equal. Thus a similarity class type may be viewed as a multiset of pairs of the
48
+ form `(d, \lambda)`.
49
+
50
+ For `2 \times 2` matrices there are four types::
51
+
52
+ sage: for tau in SimilarityClassTypes(2):
53
+ ....: print(tau)
54
+ [[1, [1]], [1, [1]]]
55
+ [[1, [2]]]
56
+ [[1, [1, 1]]]
57
+ [[2, [1]]]
58
+
59
+ These four types correspond to the regular split semisimple matrices, the
60
+ non-semisimple matrices, the central matrices and the irreducible matrices
61
+ respectively.
62
+
63
+ For any matrix `A` in a given similarity class type, it is possible to calculate
64
+ the number elements in the similarity class of `A`, the dimension of the algebra
65
+ of matrices in `M_n(A)` that commute with `A`, and the cardinality of the
66
+ subgroup of `GL_n(\GF{q})` that commute with `A`. For each similarity
67
+ class type, it is also possible to compute the number of classes of that type
68
+ (and hence, the total number of matrices of that type). All these calculations
69
+ treat the cardinality `q` of the finite field as a formal variable::
70
+
71
+ sage: M = SimilarityClassType([[1, [1]], [1, [1]]])
72
+ sage: M.class_card()
73
+ q^2 + q
74
+ sage: M.centralizer_algebra_dim()
75
+ 2
76
+ sage: M.centralizer_group_card()
77
+ q^2 - 2*q + 1
78
+ sage: M.number_of_classes()
79
+ 1/2*q^2 - 1/2*q
80
+ sage: M.number_of_matrices()
81
+ 1/2*q^4 - 1/2*q^2
82
+
83
+ We now describe two applications of similarity class types.
84
+
85
+ We say that an `n \times n` matrix has rational canonical form type `\lambda` for
86
+ some partition `\lambda` of `n` if the diagonal blocks in the rational canonical
87
+ form have sizes given by the parts of `\lambda`. Thus the matrices with rational
88
+ canonical type `(n)` are the regular ones, while the matrices with rational
89
+ canonical type `(1^n)` are the central ones.
90
+
91
+ Using similarity class types, it becomes easy to get a formula for the number of
92
+ matrices with a given rational canonical type::
93
+
94
+ sage: def matrices_with_rcf(la):
95
+ ....: return sum([tau.number_of_matrices() for tau in filter(lambda tau:tau.rcf()==la, SimilarityClassTypes(la.size()))])
96
+ sage: matrices_with_rcf(Partition([2,1]))
97
+ q^6 + q^5 + q^4 - q^3 - q^2 - q
98
+
99
+ Similarity class types can also be used to calculate the number of simultaneous
100
+ similarity classes of `k`-tuples of `n\times n` matrices with entries in
101
+ `\GF{q}` by using Burnside's lemma::
102
+
103
+ sage: from sage.combinat.similarity_class_type import order_of_general_linear_group, centralizer_algebra_dim
104
+ sage: q = ZZ['q'].gen()
105
+ sage: def simultaneous_similarity_classes(n, k):
106
+ ....: return SimilarityClassTypes(n).sum(lambda la: q**(k*centralizer_algebra_dim(la)), invertible = True)/order_of_general_linear_group(n)
107
+ sage: simultaneous_similarity_classes(3, 2)
108
+ q^10 + q^8 + 2*q^7 + 2*q^6 + 2*q^5 + q^4
109
+
110
+ Similarity class types can be used to compute the coefficients of generating
111
+ functions coming from the cycle index type techniques of Kung and Stong (see
112
+ Morrison [Morrison06]_).
113
+
114
+ They can also be used to compute the number of invariant subspaces for a matrix
115
+ over a finite field of any given dimension. For this we use the elegant recursive
116
+ formula of Ramaré [R17]_ (see also [PR22]_).
117
+
118
+ Along with the results of [PSS13]_, similarity class types can be used to
119
+ calculate the number of similarity classes of matrices of order `n` with entries
120
+ in a principal ideal local ring of length two with residue field of cardinality
121
+ `q` with centralizer of any given cardinality up to `n = 4`. Among these, the
122
+ classes which are selftranspose can also be counted::
123
+
124
+ sage: from sage.combinat.similarity_class_type import matrix_centralizer_cardinalities_length_two
125
+ sage: list(matrix_centralizer_cardinalities_length_two(3))
126
+ [(q^6 - 3*q^5 + 3*q^4 - q^3, 1/6*q^6 - 1/2*q^5 + 1/3*q^4),
127
+ (q^6 - 2*q^5 + q^4, q^5 - q^4),
128
+ (q^8 - 3*q^7 + 3*q^6 - q^5, 1/2*q^5 - q^4 + 1/2*q^3),
129
+ (q^8 - 2*q^7 + q^6, q^4 - q^3),
130
+ (q^10 - 2*q^9 + 2*q^7 - q^6, q^4 - q^3),
131
+ (q^8 - q^7 - q^6 + q^5, 1/2*q^5 - q^4 + 1/2*q^3),
132
+ (q^6 - q^5 - q^4 + q^3, 1/2*q^6 - 1/2*q^5),
133
+ (q^6 - q^5, q^4),
134
+ (q^10 - 2*q^9 + q^8, q^3),
135
+ (q^8 - 2*q^7 + q^6, q^4 - q^3),
136
+ (q^8 - q^7, q^3 + q^2),
137
+ (q^12 - 3*q^11 + 3*q^10 - q^9, 1/6*q^4 - 1/2*q^3 + 1/3*q^2),
138
+ (q^12 - 2*q^11 + q^10, q^3 - q^2),
139
+ (q^14 - 2*q^13 + 2*q^11 - q^10, q^3 - q^2),
140
+ (q^12 - q^11 - q^10 + q^9, 1/2*q^4 - 1/2*q^3),
141
+ (q^12 - q^11, q^2),
142
+ (q^14 - 2*q^13 + q^12, q^2),
143
+ (q^18 - q^17 - q^16 + q^14 + q^13 - q^12, q^2),
144
+ (q^12 - q^9, 1/3*q^4 - 1/3*q^2),
145
+ (q^6 - q^3, 1/3*q^6 - 1/3*q^4)]
146
+
147
+ REFERENCES:
148
+
149
+ .. [Green55] Green, J. A. *The characters of the finite general linear groups*.
150
+ Trans. Amer. Math. Soc. 80 (1955), 402--447.
151
+ :doi:`10.1090/S0002-9947-1955-0072878-2`
152
+
153
+ .. [Morrison06] Morrison, Kent E.
154
+ *Integer sequences and matrices over finite fields*.
155
+ J. Integer Seq. 9 (2006), no. 2, Article 06.2.1, 28 pp.
156
+ https://cs.uwaterloo.ca/journals/JIS/VOL9/Morrison/morrison37.html
157
+
158
+ .. [PSS13] Prasad, A., Singla, P., and Spallone, S., *Similarity of matrices
159
+ over local rings of length two*. :arxiv:`1212.6157`
160
+
161
+ .. [PR22] Prasad, A., Ram, S., *Splitting subspaces and a finite field
162
+ interpretation of the Touchard-Riordan formula*. :arxiv:`2205.11076`
163
+
164
+ .. [R17] Ramaré, O., *Rationality of the zeta function of the subgroups of
165
+ abelian p-groups*. Publ. Math. Debrecen 90.1-2.
166
+ :doi:`10.5486/PMD.2017.7466`
167
+
168
+ AUTHOR:
169
+
170
+ - Amritanshu Prasad (2013-07-18): initial implementation
171
+
172
+ - Amritanshu Prasad (2013-09-09): added functions for similarity classes over
173
+ rings of length two
174
+
175
+ - Amritanshu Prasad (2022-07-31): added computation of similarity class type of
176
+ a given matrix and invariant subspace generating function
177
+ """
178
+ # ****************************************************************************
179
+ # Copyright (C) 2013 Amritanshu Prasad <amri@imsc.res.in>
180
+ #
181
+ # Distributed under the terms of the GNU General Public License (GPL)
182
+ #
183
+ # This code is distributed in the hope that it will be useful, but
184
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
185
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
186
+ # General Public License for more details.
187
+ #
188
+ # The full text of the GPL is available at:
189
+ #
190
+ # https://www.gnu.org/licenses/
191
+ # ****************************************************************************
192
+
193
+ from itertools import chain, product
194
+
195
+ from sage.arith.misc import divisors, factorial, moebius
196
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
197
+ from sage.combinat.combinat import CombinatorialElement
198
+ from sage.combinat.misc import IterableFunctionCall
199
+ from sage.combinat.partition import Partitions, Partition
200
+ from sage.misc.cachefunc import cached_in_parent_method, cached_function
201
+ from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
202
+ from sage.misc.misc_c import prod
203
+ from sage.rings.fraction_field import FractionField
204
+ from sage.rings.integer_ring import ZZ
205
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
206
+ from sage.rings.rational_field import QQ
207
+ from sage.structure.element import Element, Matrix
208
+ from sage.structure.parent import Parent
209
+ from sage.structure.unique_representation import UniqueRepresentation
210
+
211
+
212
+ @cached_function
213
+ def fq(n, q=None):
214
+ r"""
215
+ Return `(1-q^{-1}) (1-q^{-2}) \cdots (1-q^{-n})`.
216
+
217
+ INPUT:
218
+
219
+ - ``n`` -- nonnegative integer
220
+
221
+ - ``q`` -- integer or an indeterminate
222
+
223
+ OUTPUT: a rational function in ``q``
224
+
225
+ EXAMPLES::
226
+
227
+ sage: from sage.combinat.similarity_class_type import fq
228
+ sage: fq(0)
229
+ 1
230
+ sage: fq(3)
231
+ (q^6 - q^5 - q^4 + q^2 + q - 1)/q^6
232
+ """
233
+ if q is None:
234
+ q = ZZ['q'].gen()
235
+ return prod(1 - q**(-i - 1) for i in range(n))
236
+
237
+
238
+ @cached_function
239
+ def primitives(n, invertible=False, q=None):
240
+ """
241
+ Return the number of similarity classes of simple matrices
242
+ of order ``n`` with entries in a finite field of order ``q``.
243
+ This is the same as the number of irreducible polynomials
244
+ of degree `d`.
245
+
246
+ If ``invertible`` is ``True``, then only the number of
247
+ similarity classes of invertible matrices is returned.
248
+
249
+ .. NOTE::
250
+
251
+ All primitive classes are invertible unless ``n`` is `1`.
252
+
253
+ INPUT:
254
+
255
+ - ``n`` -- positive integer
256
+
257
+ - ``invertible`` -- boolean; if set, only number of nonzero classes is returned
258
+
259
+ - ``q`` -- integer or an indeterminate
260
+
261
+ OUTPUT: a rational function of the variable ``q``
262
+
263
+ EXAMPLES::
264
+
265
+ sage: from sage.combinat.similarity_class_type import primitives
266
+ sage: primitives(1)
267
+ q
268
+ sage: primitives(1, invertible = True)
269
+ q - 1
270
+ sage: primitives(4)
271
+ 1/4*q^4 - 1/4*q^2
272
+ sage: primitives(4, invertible = True)
273
+ 1/4*q^4 - 1/4*q^2
274
+ """
275
+ if q is None:
276
+ q = QQ['q'].gen()
277
+ p = sum(moebius(n // d) * q**d for d in divisors(n)) / n
278
+ if invertible and n == 1:
279
+ return p - 1
280
+ else:
281
+ return p
282
+
283
+
284
+ @cached_function
285
+ def order_of_general_linear_group(n, q=None):
286
+ r"""
287
+ Return the cardinality of the group of `n \times n` invertible matrices
288
+ with entries in a field of order ``q``.
289
+
290
+ INPUT:
291
+
292
+ - ``n`` -- nonnegative integer
293
+
294
+ - ``q`` -- integer or an indeterminate
295
+
296
+ EXAMPLES::
297
+
298
+ sage: from sage.combinat.similarity_class_type import order_of_general_linear_group
299
+ sage: order_of_general_linear_group(0)
300
+ 1
301
+ sage: order_of_general_linear_group(2)
302
+ q^4 - q^3 - q^2 + q
303
+ """
304
+ if q is None:
305
+ q = ZZ['q'].gen()
306
+ return prod([q**n - q**i for i in range(n)])
307
+
308
+
309
+ @cached_function
310
+ def centralizer_algebra_dim(la):
311
+ r"""
312
+ Return the dimension of the centralizer algebra in `M_n(\GF{q})`
313
+ of a nilpotent matrix whose Jordan blocks are given by ``la``.
314
+
315
+ EXAMPLES::
316
+
317
+ sage: from sage.combinat.similarity_class_type import centralizer_algebra_dim
318
+ sage: centralizer_algebra_dim(Partition([2, 1]))
319
+ 5
320
+
321
+ .. NOTE::
322
+
323
+ If it is a list, ``la`` is expected to be sorted in decreasing order.
324
+ """
325
+ return sum([(2 * i + 1) * la[i] for i in range(len(la))])
326
+
327
+
328
+ @cached_function
329
+ def centralizer_group_cardinality(la, q=None):
330
+ r"""
331
+ Return the cardinality of the centralizer group in `GL_n(\GF{q})`
332
+ of a nilpotent matrix whose Jordan blocks are given by ``la``.
333
+
334
+ INPUT:
335
+
336
+ - ``lambda`` -- a partition
337
+
338
+ - ``q`` -- an integer or an indeterminate
339
+
340
+ OUTPUT: a polynomial function of ``q``
341
+
342
+ EXAMPLES::
343
+
344
+ sage: from sage.combinat.similarity_class_type import centralizer_group_cardinality
345
+ sage: q = ZZ['q'].gen()
346
+ sage: centralizer_group_cardinality(Partition([2, 1]))
347
+ q^5 - 2*q^4 + q^3
348
+ """
349
+ if q is None:
350
+ q = ZZ['q'].gen()
351
+ return q**centralizer_algebra_dim(la)*prod([fq(m, q=q) for m in la.to_exp()])
352
+
353
+
354
+ def invariant_subspace_generating_function(la, q=None, t=None):
355
+ """
356
+ Return the invariant subspace generating function of a nilpotent matrix with
357
+ Jordan block sizes given by ``la``.
358
+
359
+ INPUT:
360
+
361
+ - ``la`` -- a partition
362
+ - ``q`` -- (optional) an integer or an inderminate
363
+ - ``t`` -- (optional) an indeterminate
364
+
365
+ OUTPUT: a polynomial in ``t`` whose coefficients are polynomials in ``q``
366
+
367
+ EXAMPLES::
368
+
369
+ sage: from sage.combinat.similarity_class_type import invariant_subspace_generating_function
370
+ sage: invariant_subspace_generating_function([2,2])
371
+ t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1
372
+ """
373
+ if q is None:
374
+ q = PolynomialRing(QQ,'q').gen()
375
+ S = q.parent()
376
+ if t is None:
377
+ t = PolynomialRing(S,'t').gen()
378
+ R = t.parent()
379
+ Rff = R.fraction_field()
380
+ if not la:
381
+ return Rff(1)
382
+ u = invariant_subspace_generating_function(la[1:], q=q, t=t)
383
+ return R((t**(la[0]+1) * q**(sum(la[1:])) * u.substitute(t=t/q) - u.substitute(t=t*q)) / (t - 1))
384
+
385
+
386
+ class PrimarySimilarityClassType(Element,
387
+ metaclass=InheritComparisonClasscallMetaclass):
388
+ r"""
389
+ A primary similarity class type is a pair consisting of a partition and a positive
390
+ integer.
391
+
392
+ For a partition `\lambda` and a positive integer `d`, the primary similarity
393
+ class type `(d, \lambda)` represents similarity classes of square matrices
394
+ of order `|\lambda| \cdot d` with entries in a finite field of order `q`
395
+ which correspond to the `\GF{q[t]}`-module
396
+
397
+ .. MATH::
398
+
399
+ \frac{\GF{q[t]}}{p(t)^{\lambda_1} } \oplus
400
+ \frac{\GF{q[t]}}{p(t)^{\lambda_2}} \oplus \dotsb
401
+
402
+ for some irreducible polynomial `p(t)` of degree `d`.
403
+ """
404
+ @staticmethod
405
+ def __classcall_private__(cls, deg, par):
406
+ r"""
407
+ Create a primary similarity class type.
408
+
409
+ EXAMPLES::
410
+
411
+ sage: PrimarySimilarityClassType(2, [3, 2, 1])
412
+ [2, [3, 2, 1]]
413
+
414
+ The parent class is the class of primary similarity class types of order
415
+ `d |\lambda|`::
416
+
417
+ sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
418
+ sage: PT.parent().size()
419
+ 12
420
+ """
421
+ par = Partition(par)
422
+ P = PrimarySimilarityClassTypes(par.size()*deg)
423
+ return P(deg, par)
424
+
425
+ def __init__(self, parent, deg, par):
426
+ """
427
+ Initialize ``self``.
428
+
429
+ EXAMPLES::
430
+
431
+ sage: elt = PrimarySimilarityClassType(2, [3, 2, 1])
432
+ sage: TestSuite(elt).run()
433
+ """
434
+ self._deg = deg
435
+ self._par = par
436
+ Element.__init__(self, parent)
437
+
438
+ def __repr__(self):
439
+ """
440
+ Return string representation of ``self``.
441
+
442
+ EXAMPLES::
443
+
444
+ sage: PrimarySimilarityClassType(2, [3, 2, 1])
445
+ [2, [3, 2, 1]]
446
+ """
447
+ return "%s" % ([self._deg, self._par],)
448
+
449
+ def __hash__(self):
450
+ r"""
451
+ TESTS::
452
+
453
+ sage: PT1 = PrimarySimilarityClassType(2, [3, 2, 1])
454
+ sage: PT2 = PrimarySimilarityClassType(3, [3, 2, 1])
455
+ sage: PT3 = PrimarySimilarityClassType(2, [4, 2, 1])
456
+ sage: hash(PT1) == hash(PrimarySimilarityClassType(2, [3, 2, 1]))
457
+ True
458
+ sage: abs(hash(PT1) - hash(PT2)) == 1
459
+ True
460
+ sage: hash(PT1) == hash(PT3)
461
+ False
462
+ sage: hash(PT2) == hash(PT3)
463
+ False
464
+ """
465
+ return hash(self._deg) ^ hash(tuple(self._par))
466
+
467
+ def __eq__(self, other):
468
+ """
469
+ Check equality.
470
+
471
+ EXAMPLES::
472
+
473
+ sage: PT1 = PrimarySimilarityClassType(2, [3, 2, 1])
474
+ sage: PT2 = PrimarySimilarityClassType(2, Partition([3, 2, 1]))
475
+ sage: PT1 == PT2
476
+ True
477
+ sage: PT3 = PrimarySimilarityClassType(3, [3, 2, 1])
478
+ sage: PT1 == PT3
479
+ False
480
+ sage: PT4 = PrimarySimilarityClassType(2, [3, 2, 1, 0])
481
+ sage: PT1 == PT4
482
+ True
483
+ sage: PT5 = PrimarySimilarityClassType(2, [4, 2, 1])
484
+ sage: PT1 == PT5
485
+ False
486
+ """
487
+ return isinstance(other, PrimarySimilarityClassType) and \
488
+ self.degree() == other.degree() and \
489
+ self.partition() == other.partition()
490
+
491
+ def __ne__(self, other):
492
+ r"""
493
+ TESTS::
494
+
495
+ sage: PT1 = PrimarySimilarityClassType(2, [3, 2, 1])
496
+ sage: PT2 = PrimarySimilarityClassType(2, Partition([3, 2, 1]))
497
+ sage: PT1 != PT2
498
+ False
499
+ sage: PT3 = PrimarySimilarityClassType(3, [3, 2, 1])
500
+ sage: PT1 != PT3
501
+ True
502
+ """
503
+ return not isinstance(other, PrimarySimilarityClassType) or \
504
+ self.degree() != other.degree() or \
505
+ self.partition() != other.partition()
506
+
507
+ def size(self):
508
+ """
509
+ Return the size of ``self``.
510
+
511
+ EXAMPLES::
512
+
513
+ sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
514
+ sage: PT.size()
515
+ 12
516
+ """
517
+ return self.parent().size()
518
+
519
+ def degree(self):
520
+ """
521
+ Return degree of ``self``.
522
+
523
+ EXAMPLES::
524
+
525
+ sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
526
+ sage: PT.degree()
527
+ 2
528
+ """
529
+ return self._deg
530
+
531
+ def partition(self):
532
+ """
533
+ Return partition corresponding to ``self``.
534
+
535
+ EXAMPLES::
536
+
537
+ sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
538
+ sage: PT.partition()
539
+ [3, 2, 1]
540
+ """
541
+ return Partition(self._par)
542
+
543
+ def centralizer_algebra_dim(self):
544
+ r"""
545
+ Return the dimension of the algebra of matrices which commute with a
546
+ matrix of type ``self``.
547
+
548
+ For a partition `(d, \lambda)` this dimension is given by
549
+ `d(\lambda_1 + 3\lambda_2 + 5\lambda_3 + \cdots)`.
550
+
551
+ EXAMPLES::
552
+
553
+ sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
554
+ sage: PT.centralizer_algebra_dim()
555
+ 28
556
+ """
557
+ return self.degree()*centralizer_algebra_dim(self.partition())
558
+
559
+ @cached_in_parent_method
560
+ def statistic(self, func, q=None):
561
+ r"""
562
+ Return `n_{\lambda}(q^d)` where `n_{\lambda}` is the value returned by
563
+ ``func`` upon input `\lambda`, if ``self`` is `(d, \lambda)`.
564
+
565
+ EXAMPLES::
566
+
567
+ sage: PT = PrimarySimilarityClassType(2, [3, 1])
568
+ sage: q = ZZ['q'].gen()
569
+ sage: PT.statistic(lambda la:q**la.size(), q = q)
570
+ q^8
571
+ """
572
+ if q is None:
573
+ q = ZZ['q'].gen()
574
+ return q.parent()(func(self.partition()).substitute(q=q**self.degree()))
575
+
576
+ @cached_in_parent_method
577
+ def centralizer_group_card(self, q=None):
578
+ """
579
+ Return the cardinality of the centralizer group of a matrix of type
580
+ ``self`` in a field of order ``q``.
581
+
582
+ INPUT:
583
+
584
+ - ``q`` -- integer or an indeterminate
585
+
586
+ EXAMPLES::
587
+
588
+ sage: PT = PrimarySimilarityClassType(1, [])
589
+ sage: PT.centralizer_group_card()
590
+ 1
591
+ sage: PT = PrimarySimilarityClassType(2, [1, 1])
592
+ sage: PT.centralizer_group_card()
593
+ q^8 - q^6 - q^4 + q^2
594
+ """
595
+ if q is None:
596
+ q = FractionField(ZZ['q']).gen()
597
+ return self.statistic(centralizer_group_cardinality, q=q)
598
+
599
+ def invariant_subspace_generating_function(self, q=None, t=None):
600
+ """
601
+ Return the invariant subspace generating function of ``self``.
602
+
603
+ INPUT:
604
+
605
+ - ``q`` -- (optional) an integer or an inderminate
606
+ - ``t`` -- (optional) an indeterminate
607
+
608
+ EXAMPLES::
609
+
610
+ sage: PrimarySimilarityClassType(1, [2, 2]).invariant_subspace_generating_function()
611
+ t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1
612
+ """
613
+ if q is None:
614
+ q = PolynomialRing(QQ, 'q').gen()
615
+ S = q.parent()
616
+ if t is None:
617
+ t = PolynomialRing(S, 't').gen()
618
+ return invariant_subspace_generating_function(self.partition()).substitute(q=q**self.degree(), t=t**self.degree())
619
+
620
+
621
+ class PrimarySimilarityClassTypes(UniqueRepresentation, Parent):
622
+ r"""
623
+ All primary similarity class types of size ``n`` whose degree is greater
624
+ than that of ``min`` or whose degree is that of ``min`` and whose partition
625
+ is less than of ``min`` in lexicographic order.
626
+
627
+ A primary similarity class type of size `n` is a pair `(\lambda, d)`
628
+ consisting of a partition `\lambda` and a positive integer `d` such that
629
+ `|\lambda| d = n`.
630
+
631
+ INPUT:
632
+
633
+ - ``n`` -- positive integer
634
+ - ``min`` -- a primary matrix type of size ``n``
635
+
636
+ EXAMPLES:
637
+
638
+ If ``min`` is not specified, then the class of all primary similarity class
639
+ types of size ``n`` is created::
640
+
641
+ sage: PTC = PrimarySimilarityClassTypes(2)
642
+ sage: for PT in PTC:
643
+ ....: print(PT)
644
+ [1, [2]]
645
+ [1, [1, 1]]
646
+ [2, [1]]
647
+
648
+ If ``min`` is specified, then the class consists of only those primary
649
+ similarity class types whose degree is greater than that of ``min`` or whose
650
+ degree is that of ``min`` and whose partition is less than of ``min`` in
651
+ lexicographic order::
652
+
653
+ sage: PTC = PrimarySimilarityClassTypes(2, min = PrimarySimilarityClassType(1, [1, 1]))
654
+ sage: for PT in PTC:
655
+ ....: print(PT)
656
+ [1, [1, 1]]
657
+ [2, [1]]
658
+ """
659
+ @staticmethod
660
+ def __classcall_private__(cls, n, min=None):
661
+ r"""
662
+ Create the class of vector partitions of ``vec`` where all parts
663
+ are greater than or equal to the vector ``min``.
664
+
665
+ EXAMPLES::
666
+
667
+ sage: PTC1 = PrimarySimilarityClassTypes(2)
668
+ sage: PTC2 = PrimarySimilarityClassTypes(2, min = PrimarySimilarityClassType(1, [2]))
669
+ sage: PTC1 is PTC2
670
+ True
671
+ """
672
+ if min is None:
673
+ min = (ZZ.one(), Partition([n]))
674
+ elif isinstance(min, PrimarySimilarityClassType):
675
+ min = (min.degree(), min.partition())
676
+ elif len(min) == 2:
677
+ min = (min[0], Partition(min[1]))
678
+ else:
679
+ raise ValueError("min must be a PrimarySimilarityClassType")
680
+ return super().__classcall__(cls, n, min)
681
+
682
+ def __init__(self, n, min):
683
+ r"""
684
+ Initialize ``self``.
685
+
686
+ TESTS::
687
+
688
+ sage: PTC = PrimarySimilarityClassTypes(2)
689
+ sage: TestSuite(PTC).run()
690
+ """
691
+ Parent.__init__(self, category=FiniteEnumeratedSets())
692
+ self._n = n
693
+ self._min = min
694
+
695
+ def _element_constructor_(self, deg, par):
696
+ """
697
+ Construct an element of ``self``.
698
+
699
+ INPUT:
700
+
701
+ - ``deg`` -- positive integer
702
+
703
+ - ``par`` -- a partition
704
+
705
+ EXAMPLES::
706
+
707
+ sage: PTC = PrimarySimilarityClassTypes(2)
708
+ sage: elt = PTC(1, [1, 1]); elt
709
+ [1, [1, 1]]
710
+ sage: elt.parent() is PTC
711
+ True
712
+ """
713
+ return self.element_class(self, deg, par)
714
+
715
+ Element = PrimarySimilarityClassType
716
+
717
+ def __iter__(self):
718
+ r"""
719
+ Iterate over ``self``.
720
+
721
+ EXAMPLES::
722
+
723
+ sage: PTC = PrimarySimilarityClassTypes(2)
724
+ sage: PTC.cardinality()
725
+ 3
726
+ """
727
+ n = self._n
728
+ if self._min[0].divides(n):
729
+ for par in Partitions(n // self._min[0], starting=self._min[1]):
730
+ yield self.element_class(self, self._min[0], par)
731
+ for d in (d for d in divisors(n) if d > self._min[0]):
732
+ for par in Partitions(n // d):
733
+ yield self.element_class(self, d, par)
734
+
735
+ def size(self):
736
+ r"""
737
+ Return size of elements of ``self``.
738
+
739
+ The size of a primary similarity class type `(d, \lambda)` is
740
+ `d |\lambda|`.
741
+
742
+ EXAMPLES::
743
+
744
+ sage: PTC = PrimarySimilarityClassTypes(2)
745
+ sage: PTC.size()
746
+ 2
747
+ """
748
+ return self._n
749
+
750
+ ###############################################################################
751
+
752
+ ###############################################################################
753
+
754
+
755
+ class SimilarityClassType(CombinatorialElement):
756
+ r"""
757
+ A similarity class type.
758
+
759
+ A matrix type is a multiset of primary similarity class types.
760
+
761
+ INPUT:
762
+
763
+ - ``tau`` -- list of primary similarity class types or a square matrix
764
+ over a finite field
765
+
766
+ EXAMPLES::
767
+
768
+ sage: tau1 = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]]); tau1
769
+ [[2, [2, 1]], [3, [3, 2, 1]]]
770
+
771
+ sage: SimilarityClassType(Matrix(GF(2), [[1,1],[0,1]]))
772
+ [[1, [2]]]
773
+ """
774
+ @staticmethod
775
+ def __classcall_private__(cls, tau):
776
+ """
777
+ Create a similarity class type.
778
+
779
+ EXAMPLES:
780
+
781
+ The input can be a list of lists or a list of primary similarity class
782
+ types, and the order in which this list is given does not matter::
783
+
784
+ sage: tau1 = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]]); tau1
785
+ [[2, [2, 1]], [3, [3, 2, 1]]]
786
+ sage: types = [PrimarySimilarityClassType(2, [2, 1]), PrimarySimilarityClassType(3, [3, 2, 1])]
787
+ sage: tau2 = SimilarityClassType(types)
788
+ sage: tau1 == tau2
789
+ True
790
+
791
+ The input can also be a matrix with entries in a finite field::
792
+
793
+ sage: SimilarityClassType(Matrix(GF(2), [[1,1],[0,1]]))
794
+ [[1, [2]]]
795
+
796
+ The parent class is the class of similarity class types of the sum of
797
+ the sizes of the primary matrix types in ``tau``::
798
+
799
+ sage: tau = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]])
800
+ sage: tau.parent().size()
801
+ 24
802
+ """
803
+ if isinstance(tau, Matrix):
804
+ n = tau.nrows()
805
+ F = tau.base_ring()
806
+ R = PolynomialRing(F, 't')
807
+ t = R.gen()
808
+ S = (t - tau).smith_form(transformation=False)
809
+ L = [S[i,i] for i in range(n-1, -1, -1) if S[i,i]]
810
+ f = [dict(list(p.factor())) for p in L]
811
+ d = {p: Partition([h[p] for h in f if p in h]) for p in f[0]}
812
+ return SimilarityClassType([[p.degree(), d[p]] for p in d])
813
+ else:
814
+ ret = []
815
+ for l in tau:
816
+ if isinstance(l, PrimarySimilarityClassType):
817
+ ret.append(l)
818
+ else:
819
+ ret.append(PrimarySimilarityClassType(*l))
820
+ n = sum([PT.size() for PT in ret])
821
+ T = SimilarityClassTypes(n)
822
+ return T(tau)
823
+
824
+ def __init__(self, parent, tau):
825
+ """
826
+ Initialize ``self``.
827
+
828
+ EXAMPLES::
829
+
830
+ sage: elt = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]])
831
+ sage: TestSuite(elt).run()
832
+ """
833
+ tau = sorted(tau, key=lambda PT: (PT.degree(), PT.partition()))
834
+ CombinatorialElement.__init__(self, parent, tau)
835
+
836
+ def size(self):
837
+ """
838
+ Return the sum of the sizes of the primary parts of ``self``.
839
+
840
+ EXAMPLES::
841
+
842
+ sage: tau = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]])
843
+ sage: tau.size()
844
+ 24
845
+ """
846
+ return self.parent().size()
847
+
848
+ def centralizer_algebra_dim(self):
849
+ """
850
+ Return the dimension of the algebra of matrices which commute with a
851
+ matrix of type ``self``.
852
+
853
+ EXAMPLES::
854
+
855
+ sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
856
+ sage: tau.centralizer_algebra_dim()
857
+ 2
858
+ """
859
+ return sum([PT.centralizer_algebra_dim() for PT in self])
860
+
861
+ def centralizer_group_card(self, q=None):
862
+ r"""
863
+ Return the cardinality of the group of matrices in `GL_n(\GF{q})`
864
+ which commute with a matrix of type ``self``.
865
+
866
+ INPUT:
867
+
868
+ - ``q`` -- integer or an indeterminate
869
+
870
+ EXAMPLES::
871
+
872
+ sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
873
+ sage: tau.centralizer_group_card()
874
+ q^2 - 2*q + 1
875
+ """
876
+ return prod([PT.centralizer_group_card(q=q) for PT in self])
877
+
878
+ def as_partition_dictionary(self):
879
+ r"""
880
+ Return a dictionary whose keys are the partitions of types occurring in
881
+ ``self`` and the value at the key `\lambda` is the partition formed by
882
+ sorting the degrees of primary types with partition `\lambda`.
883
+
884
+ EXAMPLES::
885
+
886
+ sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
887
+ sage: tau.as_partition_dictionary()
888
+ {[1]: [1, 1]}
889
+ """
890
+ D = {}
891
+ for PT in self:
892
+ if PT.partition() in D:
893
+ D[PT.partition()] = Partition(sorted(D[PT.partition()] + [PT.degree()]))
894
+ else:
895
+ D[PT.partition()] = Partition([PT.degree()])
896
+ return D
897
+
898
+ def number_of_classes(self, invertible=False, q=None):
899
+ """
900
+ Return the number of similarity classes of matrices of type ``self``.
901
+
902
+ INPUT:
903
+
904
+ - ``invertible`` -- boolean; return number of invertible classes if set
905
+ to ``True``
906
+
907
+ - ``q`` -- integer or an indeterminate
908
+
909
+ EXAMPLES::
910
+
911
+ sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
912
+ sage: tau.number_of_classes()
913
+ 1/2*q^2 - 1/2*q
914
+ """
915
+ if q is None:
916
+ q = ZZ['q'].gen()
917
+ if self.size() == 0:
918
+ return q.parent().one()
919
+ list_of_degrees = [PT.degree() for PT in self]
920
+ maximum_degree = max(list_of_degrees)
921
+ numerator = prod([prod([primitives(d+1, invertible=invertible, q=q)-i for i in range(list_of_degrees.count(d+1))]) for d in range(maximum_degree)])
922
+ tau_list = list(self)
923
+ D = {i: tau_list.count(i) for i in tau_list}
924
+ denominator = prod(factorial(D[primary_type]) for primary_type in D)
925
+ return numerator / denominator
926
+
927
+ def is_semisimple(self) -> bool:
928
+ """
929
+ Return ``True`` if every primary similarity class type in ``self`` has
930
+ all parts equal to ``1``.
931
+
932
+ EXAMPLES::
933
+
934
+ sage: tau = SimilarityClassType([[2, [1, 1]], [1, [1]]])
935
+ sage: tau.is_semisimple()
936
+ True
937
+ sage: tau = SimilarityClassType([[2, [1, 1]], [1, [2]]])
938
+ sage: tau.is_semisimple()
939
+ False
940
+ """
941
+ return all(PT.partition().get_part(0) == 1 for PT in self)
942
+
943
+ def is_regular(self) -> bool:
944
+ """
945
+ Return ``True`` if every primary type in ``self`` has partition with one
946
+ part.
947
+
948
+ EXAMPLES::
949
+
950
+ sage: tau = SimilarityClassType([[2, [1]], [1, [3]]])
951
+ sage: tau.is_regular()
952
+ True
953
+ sage: tau = SimilarityClassType([[2, [1, 1]], [1, [3]]])
954
+ sage: tau.is_regular()
955
+ False
956
+ """
957
+ return all(len(PT.partition()) == 1 for PT in self)
958
+
959
+ def rcf(self):
960
+ """
961
+ Return the partition corresponding to the rational canonical form of a
962
+ matrix of type ``self``.
963
+
964
+ EXAMPLES::
965
+
966
+ sage: tau = SimilarityClassType([[2, [1, 1, 1]], [1, [3, 2]]])
967
+ sage: tau.rcf()
968
+ [5, 4, 2]
969
+ """
970
+ out_list = list()
971
+ i = 0
972
+ while True:
973
+ new_part = sum([PT.partition().get_part(i)*PT.degree() for PT in self])
974
+ if new_part:
975
+ out_list.append(new_part)
976
+ else:
977
+ return Partition(out_list)
978
+ i = i+1
979
+
980
+ def class_card(self, q=None):
981
+ """
982
+ Return the number of matrices in each similarity class of type ``self``.
983
+
984
+ INPUT:
985
+
986
+ - ``q`` -- integer or an indeterminate
987
+
988
+ EXAMPLES::
989
+
990
+ sage: tau = SimilarityClassType([[1, [1, 1, 1, 1]]])
991
+ sage: tau.class_card()
992
+ 1
993
+ sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
994
+ sage: tau.class_card()
995
+ q^2 + q
996
+ """
997
+ if q is None:
998
+ q = ZZ['q'].gen()
999
+ return order_of_general_linear_group(self.size(), q=q) / self.centralizer_group_card(q=q)
1000
+
1001
+ def number_of_matrices(self, invertible=False, q=None):
1002
+ """
1003
+ Return the number of matrices of type ``self``.
1004
+
1005
+ INPUT:
1006
+
1007
+ - ``invertible`` -- a boolean; return the number of invertible
1008
+ matrices if set
1009
+
1010
+ EXAMPLES::
1011
+
1012
+ sage: tau = SimilarityClassType([[1, [1]]])
1013
+ sage: tau.number_of_matrices()
1014
+ q
1015
+ sage: tau.number_of_matrices(invertible = True)
1016
+ q - 1
1017
+ sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
1018
+ sage: tau.number_of_matrices()
1019
+ 1/2*q^4 - 1/2*q^2
1020
+ """
1021
+ if q is None:
1022
+ q = ZZ['q'].gen()
1023
+ return self.class_card(q=q)*self.number_of_classes(invertible=invertible, q=q)
1024
+
1025
+ def statistic(self, func, q=None):
1026
+ r"""
1027
+ Return.
1028
+
1029
+ .. MATH::
1030
+
1031
+ \prod_{(d, \lambda)\in \tau} n_{\lambda}(q^d)
1032
+
1033
+ where `n_{\lambda}(q)` is the value returned by ``func`` on the input
1034
+ `\lambda`.
1035
+
1036
+ INPUT:
1037
+
1038
+ - ``func`` -- a function that takes a partition to a polynomial in ``q``
1039
+
1040
+ - ``q`` -- integer or an indeterminate
1041
+
1042
+ EXAMPLES::
1043
+
1044
+ sage: tau = SimilarityClassType([[1, [1]], [1, [2, 1]], [2, [1, 1]]])
1045
+ sage: from sage.combinat.similarity_class_type import fq
1046
+ sage: tau.statistic(lambda la: prod([fq(m) for m in la.to_exp()]))
1047
+ (q^9 - 3*q^8 + 2*q^7 + 2*q^6 - 4*q^5 + 4*q^4 - 2*q^3 - 2*q^2 + 3*q - 1)/q^9
1048
+ sage: q = ZZ['q'].gen()
1049
+ sage: tau.statistic(lambda la: q**la.size(), q = q)
1050
+ q^8
1051
+ """
1052
+ if q is None:
1053
+ q = FractionField(ZZ['q']).gen()
1054
+ return prod([PT.statistic(func, q=q) for PT in self])
1055
+
1056
+ def invariant_subspace_generating_function(self, q=None, t=None):
1057
+ r"""
1058
+ Return the invariant subspace generating function of ``self``.
1059
+
1060
+ The invariant subspace generating function is the function is the
1061
+ polynomial
1062
+
1063
+ .. MATH::
1064
+
1065
+ \sum_{j\geq 0} a_j(q) t^j,
1066
+
1067
+ where `a_j(q)` denotes the number of `j`-dimensional invariant subspaces
1068
+ of dimensiona `j` for any matrix with the similarity class type ``self``
1069
+ with entries in a field of order `q`.
1070
+
1071
+ EXAMPLES::
1072
+
1073
+ sage: SimilarityClassType([[1, [2, 2]]]).invariant_subspace_generating_function()
1074
+ t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1
1075
+ sage: A = Matrix(GF(2),[(0, 1, 0, 0), (0, 1, 1, 1), (1, 0, 1, 0), (1, 1, 0, 0)])
1076
+ sage: SimilarityClassType(A).invariant_subspace_generating_function()
1077
+ t^4 + 1
1078
+ """
1079
+ if q is None:
1080
+ q = PolynomialRing(QQ, 'q').gen()
1081
+ S = q.parent()
1082
+ if t is None:
1083
+ t = PolynomialRing(S, 't').gen()
1084
+ return prod(p.invariant_subspace_generating_function(q=q, t=t) for p in self)
1085
+
1086
+
1087
+ class SimilarityClassTypes(UniqueRepresentation, Parent):
1088
+ r"""
1089
+ Class of all similarity class types of size ``n`` with all primary matrix
1090
+ types greater than or equal to the primary matrix type ``min``.
1091
+
1092
+ A similarity class type is a multiset of primary matrix types.
1093
+
1094
+ INPUT:
1095
+
1096
+ - ``n`` -- nonnegative integer
1097
+ - ``min`` -- a primary similarity class type
1098
+
1099
+ EXAMPLES:
1100
+
1101
+ If ``min`` is not specified, then the class of all matrix types of size
1102
+ ``n`` is constructed::
1103
+
1104
+ sage: M = SimilarityClassTypes(2)
1105
+ sage: for tau in M:
1106
+ ....: print(tau)
1107
+ [[1, [1]], [1, [1]]]
1108
+ [[1, [2]]]
1109
+ [[1, [1, 1]]]
1110
+ [[2, [1]]]
1111
+
1112
+ If ``min`` is specified, then the class consists of only those similarity
1113
+ class types which are multisets of primary matrix types which either have
1114
+ size greater than that of ``min``, or if they have size equal to that of
1115
+ ``min``, then they occur after ``min`` in the iterator for
1116
+ ``PrimarySimilarityClassTypes(n)``, where ``n`` is the size of ``min``::
1117
+
1118
+ sage: M = SimilarityClassTypes(2, min = [1, [1, 1]])
1119
+ sage: for tau in M:
1120
+ ....: print(tau)
1121
+ [[1, [1, 1]]]
1122
+ [[2, [1]]]
1123
+ """
1124
+ @staticmethod
1125
+ def __classcall_private__(cls, n, min=None):
1126
+ r"""
1127
+ Create the class of similarity class types of size ``n`` consisting of
1128
+ primary similarity class types greater than or equal to ``min``.
1129
+
1130
+ EXAMPLES::
1131
+
1132
+ sage: M1 = SimilarityClassTypes(2, min = [1, [1]])
1133
+ sage: M2 = SimilarityClassTypes(2)
1134
+ sage: M1 is M2
1135
+ True
1136
+ """
1137
+ if min is None:
1138
+ min = PrimarySimilarityClassType(1, Partition([1]))
1139
+ if isinstance(min, list):
1140
+ min = PrimarySimilarityClassType(min[0], min[1])
1141
+ if not isinstance(min, PrimarySimilarityClassType):
1142
+ raise ValueError("min must be a PrimarySimilarityClassType")
1143
+ return super().__classcall__(cls, n, min)
1144
+
1145
+ def __init__(self, n, min):
1146
+ r"""
1147
+ Initialize ``self``.
1148
+
1149
+ TESTS::
1150
+
1151
+ sage: M = SimilarityClassTypes(2)
1152
+ sage: TestSuite(M).run()
1153
+ """
1154
+ Parent.__init__(self, category=FiniteEnumeratedSets())
1155
+ self._n = n
1156
+ self._min = min
1157
+
1158
+ def _element_constructor_(self, tau):
1159
+ """
1160
+ Construct an element of ``self``.
1161
+
1162
+ INPUT:
1163
+
1164
+ - ``tau`` -- list of primary similarity class types
1165
+
1166
+ EXAMPLES::
1167
+
1168
+ sage: M = SimilarityClassTypes(2)
1169
+ sage: elt = M([[1, [1]], [1, [1]]]); elt
1170
+ [[1, [1]], [1, [1]]]
1171
+ sage: elt.parent() is M
1172
+ True
1173
+ """
1174
+ ret = []
1175
+ for l in tau:
1176
+ if isinstance(l, PrimarySimilarityClassType):
1177
+ ret.append(l)
1178
+ else:
1179
+ ret.append(PrimarySimilarityClassType(*l))
1180
+ return self.element_class(self, ret)
1181
+
1182
+ Element = SimilarityClassType
1183
+
1184
+ def __iter__(self):
1185
+ r"""
1186
+ Iterator for vector partitions.
1187
+
1188
+ EXAMPLES::
1189
+
1190
+ sage: SimilarityClassTypes(3).cardinality()
1191
+ 8
1192
+
1193
+ A good test of the iterator is to see that all elements of
1194
+ `M_n(\GF{q})` or `GL_n(\GF{q})` are enumerated through
1195
+ types::
1196
+
1197
+ sage: from sage.combinat.similarity_class_type import order_of_general_linear_group
1198
+ sage: q = QQ['q'].gen()
1199
+ sage: def test(n):
1200
+ ....: M = SimilarityClassTypes(n)
1201
+ ....: return M.sum(lambda la:1) == q**(n**2) and M.sum(lambda la:1, invertible = True)== order_of_general_linear_group(n)
1202
+ sage: all(test(n) for n in range(5))
1203
+ True
1204
+ sage: all(test(n) for n in range(5, 10)) # long time
1205
+ True
1206
+ """
1207
+ n = self._n
1208
+ min = self._min
1209
+ if n == 0:
1210
+ yield self.element_class(self, []) # dimension zero has only empty type
1211
+ if min.size() > n:
1212
+ return
1213
+ else:
1214
+ # choose first part
1215
+ for PT in chain(PrimarySimilarityClassTypes(min.size(), min=min), *[PrimarySimilarityClassTypes(k) for k in range(min.size() + 1, n + 1)]):
1216
+ if PT.size() == n:
1217
+ yield self.element_class(self, [PT])
1218
+ else: # recursively find all possibilities for what remains of n
1219
+ for smaller_type in SimilarityClassTypes(n - PT.size(), min=PT):
1220
+ yield self.element_class(self, [PT] + list(smaller_type))
1221
+
1222
+ def size(self):
1223
+ """
1224
+ Return size of ``self``.
1225
+
1226
+ EXAMPLES::
1227
+
1228
+ sage: tau = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]])
1229
+ sage: tau.parent().size()
1230
+ 24
1231
+ """
1232
+ return self._n
1233
+
1234
+ def sum(self, stat, sumover='matrices', invertible=False, q=None):
1235
+ r"""
1236
+ Return the sum of a local statistic over all types.
1237
+
1238
+ Given a set of functions `n_{\lambda}(q)` (these could be polynomials or
1239
+ rational functions in `q`, for each similarity class type `\tau` define
1240
+
1241
+ .. MATH::
1242
+
1243
+ n_\tau(q) = \prod_{(d,\lambda)\in \tau} n_{\lambda}(q^d).
1244
+
1245
+ This function returns
1246
+
1247
+ .. MATH::
1248
+
1249
+ \sum n_{\tau(g)}(q)
1250
+
1251
+ where `\tau(g)` denotes the type of a matrix `g`, and the sum is over
1252
+ all `n \times n` matrices if ``sumover`` is set to ``'matrices'``, is
1253
+ over all `n \times n` similarity classes if ``sumover`` is set to
1254
+ ``'classes'``, and over all `n \times n` types if ``sumover`` is set
1255
+ to ``'types'``. If ``invertible`` is set to ``True``, then the sum is
1256
+ only over invertible matrices or classes.
1257
+
1258
+ INPUT:
1259
+
1260
+ - ``stat`` -- a function which takes partitions and returns a function
1261
+ of ``q``
1262
+ - ``sumover`` -- can be one of the following:
1263
+
1264
+ * ``'matrices'``
1265
+ * ``'classes'``
1266
+ * ``'types'``
1267
+
1268
+ - ``q`` -- integer or an indeterminate
1269
+
1270
+ OUTPUT: a function of ``q``
1271
+
1272
+ EXAMPLES::
1273
+
1274
+ sage: M = SimilarityClassTypes(2)
1275
+ sage: M.sum(lambda la:1)
1276
+ q^4
1277
+ sage: M.sum(lambda la:1, invertible = True)
1278
+ q^4 - q^3 - q^2 + q
1279
+ sage: M.sum(lambda la:1, sumover = "classes")
1280
+ q^2 + q
1281
+ sage: M.sum(lambda la:1, sumover = "classes", invertible = True)
1282
+ q^2 - 1
1283
+
1284
+ Burside's lemma can be used to calculate the number of similarity
1285
+ classes of matrices::
1286
+
1287
+ sage: from sage.combinat.similarity_class_type import centralizer_algebra_dim, order_of_general_linear_group
1288
+ sage: q = ZZ['q'].gen()
1289
+ sage: M.sum(lambda la:q**centralizer_algebra_dim(la), invertible = True)/order_of_general_linear_group(2)
1290
+ q^2 + q
1291
+ """
1292
+ if sumover == "matrices":
1293
+ return sum([tau.statistic(stat, q=q)*tau.number_of_matrices(invertible=invertible, q=q) for tau in self])
1294
+ elif sumover == "classes":
1295
+ return sum([tau.statistic(stat, q=q)*tau.number_of_classes(invertible=invertible, q=q) for tau in self])
1296
+ elif sumover == "types":
1297
+ return sum([tau.statistic(stat, invertible=invertible, q=q) for tau in self])
1298
+ else:
1299
+ raise ValueError("invalid parameter %s" % (sumover))
1300
+
1301
+ ################################################################################
1302
+ # Similarity over rings of length two #
1303
+ ################################################################################
1304
+
1305
+
1306
+ def dictionary_from_generator(gen):
1307
+ r"""
1308
+ Given a generator for a list of pairs `(c,f)`, construct a dictionary whose
1309
+ keys are the distinct values for `c` and whose value at `c` is the sum of
1310
+ `f` over all pairs of the form `(c',f)` such that `c=c'`.
1311
+
1312
+ EXAMPLES::
1313
+
1314
+ sage: from sage.combinat.similarity_class_type import dictionary_from_generator
1315
+ sage: dictionary_from_generator(((x // 2, x) for x in range(10)))
1316
+ {0: 1, 1: 5, 2: 9, 3: 13, 4: 17}
1317
+
1318
+ It also works with lists::
1319
+
1320
+ sage: dictionary_from_generator([(x // 2, x) for x in range(10)])
1321
+ {0: 1, 1: 5, 2: 9, 3: 13, 4: 17}
1322
+
1323
+ .. NOTE::
1324
+
1325
+ Since the generator is first converted to a list, memory usage could be
1326
+ high.
1327
+ """
1328
+ L = list(gen)
1329
+ setofkeys = set(item[0] for item in L)
1330
+ return {key: sum(pair[1] for pair in L if pair[0] == key)
1331
+ for key in setofkeys}
1332
+
1333
+
1334
+ def matrix_similarity_classes(n, q=None, invertible=False):
1335
+ r"""
1336
+ Return the number of matrix similarity classes over a finite field of order
1337
+ ``q``.
1338
+
1339
+ TESTS::
1340
+
1341
+ sage: from sage.combinat.similarity_class_type import matrix_similarity_classes
1342
+ sage: matrix_similarity_classes(2)
1343
+ q^2 + q
1344
+ sage: matrix_similarity_classes(2, invertible = True)
1345
+ q^2 - 1
1346
+ sage: matrix_similarity_classes(2, invertible = True, q = 4)
1347
+ 15
1348
+ """
1349
+ if q is None:
1350
+ q = ZZ['q'].gen()
1351
+ basering = q.parent()
1352
+ if n == 0:
1353
+ return basering.one()
1354
+ if invertible:
1355
+ tilde = 1 - ~q
1356
+ return sum(q**max(la) *
1357
+ tilde ** len([x for x in la.to_exp() if x > 0])
1358
+ for la in Partitions(n))
1359
+ return sum(q**max(la) for la in Partitions(n))
1360
+
1361
+
1362
+ def matrix_centralizer_cardinalities(n, q=None, invertible=False):
1363
+ """
1364
+ Generate pairs consisting of centralizer cardinalities of matrices over a
1365
+ finite field and their frequencies.
1366
+
1367
+ TESTS::
1368
+
1369
+ sage: from sage.combinat.similarity_class_type import matrix_centralizer_cardinalities
1370
+ sage: list(matrix_centralizer_cardinalities(1))
1371
+ [(q - 1, q)]
1372
+ sage: list(matrix_centralizer_cardinalities(2))
1373
+ [(q^2 - 2*q + 1, 1/2*q^2 - 1/2*q),
1374
+ (q^2 - q, q),
1375
+ (q^4 - q^3 - q^2 + q, q),
1376
+ (q^2 - 1, 1/2*q^2 - 1/2*q)]
1377
+ sage: list(matrix_centralizer_cardinalities(2, invertible = True))
1378
+ [(q^2 - 2*q + 1, 1/2*q^2 - 3/2*q + 1),
1379
+ (q^2 - q, q - 1),
1380
+ (q^4 - q^3 - q^2 + q, q - 1),
1381
+ (q^2 - 1, 1/2*q^2 - 1/2*q)]
1382
+ """
1383
+ for tau in SimilarityClassTypes(n):
1384
+ yield (tau.centralizer_group_card(q=q), tau.number_of_classes(invertible=invertible, q=q))
1385
+
1386
+
1387
+ def input_parsing(data):
1388
+ """
1389
+ Recognize and return the intended type of ``input``.
1390
+
1391
+ TESTS::
1392
+
1393
+ sage: from sage.combinat.similarity_class_type import input_parsing
1394
+ sage: input_parsing(Partition([2, 1]))
1395
+ ('par', [2, 1])
1396
+ sage: input_parsing(PrimarySimilarityClassType(2, [2, 1]))
1397
+ ('pri', [2, [2, 1]])
1398
+ sage: input_parsing(SimilarityClassType([[2, [2, 1]]]))
1399
+ ('sim', [[2, [2, 1]]])
1400
+ sage: input_parsing([2, 1])
1401
+ ('par', [2, 1])
1402
+ sage: input_parsing([2, [2, 1]])
1403
+ ('pri', [2, [2, 1]])
1404
+ sage: input_parsing([[2, [2, 1]]])
1405
+ ('sim', [[2, [2, 1]]])
1406
+ """
1407
+ if isinstance(data, SimilarityClassType):
1408
+ case = 'sim'
1409
+ elif isinstance(data, PrimarySimilarityClassType):
1410
+ case = 'pri'
1411
+ elif isinstance(data, Partition):
1412
+ case = 'par'
1413
+ else:
1414
+ try:
1415
+ data = Partition(data)
1416
+ case = 'par'
1417
+ except (TypeError, ValueError):
1418
+ try:
1419
+ data = SimilarityClassType(data)
1420
+ case = 'sim'
1421
+ except (TypeError, ValueError):
1422
+ try:
1423
+ data = PrimarySimilarityClassType(*data)
1424
+ case = 'pri'
1425
+ except (TypeError, ValueError):
1426
+ raise ValueError("expected a Partition, a SimilarityClassType or a PrimarySimilarityClassType, got a %s" % type(data))
1427
+ return case, data
1428
+
1429
+
1430
+ def ext_orbits(input_data, q=None, selftranspose=False):
1431
+ r"""
1432
+ Return the number of orbits in `\mathrm{Ext}^1(M, M)` for the action of
1433
+ `\mathrm{Aut}(M, M)`, where `M` is the `\GF{q[t]}`-module constructed
1434
+ from ``input_data``.
1435
+
1436
+ INPUT:
1437
+
1438
+ - ``input_data`` -- input for :func:`input_parsing()`
1439
+ - ``q`` -- (default: `q`) an integer or an indeterminate
1440
+ - ``selftranspose`` -- boolean (default: ``False``); stating if we only
1441
+ want selftranspose type
1442
+
1443
+ TESTS::
1444
+
1445
+ sage: from sage.combinat.similarity_class_type import ext_orbits
1446
+ sage: ext_orbits([6, 1])
1447
+ q^7 + q^6 + q^5
1448
+ sage: ext_orbits([6, 1], selftranspose = True)
1449
+ q^7 + q^6 - q^5
1450
+ sage: ext_orbits([6, 1, 1])
1451
+ q^8 + 2*q^7 + 2*q^6 + 2*q^5
1452
+ sage: ext_orbits ([6, 1, 1], selftranspose = True)
1453
+ q^8 + 2*q^7
1454
+ sage: ext_orbits([2, 2])
1455
+ q^4 + q^3 + q^2
1456
+ sage: ext_orbits([2, 2], selftranspose = True)
1457
+ q^4 + q^3 + q^2
1458
+ sage: ext_orbits([2, 2, 2])
1459
+ q^6 + q^5 + 2*q^4 + q^3 + 2*q^2
1460
+ sage: ext_orbits([2, 2, 2], selftranspose = True)
1461
+ q^6 + q^5 + 2*q^4 + q^3
1462
+ sage: ext_orbits([2, 2, 2, 2])
1463
+ q^8 + q^7 + 3*q^6 + 3*q^5 + 5*q^4 + 3*q^3 + 3*q^2
1464
+ sage: ext_orbits([2, 2, 2, 2], selftranspose = True)
1465
+ q^8 + q^7 + 3*q^6 + 3*q^5 + 3*q^4 + q^3 + q^2
1466
+ sage: ext_orbits([2, [6, 1]])
1467
+ q^14 + q^12 + q^10
1468
+ sage: ext_orbits([[2, [6, 1]]])
1469
+ q^14 + q^12 + q^10
1470
+ """
1471
+ # Comments cite items in the paper "Similarity over rings of length two" by
1472
+ # Prasad, Singla, and Spallone.
1473
+ if q is None:
1474
+ q = FractionField(QQ['q']).gen()
1475
+ case, data = input_parsing(input_data)
1476
+ if case == 'par':
1477
+ la = data
1478
+ if la.size() == 0:
1479
+ return q.parent()(1)
1480
+ if max(la) == 1:
1481
+ return matrix_similarity_classes(len(la), q=q)
1482
+ elif len(la) == 1:
1483
+ return q**la.size()
1484
+ elif len(la) == 2 and list(la).count(1) == 1: # see Table 3
1485
+ m = max(la) - 1
1486
+ if selftranspose:
1487
+ return q**(m + 2) + q**(m + 1) - q**m
1488
+ else:
1489
+ return q**(m + 2) + q**(m + 1) + q**m
1490
+ elif len(la) == 3 and list(la).count(1) == 2: # see Table 4
1491
+ m = max(la) - 1
1492
+ if not selftranspose:
1493
+ return q**m*(q**3 + 2*q**2 + 2*q + 2)
1494
+ else:
1495
+ return q**m*(q**3 + 2*q**2)
1496
+ elif min(la) == 2 and max(la) == 2:
1497
+ return matrix_similarity_classes_length_two(len(la), q=q, selftranspose=selftranspose)
1498
+ else:
1499
+ raise ValueError('partition %s not implemented for ExtOrbitClasses.orbits' % (la))
1500
+ elif case == 'pri':
1501
+ tau = data
1502
+ return ext_orbits(tau.partition(), q=q, selftranspose=selftranspose).substitute(q=q**tau.degree())
1503
+ elif case == 'sim':
1504
+ tau = data
1505
+ return prod([ext_orbits(PT, q=q, selftranspose=selftranspose) for PT in tau])
1506
+
1507
+
1508
+ def matrix_similarity_classes_length_two(n, q=None, selftranspose=False, invertible=False):
1509
+ """
1510
+ Return the number of similarity classes of matrices of order ``n`` with
1511
+ entries in a principal ideal local ring of length two.
1512
+
1513
+ INPUT:
1514
+
1515
+ - ``n`` -- the order
1516
+ - ``q`` -- (default: `q`) an integer or an indeterminate
1517
+ - ``selftranspose`` -- boolean (default: ``False``); stating if we only want
1518
+ selftranspose type
1519
+ - ``invertible`` -- boolean (default: ``False``); stating if we only want
1520
+ invertible type
1521
+
1522
+ EXAMPLES:
1523
+
1524
+ We can generate Table 6 of [PSS13]_::
1525
+
1526
+ sage: from sage.combinat.similarity_class_type import matrix_similarity_classes_length_two
1527
+ sage: matrix_similarity_classes_length_two(2)
1528
+ q^4 + q^3 + q^2
1529
+ sage: matrix_similarity_classes_length_two(2, invertible = True)
1530
+ q^4 - q
1531
+ sage: matrix_similarity_classes_length_two(3)
1532
+ q^6 + q^5 + 2*q^4 + q^3 + 2*q^2
1533
+ sage: matrix_similarity_classes_length_two(3, invertible = true)
1534
+ q^6 - q^3 + 2*q^2 - 2*q
1535
+ sage: matrix_similarity_classes_length_two(4)
1536
+ q^8 + q^7 + 3*q^6 + 3*q^5 + 5*q^4 + 3*q^3 + 3*q^2
1537
+ sage: matrix_similarity_classes_length_two(4, invertible = True)
1538
+ q^8 + q^6 - q^5 + 2*q^4 - 2*q^3 + 2*q^2 - 3*q
1539
+
1540
+ And also Table 7::
1541
+
1542
+ sage: matrix_similarity_classes_length_two(2, selftranspose = True)
1543
+ q^4 + q^3 + q^2
1544
+ sage: matrix_similarity_classes_length_two(2, selftranspose = True, invertible = True)
1545
+ q^4 - q
1546
+ sage: matrix_similarity_classes_length_two(3, selftranspose = True)
1547
+ q^6 + q^5 + 2*q^4 + q^3
1548
+ sage: matrix_similarity_classes_length_two(3, selftranspose = True, invertible = True)
1549
+ q^6 - q^3
1550
+ sage: matrix_similarity_classes_length_two(4, selftranspose = True)
1551
+ q^8 + q^7 + 3*q^6 + 3*q^5 + 3*q^4 + q^3 + q^2
1552
+ sage: matrix_similarity_classes_length_two(4, selftranspose = True, invertible = True)
1553
+ q^8 + q^6 - q^5 - q
1554
+ """
1555
+ if q is None:
1556
+ q = FractionField(QQ['q']).gen()
1557
+ return sum([tau.number_of_classes(invertible=invertible, q=q)*ext_orbits(tau, q=q, selftranspose=selftranspose) for tau in SimilarityClassTypes(n)])
1558
+
1559
+
1560
+ def ext_orbit_centralizers(input_data, q=None, selftranspose=False):
1561
+ r"""
1562
+ Generate pairs consisting of centralizer cardinalities of orbits in
1563
+ `\mathrm{Ext}^1(M, M)` for the action of `\mathrm{Aut}(M, M)`, where `M` is
1564
+ the `\GF{q[t]}`-module constructed from ``input`` and their frequencies.
1565
+
1566
+ INPUT:
1567
+
1568
+ - ``input_data`` -- input for :func:`input_parsing()`
1569
+ - ``q`` -- (default: `q`) an integer or an indeterminate
1570
+ - ``selftranspose`` -- boolean (default: ``False``); stating if we only want
1571
+ selftranspose type
1572
+
1573
+ TESTS::
1574
+
1575
+ sage: from sage.combinat.similarity_class_type import ext_orbit_centralizers
1576
+ sage: list(ext_orbit_centralizers([6, 1]))
1577
+ [(q^9 - 2*q^8 + q^7, q^6),
1578
+ (q^7 - 2*q^6 + q^5, q^7 - q^6),
1579
+ (q^7 - q^6, q^6 + q^5)]
1580
+ sage: list(ext_orbit_centralizers([6, 1], selftranspose = True))
1581
+ [(q^9 - 2*q^8 + q^7, q^6),
1582
+ (q^7 - 2*q^6 + q^5, q^7 - q^6),
1583
+ (q^7 - q^6, q^6 - q^5)]
1584
+ sage: list(ext_orbit_centralizers([6, 1, 1]))
1585
+ [(q^12 - 3*q^11 + 3*q^10 - q^9, 1/2*q^7 - 1/2*q^6),
1586
+ (q^8 - 3*q^7 + 3*q^6 - q^5, 1/2*q^8 - q^7 + 1/2*q^6),
1587
+ (q^12 - 2*q^11 + q^10, q^6),
1588
+ (q^8 - 2*q^7 + q^6, q^7 - q^6),
1589
+ (q^14 - 2*q^13 + 2*q^11 - q^10, q^6),
1590
+ (q^10 - 2*q^9 + 2*q^7 - q^6, q^7 - q^6),
1591
+ (q^12 - q^11 - q^10 + q^9, 1/2*q^7 - 1/2*q^6),
1592
+ (q^8 - q^7 - q^6 + q^5, 1/2*q^8 - q^7 + 1/2*q^6),
1593
+ (q^8 - 2*q^7 + q^6, q^7 - q^6),
1594
+ (q^8 - q^7, q^6 + 2*q^5),
1595
+ (q^10 - 2*q^9 + q^8, 2*q^6)]
1596
+ sage: list(ext_orbit_centralizers([6, 1, 1], selftranspose = True))
1597
+ [(q^12 - 3*q^11 + 3*q^10 - q^9, 1/2*q^7 - 1/2*q^6),
1598
+ (q^8 - 3*q^7 + 3*q^6 - q^5, 1/2*q^8 - q^7 + 1/2*q^6),
1599
+ (q^12 - 2*q^11 + q^10, q^6),
1600
+ (q^8 - 2*q^7 + q^6, q^7 - q^6),
1601
+ (q^14 - 2*q^13 + 2*q^11 - q^10, q^6),
1602
+ (q^10 - 2*q^9 + 2*q^7 - q^6, q^7 - q^6),
1603
+ (q^12 - q^11 - q^10 + q^9, 1/2*q^7 - 1/2*q^6),
1604
+ (q^8 - q^7 - q^6 + q^5, 1/2*q^8 - q^7 + 1/2*q^6),
1605
+ (q^8 - 2*q^7 + q^6, q^7 - q^6),
1606
+ (q^8 - q^7, q^6)]
1607
+ sage: list(ext_orbit_centralizers([2, [6, 1, 1]], selftranspose = True))
1608
+ [(q^24 - 3*q^22 + 3*q^20 - q^18, 1/2*q^14 - 1/2*q^12),
1609
+ (q^16 - 3*q^14 + 3*q^12 - q^10, 1/2*q^16 - q^14 + 1/2*q^12),
1610
+ (q^24 - 2*q^22 + q^20, q^12),
1611
+ (q^16 - 2*q^14 + q^12, q^14 - q^12),
1612
+ (q^28 - 2*q^26 + 2*q^22 - q^20, q^12),
1613
+ (q^20 - 2*q^18 + 2*q^14 - q^12, q^14 - q^12),
1614
+ (q^24 - q^22 - q^20 + q^18, 1/2*q^14 - 1/2*q^12),
1615
+ (q^16 - q^14 - q^12 + q^10, 1/2*q^16 - q^14 + 1/2*q^12),
1616
+ (q^16 - 2*q^14 + q^12, q^14 - q^12),
1617
+ (q^16 - q^14, q^12)]
1618
+ sage: list(ext_orbit_centralizers([[2, [6, 1, 1]]], selftranspose = True))
1619
+ [(q^24 - 3*q^22 + 3*q^20 - q^18, 1/2*q^14 - 1/2*q^12),
1620
+ (q^16 - 3*q^14 + 3*q^12 - q^10, 1/2*q^16 - q^14 + 1/2*q^12),
1621
+ (q^24 - 2*q^22 + q^20, q^12),
1622
+ (q^16 - 2*q^14 + q^12, q^14 - q^12),
1623
+ (q^28 - 2*q^26 + 2*q^22 - q^20, q^12),
1624
+ (q^20 - 2*q^18 + 2*q^14 - q^12, q^14 - q^12),
1625
+ (q^24 - q^22 - q^20 + q^18, 1/2*q^14 - 1/2*q^12),
1626
+ (q^16 - q^14 - q^12 + q^10, 1/2*q^16 - q^14 + 1/2*q^12),
1627
+ (q^16 - 2*q^14 + q^12, q^14 - q^12),
1628
+ (q^16 - q^14, q^12)]
1629
+ """
1630
+ # Comments cite items in the paper "Similarity over rings of length two" by
1631
+ # Prasad, Singla, and Spallone.
1632
+ if q is None:
1633
+ q = FractionField(QQ['q']).gen()
1634
+ case, data = input_parsing(input_data)
1635
+ if case == 'par':
1636
+ la = data
1637
+ if len(la) == 0:
1638
+ yield (1, 1)
1639
+ return
1640
+ elif max(la) == 1:
1641
+ for item in matrix_centralizer_cardinalities(len(la), q=q):
1642
+ yield item
1643
+ return
1644
+ elif len(la) == 1:
1645
+ yield (q**la[0] - q**(la[0]-1), q**la[0])
1646
+ return
1647
+ elif len(la) == 2 and list(la).count(1) == 1: # see Table 3
1648
+ m = max(la) - 1
1649
+ yield (q**(m + 4) - 2*q**(m + 3) + q**(m + 2), q**(m + 1)) # (8.5.1)
1650
+ yield (q**(m + 2) - 2*q**(m + 1) + q**m, q**(m + 2) - q**(m + 1)) # (8.5.2)
1651
+ if selftranspose:
1652
+ yield (q**(m + 2) - q**(m + 1), q**(m+1) - q**m) # (8.5.3) and (8.5.4)
1653
+ else:
1654
+ yield (q**(m + 2) - q**(m + 1), q**(m + 1) + q**m) # (8.5.3) and (8.5.4)
1655
+ return
1656
+ elif len(la) == 3 and list(la).count(1) == 2: # see Table 4
1657
+ m = max(la) - 1
1658
+ for item in matrix_centralizer_cardinalities(2, q=q):
1659
+ yield (item[0]*(q**(m + 5) - q**(m + 4)), item[1]*q**m) # (8.6.1)
1660
+ yield (item[0]*(q**(m + 1) - q**m), item[1]*(q**(m + 1) - q**m)) # (8.6.2)
1661
+ yield (q**(m + 3) - 2*q**(m + 2) + q**(m+1), q**(m + 2) - q**(m + 1)) # (8.6.3)
1662
+ if selftranspose:
1663
+ yield (q**(m + 3) - q**(m+2), q**(m+1)) # (8.6.4), (8.6.5) and (8.6.7)
1664
+ else:
1665
+ yield (q**(m + 3) - q**(m+2), q**(m + 1) + 2*q**m) # (8.6.4), (8.6.5) and (8.6.7)
1666
+ yield (q**(m + 5) - 2*q**(m + 4) + q**(m + 3), 2*q**(m + 1)) # (8.6.6) and (8.6.8)
1667
+ return
1668
+ elif max(la) == 2 and min(la) == 2:
1669
+ for item in matrix_centralizer_cardinalities_length_two(len(la), q=q, selftranspose=selftranspose):
1670
+ yield item
1671
+ else:
1672
+ raise ValueError('partition %s not implemented for ExtOrbitClasses.orbit_centralizers' % (la))
1673
+ elif case == 'pri':
1674
+ tau = data
1675
+ for item in ext_orbit_centralizers(tau.partition(), selftranspose=selftranspose):
1676
+ yield (item[0].substitute(q=q**tau.degree()), item[1].substitute(q=q**tau.degree()))
1677
+ elif case == 'sim':
1678
+ tau = data
1679
+ for item in product(*[IterableFunctionCall(lambda x: ext_orbit_centralizers(x, q=q, selftranspose=selftranspose), PT) for PT in tau]):
1680
+ size = prod([list(entry)[0] for entry in item])
1681
+ freq = prod([list(entry)[1] for entry in item])
1682
+ yield (size, freq)
1683
+
1684
+
1685
+ def matrix_centralizer_cardinalities_length_two(n, q=None, selftranspose=False, invertible=False):
1686
+ r"""
1687
+ Generate pairs consisting of centralizer cardinalities of matrices over a
1688
+ principal ideal local ring of length two with residue field of order ``q``
1689
+ and their frequencies.
1690
+
1691
+ INPUT:
1692
+
1693
+ - ``n`` -- the order
1694
+ - ``q`` -- (default: `q`) an integer or an indeterminate
1695
+ - ``selftranspose`` -- boolean (default: ``False``); stating if we only want
1696
+ selftranspose type
1697
+ - ``invertible`` -- boolean (default: ``False``); stating if we only want
1698
+ invertible type
1699
+
1700
+ TESTS::
1701
+
1702
+ sage: from sage.combinat.similarity_class_type import matrix_centralizer_cardinalities_length_two
1703
+ sage: list(matrix_centralizer_cardinalities_length_two(1))
1704
+ [(q^2 - q, q^2)]
1705
+ sage: list(matrix_centralizer_cardinalities_length_two(2))
1706
+ [(q^4 - 2*q^3 + q^2, 1/2*q^4 - 1/2*q^3),
1707
+ (q^4 - q^3, q^3),
1708
+ (q^6 - 2*q^5 + q^4, 1/2*q^3 - 1/2*q^2),
1709
+ (q^6 - q^5, q^2),
1710
+ (q^8 - q^7 - q^6 + q^5, q^2),
1711
+ (q^6 - q^4, 1/2*q^3 - 1/2*q^2),
1712
+ (q^4 - q^2, 1/2*q^4 - 1/2*q^3)]
1713
+ sage: from sage.combinat.similarity_class_type import dictionary_from_generator
1714
+ sage: dictionary_from_generator(matrix_centralizer_cardinalities_length_two(2, q = 2))
1715
+ {4: 4, 8: 8, 12: 4, 16: 2, 32: 4, 48: 2, 96: 4}
1716
+ """
1717
+ if q is None:
1718
+ q = FractionField(QQ['q']).gen()
1719
+ for tau in SimilarityClassTypes(n):
1720
+ for pair in ext_orbit_centralizers(tau, q=q, selftranspose=selftranspose):
1721
+ yield (q**tau.centralizer_algebra_dim()*pair[0], tau.number_of_classes(invertible=invertible, q=q)*pair[1])