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,2051 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.modules
3
+ r"""
4
+ Recognizable series
5
+
6
+ Let `A` be an alphabet and `K` a semiring. Then a formal series `S`
7
+ with coefficients in `K` and indices in the words `A^*` is called
8
+ recognizable if it has a linear representation, i.e., there exists
9
+
10
+ - a nonnegative integer `n`
11
+
12
+ and there exist
13
+
14
+ - two vectors `\mathit{left}` and `\mathit{right}` of dimension `n` and
15
+
16
+ - a morphism of monoids `\mu` from `A^*` to `n\times n` matrices over `K`
17
+
18
+ such that the coefficient corresponding to a word `w\in A^*` equals
19
+
20
+ .. MATH::
21
+
22
+ \mathit{left} \, \mu(w) \, \mathit{right}.
23
+
24
+ .. NOTE::
25
+
26
+ Whenever a minimization (:meth:`~RecognizableSeries.minimized`) of
27
+ a series needs to be computed, it is required that `K` is a field.
28
+ In particular, minimization is called before checking if a series is
29
+ nonzero.
30
+
31
+ .. SEEALSO::
32
+
33
+ :mod:`k-regular sequence <sage.combinat.regular_sequence>`,
34
+ :mod:`sage.rings.cfinite_sequence`,
35
+ :mod:`sage.combinat.binary_recurrence_sequences`.
36
+
37
+ AUTHORS:
38
+
39
+ - Daniel Krenn (2016, 2021): supported by the Austrian Science Fund (FWF): P 24644-N26
40
+ """
41
+ # ****************************************************************************
42
+ # Copyright (C) 2016 Daniel Krenn <dev@danielkrenn.at>
43
+ #
44
+ # This program is free software: you can redistribute it and/or modify
45
+ # it under the terms of the GNU General Public License as published by
46
+ # the Free Software Foundation, either version 3 of the License, or
47
+ # (at your option) any later version.
48
+ # https://www.gnu.org/licenses/
49
+ # ****************************************************************************
50
+
51
+ from functools import wraps
52
+
53
+ from sage.misc.cachefunc import cached_method
54
+ from sage.structure.element import ModuleElement
55
+ from sage.structure.parent import Parent
56
+ from sage.structure.unique_representation import UniqueRepresentation
57
+
58
+
59
+ class PrefixClosedSet:
60
+ def __init__(self, words):
61
+ r"""
62
+ A prefix-closed set.
63
+
64
+ Creation of this prefix-closed set is interactive
65
+ iteratively.
66
+
67
+ INPUT:
68
+
69
+ - ``words`` -- a class of words
70
+ (instance of :class:`~sage.combinat.words.words.Words`)
71
+
72
+ EXAMPLES::
73
+
74
+ sage: from sage.combinat.recognizable_series import PrefixClosedSet
75
+ sage: P = PrefixClosedSet(Words([0, 1], infinite=False)); P
76
+ [word: ]
77
+
78
+ sage: P = PrefixClosedSet.create_by_alphabet([0, 1]); P
79
+ [word: ]
80
+
81
+ See :meth:`iterate_possible_additions` for further examples.
82
+ """
83
+ self.words = words
84
+ self.elements = [self.words([])]
85
+
86
+ @classmethod
87
+ def create_by_alphabet(cls, alphabet):
88
+ r"""
89
+ A prefix-closed set.
90
+
91
+ This is a convenience method for the
92
+ creation of prefix-closed sets by specifying an alphabet.
93
+
94
+ INPUT:
95
+
96
+ - ``alphabet`` -- finite words over this ``alphabet``
97
+ will used
98
+
99
+ EXAMPLES::
100
+
101
+ sage: from sage.combinat.recognizable_series import PrefixClosedSet
102
+ sage: P = PrefixClosedSet.create_by_alphabet([0, 1]); P
103
+ [word: ]
104
+ """
105
+ from sage.combinat.words.words import Words
106
+ return cls(Words(alphabet, infinite=False))
107
+
108
+ def __repr__(self):
109
+ r"""
110
+ A representation string of this prefix-closed set.
111
+
112
+ OUTPUT: string
113
+
114
+ EXAMPLES::
115
+
116
+ sage: from sage.combinat.recognizable_series import PrefixClosedSet
117
+ sage: P = PrefixClosedSet.create_by_alphabet([0, 1])
118
+ sage: repr(P) # indirect doctest
119
+ '[word: ]'
120
+ """
121
+ return repr(self.elements)
122
+
123
+ def add(self, w, check=True):
124
+ r"""
125
+ Add a word to this prefix-closed set.
126
+
127
+ INPUT:
128
+
129
+ - ``w`` -- a word
130
+
131
+ - ``check`` -- boolean (default: ``True``); if set, then it is verified
132
+ whether all proper prefixes of ``w`` are already in this
133
+ prefix-closed set
134
+
135
+ OUTPUT:
136
+
137
+ Nothing, but a
138
+ :python:`RuntimeError<library/exceptions.html#exceptions.ValueError>`
139
+ is raised if the check fails.
140
+
141
+ EXAMPLES::
142
+
143
+ sage: from sage.combinat.recognizable_series import PrefixClosedSet
144
+ sage: P = PrefixClosedSet.create_by_alphabet([0, 1])
145
+ sage: W = P.words
146
+ sage: P.add(W([0])); P
147
+ [word: , word: 0]
148
+ sage: P.add(W([0, 1])); P
149
+ [word: , word: 0, word: 01]
150
+ sage: P.add(W([1, 1]))
151
+ Traceback (most recent call last):
152
+ ...
153
+ ValueError: cannot add as not all prefixes of 11 are included yet
154
+ """
155
+ if check and any(p not in self.elements
156
+ for p in w.prefixes_iterator()
157
+ if p != w):
158
+ raise ValueError('cannot add as not all prefixes of '
159
+ '{} are included yet'.format(w))
160
+ self.elements.append(w)
161
+
162
+ def iterate_possible_additions(self):
163
+ r"""
164
+ Return an iterator over all elements including possible new elements.
165
+
166
+ OUTPUT: an iterator
167
+
168
+ EXAMPLES::
169
+
170
+ sage: from sage.combinat.recognizable_series import PrefixClosedSet
171
+ sage: P = PrefixClosedSet.create_by_alphabet([0, 1]); P
172
+ [word: ]
173
+ sage: for n, p in enumerate(P.iterate_possible_additions()):
174
+ ....: print('{}?'.format(p))
175
+ ....: if n in (0, 2, 3, 5):
176
+ ....: P.add(p)
177
+ ....: print('...added')
178
+ 0?
179
+ ...added
180
+ 1?
181
+ 00?
182
+ ...added
183
+ 01?
184
+ ...added
185
+ 000?
186
+ 001?
187
+ ...added
188
+ 010?
189
+ 011?
190
+ 0010?
191
+ 0011?
192
+ sage: P.elements
193
+ [word: , word: 0, word: 00, word: 01, word: 001]
194
+
195
+ Calling the iterator once more, returns all elements::
196
+
197
+ sage: list(P.iterate_possible_additions())
198
+ [word: 0,
199
+ word: 1,
200
+ word: 00,
201
+ word: 01,
202
+ word: 000,
203
+ word: 001,
204
+ word: 010,
205
+ word: 011,
206
+ word: 0010,
207
+ word: 0011]
208
+
209
+ The method :meth:`iterate_possible_additions` is roughly equivalent to
210
+ ::
211
+
212
+ sage: list(p + a
213
+ ....: for p in P.elements
214
+ ....: for a in P.words.iterate_by_length(1))
215
+ [word: 0,
216
+ word: 1,
217
+ word: 00,
218
+ word: 01,
219
+ word: 000,
220
+ word: 001,
221
+ word: 010,
222
+ word: 011,
223
+ word: 0010,
224
+ word: 0011]
225
+
226
+ However, the above does not allow to add elements during iteration,
227
+ whereas :meth:`iterate_possible_additions` does.
228
+ """
229
+ n = 0
230
+ it = self.words.iterate_by_length(1)
231
+ while n < len(self.elements):
232
+ try:
233
+ nn = next(it)
234
+ yield self.elements[n] + nn # next(it)
235
+ except StopIteration:
236
+ n += 1
237
+ it = self.words.iterate_by_length(1)
238
+
239
+ def prefix_set(self):
240
+ r"""
241
+ Return the set of minimal (with respect to prefix ordering) elements
242
+ of the complement of this prefix closed set.
243
+
244
+ See also Proposition 2.3.1 of [BR2010a]_.
245
+
246
+ OUTPUT: list
247
+
248
+ EXAMPLES::
249
+
250
+ sage: from sage.combinat.recognizable_series import PrefixClosedSet
251
+ sage: P = PrefixClosedSet.create_by_alphabet([0, 1]); P
252
+ [word: ]
253
+ sage: for n, p in enumerate(P.iterate_possible_additions()):
254
+ ....: if n in (0, 1, 2, 4, 6):
255
+ ....: P.add(p)
256
+ sage: P
257
+ [word: , word: 0, word: 1, word: 00, word: 10, word: 000]
258
+ sage: P.prefix_set()
259
+ [word: 01, word: 11, word: 001, word: 100,
260
+ word: 101, word: 0000, word: 0001]
261
+ """
262
+ return [p + a
263
+ for p in self.elements
264
+ for a in self.words.iterate_by_length(1)
265
+ if p + a not in self.elements]
266
+
267
+
268
+ def minimize_result(operation):
269
+ r"""
270
+ A decorator for operations that enables control of
271
+ automatic minimization on the result.
272
+
273
+ INPUT:
274
+
275
+ - ``operation`` -- a method
276
+
277
+ OUTPUT: a method with the following additional argument:
278
+
279
+ - ``minimize`` -- (default: ``None``) a boolean or ``None``.
280
+ If ``True``, then :meth:`minimized` is called after the operation,
281
+ if ``False``, then not. If this argument is ``None``, then
282
+ the default specified by the parent's ``minimize_results`` is used.
283
+
284
+ .. NOTE::
285
+
286
+ If the result of ``operation`` is ``self``, then minimization is
287
+ not applied unless ``minimize=True`` is explicitly set,
288
+ in particular, independent of the parent's ``minimize_results``.
289
+
290
+ TESTS::
291
+
292
+ sage: from sage.combinat.recognizable_series import minimize_result
293
+ sage: class P():
294
+ ....: pass
295
+ sage: p = P()
296
+ sage: class S():
297
+ ....: def __init__(self, s):
298
+ ....: self.s = s
299
+ ....: def __repr__(self):
300
+ ....: return self.s
301
+ ....: def parent(self):
302
+ ....: return p
303
+ ....: def minimized(self):
304
+ ....: return S(self.s + ' minimized')
305
+ ....: @minimize_result
306
+ ....: def operation(self):
307
+ ....: return S(self.s + ' result')
308
+
309
+ sage: p.minimize_results = True
310
+ sage: S('some').operation()
311
+ some result minimized
312
+ sage: S('some').operation(minimize=True)
313
+ some result minimized
314
+ sage: S('some').operation(minimize=False)
315
+ some result
316
+
317
+ sage: p.minimize_results = False
318
+ sage: S('some').operation()
319
+ some result
320
+ sage: S('some').operation(minimize=True)
321
+ some result minimized
322
+ sage: S('some').operation(minimize=False)
323
+ some result
324
+
325
+ ::
326
+
327
+ sage: class T(S):
328
+ ....: @minimize_result
329
+ ....: def nooperation(self):
330
+ ....: return self
331
+ sage: t = T('some')
332
+ sage: p.minimize_results = True
333
+ sage: t.nooperation() is t
334
+ True
335
+ sage: t.nooperation(minimize=True) is t
336
+ False
337
+ sage: t.nooperation(minimize=False) is t
338
+ True
339
+ sage: p.minimize_results = False
340
+ sage: t.nooperation() is t
341
+ True
342
+ sage: t.nooperation(minimize=True) is t
343
+ False
344
+ sage: t.nooperation(minimize=False) is t
345
+ True
346
+ """
347
+ @wraps(operation)
348
+ def minimized(self, *args, **kwds):
349
+ minimize = kwds.pop('minimize', None)
350
+
351
+ result = operation(self, *args, **kwds)
352
+ if minimize is not True and result is self:
353
+ return result
354
+
355
+ if minimize is None:
356
+ minimize = self.parent().minimize_results
357
+
358
+ if minimize:
359
+ result = result.minimized()
360
+
361
+ return result
362
+
363
+ return minimized
364
+
365
+
366
+ class RecognizableSeries(ModuleElement):
367
+ def __init__(self, parent, mu, left, right):
368
+ r"""
369
+ A recognizable series.
370
+
371
+ - ``parent`` -- an instance of :class:`RecognizableSeriesSpace`
372
+
373
+ - ``mu`` -- a family of square matrices, all of which have the
374
+ same dimension.
375
+ The indices of this family are the elements of the alphabet.
376
+ ``mu`` may be a list or tuple of the same cardinality as the
377
+ alphabet as well. See also :meth:`mu <mu>`.
378
+
379
+ - ``left`` -- a vector. When evaluating a
380
+ coefficient, this vector is multiplied from the left to the
381
+ matrix obtained from :meth:`mu <mu>` applying on a word.
382
+ See also :meth:`left <left>`.
383
+
384
+ - ``right`` -- a vector. When evaluating a
385
+ coefficient, this vector is multiplied from the right to the
386
+ matrix obtained from :meth:`mu <mu>` applying on a word.
387
+ See also :meth:`right <right>`.
388
+
389
+ When created via the parent :class:`RecognizableSeriesSpace`, then
390
+ the following option is available.
391
+
392
+ EXAMPLES::
393
+
394
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
395
+ sage: S = Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
396
+ ....: vector([0, 1]), vector([1, 0])).transposed(); S
397
+ [1] + 3*[01] + [10] + 5*[11] + 9*[001] + 3*[010] + ...
398
+
399
+ We can access coefficients by
400
+ ::
401
+
402
+ sage: W = Rec.indices()
403
+ sage: S[W([0, 0, 1])]
404
+ 9
405
+
406
+ .. SEEALSO::
407
+
408
+ :doc:`recognizable series <recognizable_series>`,
409
+ :class:`RecognizableSeriesSpace`.
410
+
411
+ TESTS::
412
+
413
+ sage: Rec = RecognizableSeriesSpace(ZZ, (0,1))
414
+ sage: M0 = Matrix([[1, 0], [0, 1]])
415
+ sage: M1 = Matrix([[0, -1], [1, 2]])
416
+ sage: Rec((M0, M1), (0, 1), (1, 1))
417
+ [] + [0] + 3*[1] + [00] + 3*[01] + 3*[10] + 5*[11] + [000] + 3*[001] + 3*[010] + ...
418
+
419
+ sage: M0 = Matrix([[3, 6], [0, 1]])
420
+ sage: M1 = Matrix([[0, -6], [1, 5]])
421
+ sage: L = vector([0, 1])
422
+ sage: R = vector([1, 0])
423
+ sage: S = Rec((M0, M1), L, R)
424
+ sage: S.mu[0] is M0, S.mu[1] is M1, S.left is L, S.right is R
425
+ (False, False, False, False)
426
+ sage: S.mu[0].is_immutable(), S.mu[1].is_immutable(), S.left.is_immutable(), S.right.is_immutable()
427
+ (True, True, True, True)
428
+ sage: M0.set_immutable()
429
+ sage: M1.set_immutable()
430
+ sage: L.set_immutable()
431
+ sage: R.set_immutable()
432
+ sage: S = Rec((M0, M1), L, R)
433
+ sage: S.mu[0] is M0, S.mu[1] is M1, S.left is L, S.right is R
434
+ (True, True, True, True)
435
+ """
436
+ super().__init__(parent=parent)
437
+
438
+ from copy import copy
439
+ from sage.matrix.constructor import Matrix
440
+ from sage.modules.free_module_element import vector
441
+ from sage.sets.family import Family
442
+
443
+ A = self.parent().alphabet()
444
+ if isinstance(mu, (list, tuple)):
445
+ mu = dict(zip(A, mu))
446
+
447
+ def immutable(m):
448
+ if m.is_immutable():
449
+ return m
450
+ m = copy(m)
451
+ m.set_immutable()
452
+ return m
453
+
454
+ if isinstance(mu, dict):
455
+ mu = {a: Matrix(M, immutable=True) for a, M in mu.items()}
456
+ mu = Family(mu)
457
+
458
+ if not mu.is_finite():
459
+ raise NotImplementedError('mu is not a finite family of matrices')
460
+
461
+ self._left_ = immutable(vector(left))
462
+ self._mu_ = mu
463
+ self._right_ = immutable(vector(right))
464
+
465
+ @property
466
+ def mu(self):
467
+ r"""
468
+ When evaluating a coefficient, this is applied on each letter
469
+ of a word; the result is a matrix.
470
+ This extends :meth:`mu <mu>` to words over the parent's
471
+ :meth:`~RecognizableSeriesSpace.alphabet`.
472
+
473
+ TESTS::
474
+
475
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
476
+ sage: M0 = Matrix([[1, 0], [0, 1]])
477
+ sage: M1 = Matrix([[0, -1], [1, 2]])
478
+ sage: S = Rec((M0, M1), vector([0, 1]), vector([1, 1]))
479
+ sage: S.mu[0] == M0 and S.mu[1] == M1
480
+ True
481
+ """
482
+ return self._mu_
483
+
484
+ @property
485
+ def left(self):
486
+ r"""
487
+ When evaluating a coefficient, this vector is multiplied from
488
+ the left to the matrix obtained from :meth:`mu <mu>` applied on a
489
+ word.
490
+
491
+ TESTS::
492
+
493
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
494
+ sage: Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
495
+ ....: vector([0, 1]), vector([1, 0])).transposed().left
496
+ (1, 0)
497
+ """
498
+ return self._left_
499
+
500
+ @property
501
+ def right(self):
502
+ r"""
503
+ When evaluating a coefficient, this vector is multiplied from
504
+ the right to the matrix obtained from :meth:`mu <mu>` applied on a
505
+ word.
506
+
507
+ TESTS::
508
+
509
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
510
+ sage: Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
511
+ ....: vector([0, 1]), vector([1, 0])).transposed().right
512
+ (0, 1)
513
+ """
514
+ return self._right_
515
+
516
+ def linear_representation(self):
517
+ r"""
518
+ Return the linear representation of this series.
519
+
520
+ OUTPUT:
521
+
522
+ A triple ``(left, mu, right)`` containing
523
+ the vectors :meth:`left <left>` and :meth:`right <right>`,
524
+ and the family of matrices :meth:`mu <mu>`.
525
+
526
+ EXAMPLES::
527
+
528
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
529
+ sage: Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
530
+ ....: vector([0, 1]), vector([1, 0])
531
+ ....: ).transposed().linear_representation()
532
+ ((1, 0),
533
+ Finite family {0: [3 0]
534
+ [6 1],
535
+ 1: [ 0 1]
536
+ [-6 5]},
537
+ (0, 1))
538
+ """
539
+ return (self.left, self.mu, self.right)
540
+
541
+ def _repr_(self, latex=False):
542
+ r"""
543
+ A representation string for this recognizable series.
544
+
545
+ INPUT:
546
+
547
+ - ``latex`` -- boolean (default: ``False``); if set, then LaTeX-output
548
+ is returned
549
+
550
+ OUTPUT: string
551
+
552
+ EXAMPLES::
553
+
554
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
555
+ sage: S = Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
556
+ ....: vector([0, 1]), vector([1, 0])).transposed()
557
+ sage: repr(S) # indirect doctest
558
+ '[1] + 3*[01] + [10] + 5*[11] + 9*[001] + 3*[010] + ...'
559
+
560
+ TESTS::
561
+
562
+ sage: S = Rec((Matrix([[0]]), Matrix([[0]])),
563
+ ....: vector([1]), vector([1]))
564
+ sage: repr(S) # indirect doctest
565
+ '[] + ...'
566
+
567
+ sage: S = Rec((Matrix([[0, 1], [0, 0]]), Matrix([[0, 0], [0, 0]])),
568
+ ....: vector([0, 1]), vector([1, 0]))
569
+ sage: repr(S) # indirect doctest
570
+ '0 + ...'
571
+ """
572
+ if self.is_trivial_zero():
573
+ return '0'
574
+
575
+ from itertools import islice
576
+
577
+ if latex:
578
+ from sage.misc.latex import latex as latex_repr
579
+ fr = latex_repr
580
+ fs = latex_repr
581
+ times = ' '
582
+ else:
583
+ fr = repr
584
+ fs = str
585
+ times = '*'
586
+
587
+ def summand(w, c):
588
+ if c == 1:
589
+ return '[{w}]'.format(w=fs(w))
590
+ return '{c}{times}[{w}]'.format(c=fr(c), times=times, w=fs(w))
591
+
592
+ def all_coefficients():
593
+ number_of_zeros = 0
594
+ for w in self.parent().indices():
595
+ c = self[w]
596
+ if c != 0:
597
+ number_of_zeros = 0
598
+ yield (w, self[w])
599
+ else:
600
+ number_of_zeros += 1
601
+ if number_of_zeros >= 100:
602
+ return
603
+
604
+ coefficients = islice(all_coefficients(), 10)
605
+
606
+ s = ' + '.join(summand(w, c)
607
+ for w, c in coefficients)
608
+ s = s.replace('+ -', '- ')
609
+ if not s:
610
+ s = '0'
611
+ return s + ' + ...'
612
+
613
+ def _latex_(self):
614
+ r"""
615
+ A LaTeX-representation string for this recognizable series.
616
+
617
+ OUTPUT: string
618
+
619
+ TESTS::
620
+
621
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
622
+ sage: S = Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
623
+ ....: vector([0, 1]), vector([1, 0])).transposed()
624
+ sage: latex(S) # indirect doctest
625
+ [1] + 3 [01] + [10] + 5 [11] + 9 [001] + 3 [010]
626
+ + 15 [011] + [100] + 11 [101] + 5 [110] + ...
627
+ """
628
+ return self._repr_(latex=True)
629
+
630
+ @cached_method
631
+ def coefficient_of_word(self, w, multiply_left=True, multiply_right=True):
632
+ r"""
633
+ Return the coefficient to word `w` of this series.
634
+
635
+ INPUT:
636
+
637
+ - ``w`` -- a word over the parent's
638
+ :meth:`~RecognizableSeriesSpace.alphabet`
639
+
640
+ - ``multiply_left`` -- boolean (default: ``True``); if ``False``,
641
+ then multiplication by :meth:`left <left>` is skipped
642
+
643
+ - ``multiply_right`` -- boolean (default: ``True``); if ``False``,
644
+ then multiplication by :meth:`right <right>` is skipped
645
+
646
+ OUTPUT:
647
+
648
+ An element in the parent's
649
+ :meth:`~RecognizableSeriesSpace.coefficient_ring`
650
+
651
+ EXAMPLES::
652
+
653
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
654
+ sage: W = Rec.indices()
655
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[0, -1], [1, 2]])),
656
+ ....: left=vector([0, 1]), right=vector([1, 0]))
657
+ sage: S[W(7.digits(2))] # indirect doctest
658
+ 3
659
+
660
+ TESTS::
661
+
662
+ sage: w = W(6.digits(2))
663
+ sage: S.coefficient_of_word(w)
664
+ 2
665
+ sage: S.coefficient_of_word(w, multiply_left=False)
666
+ (-1, 2)
667
+ sage: S.coefficient_of_word(w, multiply_right=False)
668
+ (2, 3)
669
+ sage: S.coefficient_of_word(w, multiply_left=False, multiply_right=False)
670
+ [-1 -2]
671
+ [ 2 3]
672
+ """
673
+ result = self._mu_of_word_(w)
674
+ if multiply_left:
675
+ result = self.left * result
676
+ if multiply_right:
677
+ result = result * self.right
678
+ return result
679
+
680
+ __getitem__ = coefficient_of_word
681
+
682
+ @cached_method
683
+ def _mu_of_empty_word_(self):
684
+ r"""
685
+ Return :meth:`mu <mu>` applied on the empty word.
686
+
687
+ OUTPUT: a matrix
688
+
689
+ TESTS::
690
+
691
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
692
+ sage: W = Rec.indices()
693
+ sage: M0 = Matrix([[1, 0], [0, 1]])
694
+ sage: M1 = Matrix([[0, -1], [1, 2]])
695
+ sage: S = Rec({W([0]): M0, W([1]): M1}, vector([0, 1]), vector([1, 1]))
696
+ sage: S._mu_of_empty_word_()
697
+ [1 0]
698
+ [0 1]
699
+ sage: I = Matrix([[1, 0], [0, 1]]); I.set_immutable()
700
+ sage: T = Rec({W([]): I, W([0]): M0, W([1]): M1}, vector([0, 1]), vector([1, 1]))
701
+ sage: T._mu_of_empty_word_()
702
+ [1 0]
703
+ [0 1]
704
+ sage: _ is I
705
+ True
706
+ """
707
+ eps = self.parent().indices()()
708
+ try:
709
+ return self.mu[eps]
710
+ except KeyError:
711
+ return next(iter(self.mu)).parent().one()
712
+
713
+ @cached_method
714
+ def _mu_of_word_(self, w):
715
+ r"""
716
+ Return :meth:`mu <mu>` applied on the word `w`.
717
+
718
+ INPUT:
719
+
720
+ - ``w`` -- a word over the parent's
721
+ :meth:`~RecognizableSeriesSpace.alphabet`
722
+
723
+ OUTPUT: a matrix
724
+
725
+ TESTS::
726
+
727
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
728
+ sage: W = Rec.indices()
729
+ sage: M0 = Matrix([[1, 0], [0, 1]])
730
+ sage: M1 = Matrix([[0, -1], [1, 2]])
731
+ sage: S = Rec((M0, M1), vector([0, 1]), vector([1, 1]))
732
+ sage: S._mu_of_word_(W([0])) == M0
733
+ True
734
+ sage: S._mu_of_word_(W([1])) == M1
735
+ True
736
+ sage: S._mu_of_word_(W(3.digits(2))) == M1^2
737
+ True
738
+
739
+ ::
740
+
741
+ sage: S._mu_of_word_(-1)
742
+ Traceback (most recent call last):
743
+ ...
744
+ ValueError: index -1 is not in Finite words over {0, 1}
745
+ """
746
+ W = self.parent().indices()
747
+ if w not in W:
748
+ raise ValueError('index {} is not in {}'.format(w, W))
749
+ from sage.misc.misc_c import prod
750
+ return prod((self.mu[a] for a in w), z=self._mu_of_empty_word_())
751
+
752
+ def __iter__(self):
753
+ r"""
754
+ Return an iterator over pairs ``(index, coefficient)``.
755
+
756
+ EXAMPLES::
757
+
758
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
759
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[0, -1], [1, 2]])),
760
+ ....: left=vector([0, 1]), right=vector([1, 0]))
761
+ sage: from itertools import islice
762
+ sage: list(islice(S, 10))
763
+ [(word: , 0),
764
+ (word: 0, 0),
765
+ (word: 1, 1),
766
+ (word: 00, 0),
767
+ (word: 01, 1),
768
+ (word: 10, 1),
769
+ (word: 11, 2),
770
+ (word: 000, 0),
771
+ (word: 001, 1),
772
+ (word: 010, 1)]
773
+ sage: list(islice((s for s in S if s[1] != 0), 10))
774
+ [(word: 1, 1),
775
+ (word: 01, 1),
776
+ (word: 10, 1),
777
+ (word: 11, 2),
778
+ (word: 001, 1),
779
+ (word: 010, 1),
780
+ (word: 011, 2),
781
+ (word: 100, 1),
782
+ (word: 101, 2),
783
+ (word: 110, 2)]
784
+
785
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[0, -1], [1, 2]])),
786
+ ....: left=vector([1, 0]), right=vector([1, 0]))
787
+ sage: list(islice((s for s in S if s[1] != 0), 10))
788
+ [(word: , 1),
789
+ (word: 0, 1),
790
+ (word: 00, 1),
791
+ (word: 11, -1),
792
+ (word: 000, 1),
793
+ (word: 011, -1),
794
+ (word: 101, -1),
795
+ (word: 110, -1),
796
+ (word: 111, -2),
797
+ (word: 0000, 1)]
798
+
799
+ TESTS::
800
+
801
+ sage: it = iter(S)
802
+ sage: iter(it) is it
803
+ True
804
+ sage: iter(S) is not it
805
+ True
806
+ """
807
+ return iter((w, self[w]) for w in self.parent().indices())
808
+
809
+ def is_trivial_zero(self):
810
+ r"""
811
+ Return whether this recognizable series is trivially equal to
812
+ zero (without any :meth:`minimization <minimized>`).
813
+
814
+ EXAMPLES::
815
+
816
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
817
+ sage: Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
818
+ ....: left=vector([0, 1]), right=vector([1, 0])).is_trivial_zero()
819
+ False
820
+ sage: Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
821
+ ....: left=vector([0, 0]), right=vector([1, 0])).is_trivial_zero()
822
+ True
823
+ sage: Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
824
+ ....: left=vector([0, 1]), right=vector([0, 0])).is_trivial_zero()
825
+ True
826
+
827
+ The following two differ in the coefficient of the empty word::
828
+
829
+ sage: Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])),
830
+ ....: left=vector([0, 1]), right=vector([1, 0])).is_trivial_zero()
831
+ True
832
+ sage: Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])),
833
+ ....: left=vector([1, 1]), right=vector([1, 1])).is_trivial_zero()
834
+ False
835
+
836
+ TESTS::
837
+
838
+ sage: Rec.zero().is_trivial_zero()
839
+ True
840
+
841
+ The following is zero, but not trivially zero::
842
+
843
+ sage: S = Rec((Matrix([[1, 0], [0, 0]]), Matrix([[1, 0], [0, 0]])),
844
+ ....: left=vector([0, 1]), right=vector([1, 0]))
845
+ sage: S.is_trivial_zero()
846
+ False
847
+ sage: S.is_zero()
848
+ True
849
+ """
850
+ return not self.left or not self.right or \
851
+ (all(not self.mu[a] for a in self.parent().alphabet()) and
852
+ not self[self.parent().indices()()])
853
+
854
+ def __bool__(self):
855
+ r"""
856
+ Return whether this recognizable series is nonzero.
857
+
858
+ TESTS::
859
+
860
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
861
+ sage: bool(Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
862
+ ....: left=vector([0, 1]), right=vector([1, 0])))
863
+ False
864
+ sage: bool(Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])),
865
+ ....: left=vector([0, 1]), right=vector([1, 0])))
866
+ False
867
+ sage: bool(Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
868
+ ....: left=vector([0, 0]), right=vector([1, 0])))
869
+ False
870
+ sage: bool(Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
871
+ ....: left=vector([0, 1]), right=vector([0, 0])))
872
+ False
873
+
874
+ ::
875
+
876
+ sage: S = Rec((Matrix([[1, 0], [0, 0]]), Matrix([[1, 0], [0, 0]])),
877
+ ....: left=vector([0, 1]), right=vector([1, 0]))
878
+ sage: bool(S)
879
+ False
880
+ """
881
+ if self.is_trivial_zero():
882
+ return False
883
+ try:
884
+ M = self.minimized()
885
+ except ValueError:
886
+ pass
887
+ else:
888
+ if M.is_trivial_zero():
889
+ return False
890
+ return True
891
+
892
+ def __hash__(self):
893
+ r"""
894
+ A hash value of this recognizable series.
895
+
896
+ TESTS::
897
+
898
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
899
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
900
+ ....: left=vector([0, 1]), right=vector([1, 0]))
901
+ sage: hash(S) # random
902
+ 42
903
+ """
904
+ return hash((self.mu, self.left, self.right))
905
+
906
+ def __eq__(self, other):
907
+ r"""
908
+ Return whether this recognizable series is equal to ``other``.
909
+
910
+ INPUT:
911
+
912
+ - ``other`` -- an object
913
+
914
+ OUTPUT: boolean
915
+
916
+ .. NOTE::
917
+
918
+ This function uses the coercion model to find a common
919
+ parent for the two operands.
920
+
921
+ EXAMPLES::
922
+
923
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
924
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
925
+ ....: left=vector([1, 1]), right=vector([1, 0]))
926
+ sage: S
927
+ [] + [0] + [1] + [00] + [01] + [10]
928
+ + [11] + [000] + [001] + [010] + ...
929
+ sage: Z1 = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
930
+ ....: left=vector([0, 1]), right=vector([1, 0]))
931
+ sage: Z1
932
+ 0 + ...
933
+ sage: Z2 = Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])),
934
+ ....: left=vector([0, 1]), right=vector([1, 0]))
935
+ sage: Z2
936
+ 0
937
+ sage: S == Z1
938
+ False
939
+ sage: S == Z2
940
+ False
941
+ sage: Z1 == Z2
942
+ True
943
+
944
+ TESTS::
945
+
946
+ sage: S == S
947
+ True
948
+ sage: S == None
949
+ False
950
+ """
951
+ if other is None:
952
+ return False
953
+ try:
954
+ return not bool(self - other)
955
+ except (TypeError, ValueError):
956
+ return False
957
+
958
+ def __ne__(self, other):
959
+ r"""
960
+ Return whether this recognizable series is not equal to ``other``.
961
+
962
+ INPUT:
963
+
964
+ - ``other`` -- an object
965
+
966
+ OUTPUT: boolean
967
+
968
+ .. NOTE::
969
+
970
+ This function uses the coercion model to find a common
971
+ parent for the two operands.
972
+
973
+ EXAMPLES::
974
+
975
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
976
+ sage: Z1 = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
977
+ ....: left=vector([0, 1]), right=vector([1, 0]))
978
+ sage: Z2 = Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])),
979
+ ....: left=vector([0, 1]), right=vector([1, 0]))
980
+ sage: Z1 != Z2
981
+ False
982
+ sage: Z1 != Z1
983
+ False
984
+ """
985
+ return not self == other
986
+
987
+ def transposed(self):
988
+ r"""
989
+ Return the transposed series.
990
+
991
+ OUTPUT: a :class:`RecognizableSeries`
992
+
993
+ Each of the matrices in :meth:`mu <mu>` is transposed. Additionally
994
+ the vectors :meth:`left <left>` and :meth:`right <right>` are switched.
995
+
996
+ EXAMPLES::
997
+
998
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
999
+ sage: S = Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
1000
+ ....: vector([0, 1]), vector([1, 0])).transposed()
1001
+ sage: S
1002
+ [1] + 3*[01] + [10] + 5*[11] + 9*[001] + 3*[010]
1003
+ + 15*[011] + [100] + 11*[101] + 5*[110] + ...
1004
+ sage: S.mu[0], S.mu[1], S.left, S.right
1005
+ (
1006
+ [3 0] [ 0 1]
1007
+ [6 1], [-6 5], (1, 0), (0, 1)
1008
+ )
1009
+ sage: T = S.transposed()
1010
+ sage: T
1011
+ [1] + [01] + 3*[10] + 5*[11] + [001] + 3*[010]
1012
+ + 5*[011] + 9*[100] + 11*[101] + 15*[110] + ...
1013
+ sage: T.mu[0], T.mu[1], T.left, T.right
1014
+ (
1015
+ [3 6] [ 0 -6]
1016
+ [0 1], [ 1 5], (0, 1), (1, 0)
1017
+ )
1018
+
1019
+ TESTS::
1020
+
1021
+ sage: T.mu[0].is_immutable(), T.mu[1].is_immutable(), T.left.is_immutable(), T.right.is_immutable()
1022
+ (True, True, True, True)
1023
+ """
1024
+ def tr(M):
1025
+ T = M.transpose()
1026
+ T.set_immutable()
1027
+ return T
1028
+
1029
+ P = self.parent()
1030
+ return P.element_class(P, self.mu.map(tr),
1031
+ left=self.right,
1032
+ right=self.left)
1033
+
1034
+ @cached_method
1035
+ def minimized(self):
1036
+ r"""
1037
+ Return a recognizable series equivalent to this series, but
1038
+ with a minimized linear representation.
1039
+
1040
+ The coefficients of the involved matrices need be in a field.
1041
+ If this is not the case, then the coefficients are
1042
+ automatically coerced to their fraction field.
1043
+
1044
+ OUTPUT: a :class:`RecognizableSeries`
1045
+
1046
+ ALGORITHM:
1047
+
1048
+ This method implements the minimization algorithm presented in
1049
+ Chapter 2 of [BR2010a]_.
1050
+
1051
+ .. NOTE::
1052
+
1053
+ Due to the algorithm, the left vector of the result
1054
+ is always `(1, 0, \ldots, 0)`, i.e., the first vector of the
1055
+ standard basis.
1056
+
1057
+ EXAMPLES::
1058
+
1059
+ sage: from itertools import islice
1060
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1061
+
1062
+ sage: S = Rec((Matrix([[3, 6], [0, 1]]), Matrix([[0, -6], [1, 5]])),
1063
+ ....: vector([0, 1]), vector([1, 0])).transposed()
1064
+ sage: S
1065
+ [1] + 3*[01] + [10] + 5*[11] + 9*[001] + 3*[010]
1066
+ + 15*[011] + [100] + 11*[101] + 5*[110] + ...
1067
+ sage: M = S.minimized()
1068
+ sage: M.mu[0], M.mu[1], M.left, M.right
1069
+ (
1070
+ [3 0] [ 0 1]
1071
+ [6 1], [-6 5], (1, 0), (0, 1)
1072
+ )
1073
+ sage: M.left == vector([1, 0])
1074
+ True
1075
+ sage: all(c == d and v == w
1076
+ ....: for (c, v), (d, w) in islice(zip(iter(S), iter(M)), 20))
1077
+ True
1078
+
1079
+ sage: S = Rec((Matrix([[2, 0], [1, 1]]), Matrix([[2, 0], [2, 1]])),
1080
+ ....: vector([1, 0]), vector([1, 1]))
1081
+ sage: S
1082
+ [] + 2*[0] + 2*[1] + 4*[00] + 4*[01] + 4*[10] + 4*[11]
1083
+ + 8*[000] + 8*[001] + 8*[010] + ...
1084
+ sage: M = S.minimized()
1085
+ sage: M.mu[0], M.mu[1], M.left, M.right
1086
+ ([2], [2], (1), (1))
1087
+ sage: all(c == d and v == w
1088
+ ....: for (c, v), (d, w) in islice(zip(iter(S), iter(M)), 20))
1089
+ True
1090
+
1091
+ TESTS::
1092
+
1093
+ sage: Rec((Matrix([[0]]), Matrix([[0]])),
1094
+ ....: vector([1]), vector([0])).minimized().linear_representation()
1095
+ ((), Finite family {0: [], 1: []}, ())
1096
+ """
1097
+ return self._minimized_right_()._minimized_left_()
1098
+
1099
+ def _minimized_right_(self):
1100
+ r"""
1101
+ Return a recognizable series equivalent to this series, but
1102
+ with a right minimized linear representation.
1103
+
1104
+ OUTPUT: a :class:`RecognizableSeries`
1105
+
1106
+ See :meth:`minimized` for details.
1107
+
1108
+ TESTS::
1109
+
1110
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1111
+ sage: S = Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])),
1112
+ ....: vector([1, 1]), vector([1, 1]))
1113
+ sage: M = S._minimized_right_()
1114
+ sage: M.mu[0], M.mu[1], M.left, M.right
1115
+ ([0], [0], (2), (1))
1116
+ """
1117
+ return self.transposed()._minimized_left_().transposed()
1118
+
1119
+ def _minimized_left_(self):
1120
+ r"""
1121
+ Return a recognizable series equivalent to this series, but
1122
+ with a left minimized linear representation.
1123
+
1124
+ OUTPUT: a :class:`RecognizableSeries`
1125
+
1126
+ See :meth:`minimized` for details.
1127
+
1128
+ TESTS::
1129
+
1130
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1131
+ sage: S = Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])),
1132
+ ....: vector([1, 1]), vector([1, 1]))
1133
+ sage: M = S._minimized_left_()
1134
+ sage: M.mu[0], M.mu[1], M.left, M.right
1135
+ ([0], [0], (1), (2))
1136
+ sage: M = S.minimized()
1137
+ sage: M.mu[0], M.mu[1], M.left, M.right
1138
+ ([0], [0], (1), (2))
1139
+
1140
+ ::
1141
+
1142
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
1143
+ ....: vector([1, -1]), vector([1, 1]))._minimized_left_()
1144
+ sage: S.mu[0], S.mu[1], S.left, S.right
1145
+ ([1], [1], (1), (0))
1146
+ sage: M = S.minimized()
1147
+ sage: M.mu[0], M.mu[1], M.left, M.right
1148
+ ([], [], (), ())
1149
+
1150
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
1151
+ ....: vector([1, 1]), vector([1, -1]))
1152
+ sage: M = S._minimized_left_()
1153
+ sage: M.mu[0], M.mu[1], M.left, M.right
1154
+ ([1], [1], (1), (0))
1155
+ sage: M = S.minimized()
1156
+ sage: M.mu[0], M.mu[1], M.left, M.right
1157
+ ([], [], (), ())
1158
+
1159
+ sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
1160
+ ....: left=vector([0, 1]), right=vector([1, 0]))
1161
+ sage: M = S._minimized_left_()
1162
+ sage: M.mu[0], M.mu[1], M.left, M.right
1163
+ ([1], [1], (1), (0))
1164
+ sage: M = S.minimized()
1165
+ sage: M.mu[0], M.mu[1], M.left, M.right
1166
+ ([], [], (), ())
1167
+ """
1168
+ from sage.matrix.constructor import Matrix
1169
+ from sage.modules.free_module_element import vector
1170
+ from sage.rings.integer_ring import ZZ
1171
+
1172
+ pcs = PrefixClosedSet(self.parent().indices())
1173
+ left = self.coefficient_of_word(pcs.elements[0], multiply_right=False)
1174
+ if left.is_zero():
1175
+ return self.parent().zero()
1176
+ Left = [left]
1177
+ for p in pcs.iterate_possible_additions():
1178
+ left = self.coefficient_of_word(p,
1179
+ multiply_left=True,
1180
+ multiply_right=False)
1181
+ try:
1182
+ Matrix(Left).solve_left(left)
1183
+ except ValueError:
1184
+ # no solution found
1185
+ pcs.add(p)
1186
+ Left.append(left)
1187
+ P = pcs.elements
1188
+ C = pcs.prefix_set()
1189
+
1190
+ ML = Matrix(Left)
1191
+
1192
+ def alpha(c):
1193
+ return ML.solve_left(self.coefficient_of_word(c, multiply_right=False))
1194
+
1195
+ mu_prime = []
1196
+ for a in self.parent().alphabet():
1197
+ a = self.parent().indices()([a])
1198
+ M = Matrix([alpha(c) if c in C else tuple(ZZ(c == q) for q in P)
1199
+ for c in (p + a for p in P)])
1200
+ mu_prime.append(M)
1201
+
1202
+ left_prime = vector([ZZ.one()] + (len(P) - 1) * [ZZ.zero()])
1203
+ right_prime = vector(self.coefficient_of_word(p) for p in P)
1204
+
1205
+ P = self.parent()
1206
+ return P.element_class(P, mu_prime, left_prime, right_prime)
1207
+
1208
+ def dimension(self):
1209
+ r"""
1210
+ Return the dimension of this recognizable series.
1211
+
1212
+ EXAMPLES::
1213
+
1214
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1215
+ sage: Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])),
1216
+ ....: left=vector([0, 1]), right=vector([1, 0])).dimension()
1217
+ 2
1218
+ """
1219
+ return self.mu.first().nrows()
1220
+
1221
+ @minimize_result
1222
+ def _add_(self, other):
1223
+ r"""
1224
+ Return the sum of this recognizable series and the ``other``
1225
+ recognizable series.
1226
+
1227
+ INPUT:
1228
+
1229
+ - ``other`` -- a :class:`RecognizableSeries` with the same parent
1230
+ as this recognizable series
1231
+
1232
+ - ``minimize`` -- (default: ``None``) a boolean or ``None``.
1233
+ If ``True``, then :meth:`minimized` is called after the operation,
1234
+ if ``False``, then not. If this argument is ``None``, then
1235
+ the default specified by the parent's ``minimize_results`` is used.
1236
+
1237
+ OUTPUT: a :class:`RecognizableSeries`
1238
+
1239
+ EXAMPLES::
1240
+
1241
+ sage: Seq2 = RegularSequenceRing(2, ZZ)
1242
+ sage: E = Seq2((Matrix([[0, 1], [0, 1]]), Matrix([[0, 0], [0, 1]])),
1243
+ ....: vector([1, 0]), vector([1, 1]))
1244
+ sage: E
1245
+ 2-regular sequence 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, ...
1246
+ sage: O = Seq2((Matrix([[0, 0], [0, 1]]), Matrix([[0, 1], [0, 1]])),
1247
+ ....: vector([1, 0]), vector([0, 1]))
1248
+ sage: O
1249
+ 2-regular sequence 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, ...
1250
+ sage: I = E + O # indirect doctest
1251
+ sage: I
1252
+ 2-regular sequence 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
1253
+ sage: I.linear_representation()
1254
+ ((1),
1255
+ Finite family {0: [1],
1256
+ 1: [1]},
1257
+ (1))
1258
+ """
1259
+ from sage.modules.free_module_element import vector
1260
+ P = self.parent()
1261
+
1262
+ result = P.element_class(
1263
+ P,
1264
+ {a: self.mu[a].block_sum(other.mu[a]) for a in P.alphabet()},
1265
+ vector(tuple(self.left) + tuple(other.left)),
1266
+ vector(tuple(self.right) + tuple(other.right)))
1267
+
1268
+ return result
1269
+
1270
+ def _neg_(self):
1271
+ r"""
1272
+ Return the additive inverse of this recognizable series.
1273
+
1274
+ OUTPUT: a :class:`RecognizableSeries`
1275
+
1276
+ EXAMPLES::
1277
+
1278
+ sage: Seq2 = RegularSequenceRing(2, ZZ)
1279
+ sage: E = Seq2((Matrix([[0, 1], [0, 1]]), Matrix([[0, 0], [0, 1]])),
1280
+ ....: vector([1, 0]), vector([1, 1]))
1281
+ sage: -E
1282
+ 2-regular sequence -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, ...
1283
+ sage: Z = E - E
1284
+ sage: Z.is_trivial_zero()
1285
+ True
1286
+ """
1287
+ P = self.parent()
1288
+ return P.element_class(P, self.mu, -self.left, self.right)
1289
+
1290
+ def _rmul_(self, other):
1291
+ r"""
1292
+ Multiply this recognizable series from the right
1293
+ by an element ``other`` of its coefficient (semi-)ring.
1294
+
1295
+ INPUT:
1296
+
1297
+ - ``other`` -- an element of the coefficient (semi-)ring
1298
+
1299
+ OUTPUT: a :class:`RecognizableSeries`
1300
+
1301
+ EXAMPLES::
1302
+
1303
+ sage: Seq2 = RegularSequenceRing(2, ZZ)
1304
+ sage: E = Seq2((Matrix([[0, 1], [0, 1]]), Matrix([[0, 0], [0, 1]])),
1305
+ ....: vector([1, 0]), vector([1, 1]))
1306
+ sage: M = 2 * E # indirect doctest
1307
+ sage: M
1308
+ 2-regular sequence 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, ...
1309
+ sage: M.linear_representation()
1310
+ ((2, 0),
1311
+ Finite family {0: [0 1]
1312
+ [0 1],
1313
+ 1: [0 0]
1314
+ [0 1]},
1315
+ (1, 1))
1316
+
1317
+ TESTS::
1318
+
1319
+ sage: 1 * E is E
1320
+ True
1321
+
1322
+ ::
1323
+
1324
+ sage: 0 * E is Seq2.zero()
1325
+ True
1326
+
1327
+ We test that ``_rmul_`` and ``_lmul_`` are actually called::
1328
+
1329
+ sage: def print_name(f):
1330
+ ....: def f_with_printed_name(*args, **kwds):
1331
+ ....: print(f.__name__)
1332
+ ....: return f(*args, **kwds)
1333
+ ....: return f_with_printed_name
1334
+
1335
+ sage: E._rmul_ = print_name(E._rmul_)
1336
+ sage: E._lmul_ = print_name(E._lmul_)
1337
+ sage: 2 * E
1338
+ _rmul_
1339
+ 2-regular sequence 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, ...
1340
+ sage: E * 2
1341
+ _lmul_
1342
+ _lmul_
1343
+ 2-regular sequence 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, ...
1344
+ """
1345
+ P = self.parent()
1346
+ if other.is_zero():
1347
+ return P._zero_()
1348
+ if other.is_one():
1349
+ return self
1350
+ return P.element_class(P, self.mu, other * self.left, self.right)
1351
+
1352
+ def _lmul_(self, other):
1353
+ r"""
1354
+ Multiply this recognizable series from the left
1355
+ by an element ``other`` of its coefficient (semi-)ring.
1356
+
1357
+ INPUT:
1358
+
1359
+ - ``other`` -- an element of the coefficient (semi-)ring
1360
+
1361
+ OUTPUT: a :class:`RecognizableSeries`
1362
+
1363
+ EXAMPLES::
1364
+
1365
+ sage: Seq2 = RegularSequenceRing(2, ZZ)
1366
+ sage: E = Seq2((Matrix([[0, 1], [0, 1]]), Matrix([[0, 0], [0, 1]])),
1367
+ ....: vector([1, 0]), vector([1, 1]))
1368
+ sage: M = E * 2 # indirect doctest
1369
+ sage: M
1370
+ 2-regular sequence 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, ...
1371
+ sage: M.linear_representation()
1372
+ ((1, 0),
1373
+ Finite family {0: [0 1]
1374
+ [0 1],
1375
+ 1: [0 0]
1376
+ [0 1]},
1377
+ (2, 2))
1378
+
1379
+ TESTS::
1380
+
1381
+ sage: E * 1 is E
1382
+ True
1383
+
1384
+ ::
1385
+
1386
+ sage: E * 0 is Seq2.zero()
1387
+ True
1388
+
1389
+ The following is not tested, as `MS^i` for integers `i` does
1390
+ not work, thus ``vector([m])`` fails. (See :issue:`21317` for
1391
+ details.)
1392
+
1393
+ ::
1394
+
1395
+ sage: MS = MatrixSpace(ZZ,2,2)
1396
+ sage: Rec = RecognizableSeriesSpace(MS, [0, 1])
1397
+ sage: m = MS.an_element()
1398
+ sage: S = Rec((Matrix([[m]]), Matrix([[m]])), # not tested
1399
+ ....: vector([m]), vector([m]))
1400
+ sage: S # not tested
1401
+ sage: M = m * S # not tested indirect doctest
1402
+ sage: M # not tested
1403
+ sage: M.linear_representation() # not tested
1404
+ """
1405
+ P = self.parent()
1406
+ if other.is_zero():
1407
+ return P._zero_()
1408
+ if other.is_one():
1409
+ return self
1410
+ return P.element_class(P, self.mu, self.left, self.right * other)
1411
+
1412
+ @minimize_result
1413
+ def hadamard_product(self, other):
1414
+ r"""
1415
+ Return the Hadamard product of this recognizable series
1416
+ and the ``other`` recognizable series, i.e., multiply the two
1417
+ series coefficient-wise.
1418
+
1419
+ INPUT:
1420
+
1421
+ - ``other`` -- a :class:`RecognizableSeries` with the same parent
1422
+ as this recognizable series
1423
+
1424
+ - ``minimize`` -- (default: ``None``) a boolean or ``None``.
1425
+ If ``True``, then :meth:`minimized` is called after the operation,
1426
+ if ``False``, then not. If this argument is ``None``, then
1427
+ the default specified by the parent's ``minimize_results`` is used.
1428
+
1429
+ OUTPUT: a :class:`RecognizableSeries`
1430
+
1431
+ EXAMPLES::
1432
+
1433
+ sage: Seq2 = RegularSequenceRing(2, ZZ)
1434
+
1435
+ sage: E = Seq2((Matrix([[0, 1], [0, 1]]), Matrix([[0, 0], [0, 1]])),
1436
+ ....: vector([1, 0]), vector([1, 1]))
1437
+ sage: E
1438
+ 2-regular sequence 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, ...
1439
+
1440
+ sage: O = Seq2((Matrix([[0, 0], [0, 1]]), Matrix([[0, 1], [0, 1]])),
1441
+ ....: vector([1, 0]), vector([0, 1]))
1442
+ sage: O
1443
+ 2-regular sequence 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, ...
1444
+
1445
+ sage: C = Seq2((Matrix([[2, 0], [2, 1]]), Matrix([[0, 1], [-2, 3]])),
1446
+ ....: vector([1, 0]), vector([0, 1]))
1447
+ sage: C
1448
+ 2-regular sequence 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...
1449
+
1450
+ ::
1451
+
1452
+ sage: CE = C.hadamard_product(E)
1453
+ sage: CE
1454
+ 2-regular sequence 0, 0, 2, 0, 4, 0, 6, 0, 8, 0, ...
1455
+ sage: CE.linear_representation()
1456
+ ((1, 0, 0),
1457
+ Finite family {0: [0 1 0]
1458
+ [0 2 0]
1459
+ [0 2 1],
1460
+ 1: [ 0 0 0]
1461
+ [ 0 0 1]
1462
+ [ 0 -2 3]},
1463
+ (0, 0, 2))
1464
+
1465
+ sage: Z = E.hadamard_product(O)
1466
+ sage: Z
1467
+ 2-regular sequence 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
1468
+ sage: Z.linear_representation()
1469
+ ((),
1470
+ Finite family {0: [],
1471
+ 1: []},
1472
+ ())
1473
+
1474
+ TESTS::
1475
+
1476
+ sage: EC = E.hadamard_product(C, minimize=False)
1477
+ sage: EC
1478
+ 2-regular sequence 0, 0, 2, 0, 4, 0, 6, 0, 8, 0, ...
1479
+ sage: EC.linear_representation()
1480
+ ((1, 0, 0, 0),
1481
+ Finite family {0: [0 0 2 0]
1482
+ [0 0 2 1]
1483
+ [0 0 2 0]
1484
+ [0 0 2 1],
1485
+ 1: [ 0 0 0 0]
1486
+ [ 0 0 0 0]
1487
+ [ 0 0 0 1]
1488
+ [ 0 0 -2 3]},
1489
+ (0, 1, 0, 1))
1490
+ sage: MEC = EC.minimized()
1491
+ sage: MEC
1492
+ 2-regular sequence 0, 0, 2, 0, 4, 0, 6, 0, 8, 0, ...
1493
+ sage: MEC.linear_representation()
1494
+ ((1, 0, 0),
1495
+ Finite family {0: [0 1 0]
1496
+ [0 2 0]
1497
+ [0 2 1],
1498
+ 1: [ 0 0 0]
1499
+ [ 0 0 1]
1500
+ [ 0 -2 3]},
1501
+ (0, 0, 2))
1502
+ """
1503
+ from sage.matrix.constructor import Matrix
1504
+ from sage.modules.free_module_element import vector
1505
+ P = self.parent()
1506
+
1507
+ def tensor_product(left, right):
1508
+ T = left.tensor_product(right)
1509
+ T.subdivide()
1510
+ return T
1511
+ result = P.element_class(
1512
+ P,
1513
+ {a: tensor_product(self.mu[a], other.mu[a]) for a in P.alphabet()},
1514
+ vector(tensor_product(Matrix(self.left), Matrix(other.left))),
1515
+ vector(tensor_product(Matrix(self.right), Matrix(other.right))))
1516
+
1517
+ return result
1518
+
1519
+
1520
+ def _pickle_RecognizableSeriesSpace(coefficients, indices, category):
1521
+ r"""
1522
+ Pickle helper.
1523
+
1524
+ TESTS::
1525
+
1526
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1527
+ sage: from sage.combinat.recognizable_series import _pickle_RecognizableSeriesSpace
1528
+ sage: _pickle_RecognizableSeriesSpace(
1529
+ ....: Rec.coefficient_ring(), Rec.indices(), Rec.category())
1530
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1531
+ """
1532
+ return RecognizableSeriesSpace(coefficients, indices=indices, category=category)
1533
+
1534
+
1535
+ class RecognizableSeriesSpace(UniqueRepresentation, Parent):
1536
+ r"""
1537
+ The space of recognizable series on the given alphabet and
1538
+ with the given coefficients.
1539
+
1540
+ INPUT:
1541
+
1542
+ - ``coefficient_ring`` -- a (semi-)ring
1543
+
1544
+ - ``alphabet`` -- tuple, list or
1545
+ :class:`~sage.sets.totally_ordered_finite_set.TotallyOrderedFiniteSet`.
1546
+ If specified, then the ``indices`` are the
1547
+ finite words over this ``alphabet``.
1548
+ ``alphabet`` and ``indices`` cannot be specified
1549
+ at the same time.
1550
+
1551
+ - ``indices`` -- a SageMath-parent of finite words over an alphabet.
1552
+ ``alphabet`` and ``indices`` cannot be specified
1553
+ at the same time.
1554
+
1555
+ - ``category`` -- (default: ``None``) the category of this
1556
+ space
1557
+
1558
+ EXAMPLES:
1559
+
1560
+ We create a recognizable series that counts the number of ones in each word::
1561
+
1562
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1563
+ sage: Rec
1564
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1565
+ sage: Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 1], [0, 1]])),
1566
+ ....: vector([1, 0]), vector([0, 1]))
1567
+ [1] + [01] + [10] + 2*[11] + [001] + [010] + 2*[011] + [100] + 2*[101] + 2*[110] + ...
1568
+
1569
+ All of the following examples create the same space::
1570
+
1571
+ sage: Rec1 = RecognizableSeriesSpace(ZZ, [0, 1])
1572
+ sage: Rec1
1573
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1574
+ sage: Rec2 = RecognizableSeriesSpace(coefficient_ring=ZZ, alphabet=[0, 1])
1575
+ sage: Rec2
1576
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1577
+ sage: Rec3 = RecognizableSeriesSpace(ZZ, indices=Words([0, 1], infinite=False))
1578
+ sage: Rec3
1579
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1580
+
1581
+ .. SEEALSO::
1582
+
1583
+ :doc:`recognizable series <recognizable_series>`,
1584
+ :class:`RecognizableSeries`.
1585
+ """
1586
+ Element = RecognizableSeries
1587
+
1588
+ @staticmethod
1589
+ def __classcall__(cls, *args, **kwds):
1590
+ r"""
1591
+ Prepare normalizing the input in order to ensure a
1592
+ unique representation.
1593
+
1594
+ For more information see :class:`RecognizableSeriesSpace`
1595
+ and :meth:`__normalize__`.
1596
+
1597
+ TESTS::
1598
+
1599
+ sage: Rec1 = RecognizableSeriesSpace(ZZ, [0, 1])
1600
+ sage: Rec1
1601
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1602
+ sage: Rec2 = RecognizableSeriesSpace(coefficient_ring=ZZ, alphabet=[0, 1])
1603
+ sage: Rec2
1604
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1605
+ sage: Rec3 = RecognizableSeriesSpace(ZZ, indices=Words([0, 1], infinite=False))
1606
+ sage: Rec3
1607
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1608
+ sage: Rec1 is Rec2 is Rec3
1609
+ True
1610
+ """
1611
+ return super().__classcall__(
1612
+ cls, *cls.__normalize__(*args, **kwds))
1613
+
1614
+ @classmethod
1615
+ def __normalize__(cls,
1616
+ coefficient_ring=None,
1617
+ alphabet=None, indices=None,
1618
+ category=None,
1619
+ minimize_results=True):
1620
+ r"""
1621
+ Normalize the input in order to ensure a unique
1622
+ representation.
1623
+
1624
+ For more information see :class:`RecognizableSeriesSpace`.
1625
+
1626
+ TESTS::
1627
+
1628
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) # indirect doctest
1629
+ sage: Rec.category()
1630
+ Category of modules over Integer Ring
1631
+ sage: RecognizableSeriesSpace([0, 1], [0, 1])
1632
+ Traceback (most recent call last):
1633
+ ...
1634
+ ValueError: coefficient ring [0, 1] is not a semiring
1635
+
1636
+ ::
1637
+
1638
+ sage: W = Words([0, 1], infinite=False)
1639
+ sage: RecognizableSeriesSpace(ZZ)
1640
+ Traceback (most recent call last):
1641
+ ...
1642
+ ValueError: specify either 'alphabet' or 'indices'
1643
+ sage: RecognizableSeriesSpace(ZZ, alphabet=[0, 1], indices=W)
1644
+ Traceback (most recent call last):
1645
+ ...
1646
+ ValueError: specify either 'alphabet' or 'indices'
1647
+ sage: RecognizableSeriesSpace(alphabet=[0, 1])
1648
+ Traceback (most recent call last):
1649
+ ...
1650
+ ValueError: no coefficient ring specified
1651
+ sage: RecognizableSeriesSpace(ZZ, indices=Words(ZZ))
1652
+ Traceback (most recent call last):
1653
+ ...
1654
+ NotImplementedError: alphabet is not finite
1655
+ """
1656
+ if (alphabet is None) == (indices is None):
1657
+ raise ValueError("specify either 'alphabet' or 'indices'")
1658
+
1659
+ if indices is None:
1660
+ from sage.combinat.words.words import Words
1661
+ indices = Words(alphabet, infinite=False)
1662
+ if not indices.alphabet().is_finite():
1663
+ raise NotImplementedError('alphabet is not finite')
1664
+
1665
+ if coefficient_ring is None:
1666
+ raise ValueError('no coefficient ring specified')
1667
+ from sage.categories.semirings import Semirings
1668
+ if coefficient_ring not in Semirings():
1669
+ raise ValueError(
1670
+ 'coefficient ring {} is not a semiring'.format(coefficient_ring))
1671
+
1672
+ from sage.categories.modules import Modules
1673
+ category = category or Modules(coefficient_ring)
1674
+
1675
+ return (coefficient_ring, indices, category, minimize_results)
1676
+
1677
+ def __init__(self, coefficient_ring, indices, category, minimize_results):
1678
+ r"""
1679
+ See :class:`RecognizableSeriesSpace` for details.
1680
+
1681
+ INPUT:
1682
+
1683
+ - ``coefficients`` -- a (semi-)ring
1684
+
1685
+ - ``indices`` -- a SageMath-parent of finite words over an alphabet
1686
+
1687
+ - ``category`` -- (default: ``None``) the category of this
1688
+ space
1689
+
1690
+ - ``minimize_results`` -- boolean (default: ``True``); if set, then
1691
+ :meth:`RecognizableSeries.minimized` is automatically called
1692
+ after performing operations.
1693
+
1694
+ TESTS::
1695
+
1696
+ sage: RecognizableSeriesSpace(ZZ, [0, 1])
1697
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1698
+
1699
+ ::
1700
+
1701
+ sage: from itertools import islice
1702
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1703
+ sage: TestSuite(Rec).run( # long time
1704
+ ....: verbose=True,
1705
+ ....: elements=tuple(islice(Rec.some_elements(), 4)))
1706
+ running ._test_additive_associativity() . . . pass
1707
+ running ._test_an_element() . . . pass
1708
+ running ._test_cardinality() . . . pass
1709
+ running ._test_category() . . . pass
1710
+ running ._test_construction() . . . pass
1711
+ running ._test_elements() . . .
1712
+ Running the test suite of self.an_element()
1713
+ running ._test_category() . . . pass
1714
+ running ._test_eq() . . . pass
1715
+ running ._test_new() . . . pass
1716
+ running ._test_nonzero_equal() . . . pass
1717
+ running ._test_not_implemented_methods() . . . pass
1718
+ running ._test_pickling() . . . pass
1719
+ pass
1720
+ running ._test_elements_eq_reflexive() . . . pass
1721
+ running ._test_elements_eq_symmetric() . . . pass
1722
+ running ._test_elements_eq_transitive() . . . pass
1723
+ running ._test_elements_neq() . . . pass
1724
+ running ._test_eq() . . . pass
1725
+ running ._test_new() . . . pass
1726
+ running ._test_not_implemented_methods() . . . pass
1727
+ running ._test_pickling() . . . pass
1728
+ running ._test_some_elements() . . . pass
1729
+ running ._test_zero() . . . pass
1730
+ """
1731
+ self._indices_ = indices
1732
+ self._minimize_results_ = minimize_results
1733
+ super().__init__(
1734
+ category=category, base=coefficient_ring)
1735
+
1736
+ def __reduce__(self):
1737
+ r"""
1738
+ Pickling support.
1739
+
1740
+ TESTS::
1741
+
1742
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1743
+ sage: loads(dumps(Rec)) # indirect doctest
1744
+ Space of recognizable series on {0, 1} with coefficients in Integer Ring
1745
+ """
1746
+ return _pickle_RecognizableSeriesSpace, \
1747
+ (self.coefficient_ring(), self.indices(), self.category())
1748
+
1749
+ def alphabet(self):
1750
+ r"""
1751
+ Return the alphabet of this recognizable series space.
1752
+
1753
+ OUTPUT: a totally ordered set
1754
+
1755
+ EXAMPLES::
1756
+
1757
+ sage: RecognizableSeriesSpace(ZZ, [0, 1]).alphabet()
1758
+ {0, 1}
1759
+
1760
+ TESTS::
1761
+
1762
+ sage: type(RecognizableSeriesSpace(ZZ, [0, 1]).alphabet())
1763
+ <class 'sage.sets.totally_ordered_finite_set.TotallyOrderedFiniteSet_with_category'>
1764
+ """
1765
+ return self.indices().alphabet()
1766
+
1767
+ def indices(self):
1768
+ r"""
1769
+ Return the indices of the recognizable series.
1770
+
1771
+ OUTPUT: the set of finite words over the alphabet
1772
+
1773
+ EXAMPLES::
1774
+
1775
+ sage: RecognizableSeriesSpace(ZZ, [0, 1]).indices()
1776
+ Finite words over {0, 1}
1777
+ """
1778
+ return self._indices_
1779
+
1780
+ def coefficient_ring(self):
1781
+ r"""
1782
+ Return the coefficients of this recognizable series space.
1783
+
1784
+ OUTPUT:
1785
+
1786
+ A (semi-)ring
1787
+
1788
+ EXAMPLES::
1789
+
1790
+ sage: RecognizableSeriesSpace(ZZ, [0, 1]).coefficient_ring()
1791
+ Integer Ring
1792
+ """
1793
+ return self.base()
1794
+
1795
+ @property
1796
+ def minimize_results(self):
1797
+ r"""
1798
+ A boolean indicating whether
1799
+ :meth:`RecognizableSeries.minimized` is automatically called
1800
+ after performing operations.
1801
+
1802
+ TESTS::
1803
+
1804
+ sage: RecognizableSeriesSpace(ZZ, [0, 1]).minimize_results
1805
+ True
1806
+ sage: RecognizableSeriesSpace(ZZ, [0, 1], minimize_results=True).minimize_results
1807
+ True
1808
+ sage: RecognizableSeriesSpace(ZZ, [0, 1], minimize_results=False).minimize_results
1809
+ False
1810
+ """
1811
+ return self._minimize_results_
1812
+
1813
+ def _repr_(self):
1814
+ r"""
1815
+ Return a representation string of this recognizable sequence
1816
+ space.
1817
+
1818
+ OUTPUT: string
1819
+
1820
+ TESTS::
1821
+
1822
+ sage: repr(RecognizableSeriesSpace(ZZ, [0, 1])) # indirect doctest
1823
+ 'Space of recognizable series on {0, 1} with coefficients in Integer Ring'
1824
+ """
1825
+ return 'Space of recognizable series on {} ' \
1826
+ 'with coefficients in {}'.format(self.alphabet(),
1827
+ self.coefficient_ring())
1828
+
1829
+ def _an_element_(self):
1830
+ r"""
1831
+ Return an element of this recognizable series space.
1832
+
1833
+ OUTPUT: a :class:`RecognizableSeries`
1834
+
1835
+ EXAMPLES::
1836
+
1837
+ sage: RecognizableSeriesSpace(ZZ, [0, 1]).an_element() # indirect doctest
1838
+ [1] + [01] + [10] + 2*[11] + [001] + [010]
1839
+ + 2*[011] + [100] + 2*[101] + 2*[110] + ...
1840
+ """
1841
+ from sage.matrix.constructor import Matrix
1842
+ from sage.modules.free_module_element import vector
1843
+ z = self.coefficient_ring().zero()
1844
+ o = self.coefficient_ring().one()
1845
+ e = self.coefficient_ring().an_element()
1846
+ return self(list(Matrix([[o, z], [i * o, o]])
1847
+ for i, _ in enumerate(self.alphabet())),
1848
+ vector([z, e]), right=vector([e, z]))
1849
+
1850
+ def some_elements(self, **kwds):
1851
+ r"""
1852
+ Return some elements of this recognizable series space.
1853
+
1854
+ See :class:`TestSuite` for a typical use case.
1855
+
1856
+ INPUT:
1857
+
1858
+ - ``kwds`` are passed on to the element constructor
1859
+
1860
+ OUTPUT: an iterator
1861
+
1862
+ EXAMPLES::
1863
+
1864
+ sage: tuple(RecognizableSeriesSpace(ZZ, [0, 1]).some_elements())
1865
+ ([1] + [01] + [10] + 2*[11] + [001] + [010]
1866
+ + 2*[011] + [100] + 2*[101] + 2*[110] + ...,
1867
+ [] + [1] + [11] + [111] + [1111] + [11111] + [111111] + ...,
1868
+ [] + [0] + [1] + [00] + [10] + [11]
1869
+ + [000] - 1*[001] + [100] + [110] + ...,
1870
+ 2*[] - 1*[1] + 2*[10] - 1*[101]
1871
+ + 2*[1010] - 1*[10101] + 2*[101010] + ...,
1872
+ [] + [1] + 6*[00] + [11] - 39*[000] + 5*[001] + 6*[100] + [111]
1873
+ + 288*[0000] - 33*[0001] + ...,
1874
+ -5*[] + ...,
1875
+ ...
1876
+ 210*[] + ...,
1877
+ 2210*[] - 170*[0] + 170*[1] + ...)
1878
+ """
1879
+ from itertools import islice
1880
+ from sage.matrix.matrix_space import MatrixSpace
1881
+ from sage.modules.free_module import FreeModule
1882
+ yield self.an_element()
1883
+
1884
+ C = self.coefficient_ring()
1885
+ k = len(self.alphabet())
1886
+ for dim in range(1, 11):
1887
+ elements_M = MatrixSpace(C, dim).some_elements()
1888
+ elements_V = FreeModule(C, dim).some_elements()
1889
+ for _ in range(3):
1890
+ mu = list(islice(elements_M, k))
1891
+ LR = list(islice(elements_V, 2))
1892
+ if len(mu) != k or len(LR) != 2:
1893
+ break
1894
+ yield self(mu, *LR, **kwds)
1895
+
1896
+ @cached_method
1897
+ def _zero_(self):
1898
+ r"""
1899
+ Return the zero element of this :class:`RecognizableSeriesSpace`,
1900
+ i.e. the unique neutral element for `+`.
1901
+
1902
+ TESTS::
1903
+
1904
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1905
+ sage: Z = Rec._zero_(); Z
1906
+ 0
1907
+ sage: Z.linear_representation()
1908
+ ((), Finite family {0: [], 1: []}, ())
1909
+ """
1910
+ from sage.matrix.constructor import Matrix
1911
+ from sage.modules.free_module_element import vector
1912
+ from sage.sets.family import Family
1913
+
1914
+ return self.element_class(
1915
+ self, Family(self.alphabet(), lambda a: Matrix()),
1916
+ vector([]), vector([]))
1917
+
1918
+ @cached_method
1919
+ def one(self):
1920
+ r"""
1921
+ Return the one element of this :class:`RecognizableSeriesSpace`,
1922
+ i.e. the embedding of the one of the coefficient ring into
1923
+ this :class:`RecognizableSeriesSpace`.
1924
+
1925
+ EXAMPLES::
1926
+
1927
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1928
+ sage: O = Rec.one(); O
1929
+ [] + ...
1930
+ sage: O.linear_representation()
1931
+ ((1), Finite family {0: [0], 1: [0]}, (1))
1932
+
1933
+ TESTS::
1934
+
1935
+ sage: Rec.one() is Rec.one()
1936
+ True
1937
+ """
1938
+ from sage.matrix.constructor import Matrix
1939
+ from sage.modules.free_module_element import vector
1940
+
1941
+ R = self.coefficient_ring()
1942
+ one = R.one()
1943
+ zero = R.zero()
1944
+ return self.element_class(self,
1945
+ len(self.alphabet())*[Matrix([[zero]])],
1946
+ vector([one]),
1947
+ vector([one]))
1948
+
1949
+ @cached_method
1950
+ def one_hadamard(self):
1951
+ r"""
1952
+ Return the identity with respect to the
1953
+ :meth:`~RecognizableSeries.hadamard_product`, i.e. the
1954
+ coefficient-wise multiplication.
1955
+
1956
+ OUTPUT: a :class:`RecognizableSeries`
1957
+
1958
+ EXAMPLES::
1959
+
1960
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1961
+ sage: Rec.one_hadamard()
1962
+ [] + [0] + [1] + [00] + [01] + [10]
1963
+ + [11] + [000] + [001] + [010] + ...
1964
+
1965
+ TESTS::
1966
+
1967
+ sage: Rec.one_hadamard() is Rec.one_hadamard()
1968
+ True
1969
+ """
1970
+ from sage.matrix.constructor import Matrix
1971
+ from sage.modules.free_module_element import vector
1972
+
1973
+ one = self.coefficient_ring()(1)
1974
+ return self({a: Matrix([[one]]) for a in self.alphabet()},
1975
+ vector([one]), vector([one]))
1976
+
1977
+ def _element_constructor_(self, data,
1978
+ left=None, right=None):
1979
+ r"""
1980
+ Return a recognizable series.
1981
+
1982
+ See :class:`RecognizableSeriesSpace` for details.
1983
+
1984
+ TESTS::
1985
+
1986
+ sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1])
1987
+
1988
+ sage: Rec.zero()
1989
+ 0
1990
+ sage: type(_)
1991
+ <class 'sage.combinat.recognizable_series.RecognizableSeriesSpace_with_category.element_class'>
1992
+
1993
+ ::
1994
+
1995
+ sage: M0 = Matrix([[1, 0], [0, 1]])
1996
+ sage: M1 = Matrix([[0, -1], [1, 2]])
1997
+ sage: S = Rec((M0, M1), vector([0, 1]), vector([1, 1]))
1998
+ sage: Rec(S) is S
1999
+ True
2000
+
2001
+ ::
2002
+
2003
+ sage: A = Rec(42); A
2004
+ 42*[] + ...
2005
+ sage: A.linear_representation()
2006
+ ((42), Finite family {0: [0], 1: [0]}, (1))
2007
+ sage: Z = Rec(0); Z
2008
+ 0
2009
+ sage: Z.linear_representation()
2010
+ ((), Finite family {0: [], 1: []}, ())
2011
+
2012
+ ::
2013
+
2014
+ sage: Rec((M0, M1))
2015
+ Traceback (most recent call last):
2016
+ ...
2017
+ ValueError: left or right vector is None
2018
+ sage: Rec((M0, M1), [0, 1])
2019
+ Traceback (most recent call last):
2020
+ ...
2021
+ ValueError: left or right vector is None
2022
+ sage: Rec((M0, M1), left=[0, 1])
2023
+ Traceback (most recent call last):
2024
+ ...
2025
+ ValueError: left or right vector is None
2026
+ sage: Rec((M0, M1), right=[0, 1])
2027
+ Traceback (most recent call last):
2028
+ ...
2029
+ ValueError: left or right vector is None
2030
+ """
2031
+ if isinstance(data, int) and data == 0:
2032
+ return self._zero_()
2033
+
2034
+ if isinstance(data, self.element_class) and data.parent() == self:
2035
+ element = data
2036
+
2037
+ elif isinstance(data, RecognizableSeries):
2038
+ element = self.element_class(self, data.mu, data.left, data.right)
2039
+
2040
+ elif data in self.coefficient_ring():
2041
+ c = self.coefficient_ring()(data)
2042
+ return c * self.one()
2043
+
2044
+ else:
2045
+ mu = data
2046
+ if left is None or right is None:
2047
+ raise ValueError('left or right vector is None')
2048
+
2049
+ element = self.element_class(self, mu, left, right)
2050
+
2051
+ return element