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,1623 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.modules sage.plot
3
+ r"""
4
+ Substitutions over unit cube faces (Rauzy fractals)
5
+
6
+ This module implements the `E_1^*(\sigma)` substitution
7
+ associated with a one-dimensional substitution `\sigma`,
8
+ that acts on unit faces of dimension `(d-1)` in `\RR^d`.
9
+
10
+ This module defines the following classes and functions:
11
+
12
+ - ``Face`` -- a class to model a face
13
+
14
+ - ``Patch`` -- a class to model a finite set of faces
15
+
16
+ - ``E1Star`` -- a class to model the `E_1^*(\sigma)` application
17
+ defined by the substitution sigma
18
+
19
+ See the documentation of these objects for more information.
20
+
21
+ The convention for the choice of the unit faces and the
22
+ definition of `E_1^*(\sigma)` varies from article to article.
23
+ Here, unit faces are defined by
24
+
25
+ .. MATH::
26
+
27
+ \begin{array}{ccc}
28
+ \,[x, 1]^* & = & \{x + \lambda e_2 + \mu e_3 : \lambda, \mu \in [0,1]\} \\
29
+ \,[x, 2]^* & = & \{x + \lambda e_1 + \mu e_3 : \lambda, \mu \in [0,1]\} \\
30
+ \,[x, 3]^* & = & \{x + \lambda e_1 + \mu e_2 : \lambda, \mu \in [0,1]\}
31
+ \end{array}
32
+
33
+ and the dual substitution `E_1^*(\sigma)` is defined by
34
+
35
+ .. MATH::
36
+
37
+ E_1^*(\sigma)([x,i]^*) =
38
+ \bigcup_{k = 1,2,3} \; \bigcup_{s | \sigma(k) = pis}
39
+ [M^{-1}(x + \ell(s)), k]^*,
40
+
41
+ where `\ell(s)` is the abelianized of `s`, and `M` is the matrix of `\sigma`.
42
+
43
+ AUTHORS:
44
+
45
+ - Franco Saliola (2009): initial version
46
+ - Vincent Delecroix, Timo Jolivet, Stepan Starosta, Sebastien Labbe (2010-05): redesign
47
+ - Timo Jolivet (2010-08, 2010-09, 2011): redesign
48
+
49
+ REFERENCES:
50
+
51
+ .. [AI] \P. Arnoux, S. Ito,
52
+ Pisot substitutions and Rauzy fractals,
53
+ Bull. Belg. Math. Soc. 8 (2), 2001, pp. 181--207
54
+
55
+ .. [SAI] \Y. Sano, P. Arnoux, S. Ito,
56
+ Higher dimensional extensions of substitutions and their dual maps,
57
+ J. Anal. Math. 83, 2001, pp. 183--206
58
+
59
+ EXAMPLES:
60
+
61
+ We start by drawing a simple three-face patch::
62
+
63
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
64
+ sage: x = [Face((0,0,0),1), Face((0,0,0),2), Face((0,0,0),3)]
65
+ sage: P = Patch(x)
66
+ sage: P
67
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
68
+ sage: P.plot() #not tested
69
+
70
+ We apply a substitution to this patch, and draw the result::
71
+
72
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
73
+ sage: E = E1Star(sigma)
74
+ sage: E(P)
75
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*, [(0, 1, -1), 2]*, [(1, 0, -1), 1]*]
76
+ sage: E(P).plot() #not tested
77
+
78
+ .. NOTE::
79
+
80
+ - The type of a face is given by an integer in ``[1, ..., d]``
81
+ where ``d`` is the length of the vector of the face.
82
+
83
+ - The alphabet of the domain and the codomain of `\sigma` must be
84
+ equal, and they must be of the form ``[1, ..., d]``, where ``d``
85
+ is a positive integer corresponding to the length of the vectors
86
+ of the faces on which `E_1^*(\sigma)` will act.
87
+
88
+ ::
89
+
90
+ sage: P = Patch([Face((0,0,0),1), Face((0,0,0),2), Face((0,0,0),3)])
91
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
92
+ sage: E = E1Star(sigma)
93
+ sage: E(P)
94
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*, [(0, 1, -1), 2]*, [(1, 0, -1), 1]*]
95
+
96
+ The application of an ``E1Star`` substitution assigns to each new face the color of its preimage.
97
+ The ``repaint`` method allows us to repaint the faces of a patch.
98
+ A single color can also be assigned to every face, by specifying a list of a single color::
99
+
100
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
101
+ sage: P = E(P, 5)
102
+ sage: P.repaint(['green'])
103
+ sage: P.plot() #not tested
104
+
105
+ A list of colors allows us to color the faces sequentially::
106
+
107
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
108
+ sage: P = E(P)
109
+ sage: P.repaint(['red', 'yellow', 'green', 'blue', 'black'])
110
+ sage: P = E(P, 3)
111
+ sage: P.plot() #not tested
112
+
113
+ All the color schemes from ``list(matplotlib.cm.datad)`` can be used::
114
+
115
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
116
+ sage: P.repaint(cmap='summer')
117
+ sage: P = E(P, 3)
118
+ sage: P.plot() #not tested
119
+ sage: P.repaint(cmap='hsv')
120
+ sage: P = E(P, 2)
121
+ sage: P.plot() #not tested
122
+
123
+ It is also possible to specify a dictionary to color the faces according to their type::
124
+
125
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
126
+ sage: P = E(P, 5)
127
+ sage: P.repaint({1:(0.7, 0.7, 0.7), 2:(0.5,0.5,0.5), 3:(0.3,0.3,0.3)})
128
+ sage: P.plot() #not tested
129
+ sage: P.repaint({1:'red', 2:'yellow', 3:'green'})
130
+ sage: P.plot() #not tested
131
+
132
+ Let us look at a nice big patch in 3D::
133
+
134
+ sage: sigma = WordMorphism({1:[1,2], 2:[3], 3:[1]})
135
+ sage: E = E1Star(sigma)
136
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
137
+ sage: P = P + P.translate([-1,1,0])
138
+ sage: P = E(P, 11)
139
+ sage: P.plot3d() #not tested
140
+
141
+ Plotting with TikZ pictures is possible::
142
+
143
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
144
+ sage: s = P.plot_tikz()
145
+ sage: print(s) #not tested
146
+ \begin{tikzpicture}
147
+ [x={(-0.216506cm,-0.125000cm)}, y={(0.216506cm,-0.125000cm)}, z={(0.000000cm,0.250000cm)}]
148
+ \definecolor{facecolor}{rgb}{0.000,1.000,0.000}
149
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
150
+ (0, 0, 0) -- (0, 0, 1) -- (1, 0, 1) -- (1, 0, 0) -- cycle;
151
+ \definecolor{facecolor}{rgb}{1.000,0.000,0.000}
152
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
153
+ (0, 0, 0) -- (0, 1, 0) -- (0, 1, 1) -- (0, 0, 1) -- cycle;
154
+ \definecolor{facecolor}{rgb}{0.000,0.000,1.000}
155
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
156
+ (0, 0, 0) -- (1, 0, 0) -- (1, 1, 0) -- (0, 1, 0) -- cycle;
157
+ \end{tikzpicture}
158
+
159
+ Plotting patches made of unit segments instead of unit faces::
160
+
161
+ sage: P = Patch([Face([0,0], 1), Face([0,0], 2)])
162
+ sage: E = E1Star(WordMorphism({1:[1,2],2:[1]}))
163
+ sage: F = E1Star(WordMorphism({1:[1,1,2],2:[2,1]}))
164
+ sage: E(P,5).plot() # needs sage.plot
165
+ Graphics object consisting of 21 graphics primitives
166
+ sage: F(P,3).plot() # needs sage.plot
167
+ Graphics object consisting of 34 graphics primitives
168
+
169
+ Everything works in any dimension (except for the plotting features
170
+ which only work in dimension two or three)::
171
+
172
+ sage: P = Patch([Face((0,0,0,0),1), Face((0,0,0,0),4)])
173
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1,4], 4:[1]})
174
+ sage: E = E1Star(sigma)
175
+ sage: E(P)
176
+ Patch: [[(0, 0, 0, 0), 3]*, [(0, 0, 0, 0), 4]*, [(0, 0, 1, -1), 3]*, [(0, 1, 0, -1), 2]*, [(1, 0, 0, -1), 1]*]
177
+
178
+ ::
179
+
180
+ sage: sigma = WordMorphism({1:[1,2],2:[1,3],3:[1,4],4:[1,5],5:[1,6],6:[1,7],7:[1,8],8:[1,9],9:[1,10],10:[1,11],11:[1,12],12:[1]})
181
+ sage: E = E1Star(sigma)
182
+ sage: E
183
+ E_1^*(1->12, 10->1,11, 11->1,12, 12->1, 2->13, 3->14, 4->15, 5->16, 6->17, 7->18, 8->19, 9->1,10)
184
+ sage: P = Patch([Face((0,0,0,0,0,0,0,0,0,0,0,0),t) for t in [1,2,3]])
185
+ sage: for x in sorted(E(P), key=lambda x : (x.vector(),x.type())): print(x)
186
+ [(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 1]*
187
+ [(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 2]*
188
+ [(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 12]*
189
+ [(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1), 11]*
190
+ [(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1), 10]*
191
+ [(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1), 9]*
192
+ [(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1), 8]*
193
+ [(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1), 7]*
194
+ [(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1), 6]*
195
+ [(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1), 5]*
196
+ [(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1), 4]*
197
+ [(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1), 3]*
198
+ [(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), 2]*
199
+ [(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), 1]*
200
+ """
201
+ # ****************************************************************************
202
+ # Copyright (C) 2010 Franco Saliola <saliola@gmail.com>
203
+ # Vincent Delecroix <20100.delecroix@gmail.com>
204
+ # Timo Jolivet <timo.jolivet@gmail.com>
205
+ # Stepan Starosta <stepan.starosta@gmail.com>
206
+ # Sébastien Labbé <slabqc at gmail.com>
207
+ #
208
+ # Distributed under the terms of the GNU General Public License (GPL)
209
+ # as published by the Free Software Foundation; either version 2 of
210
+ # the License, or (at your option) any later version.
211
+ # https://www.gnu.org/licenses/
212
+ # ****************************************************************************
213
+ from __future__ import annotations
214
+
215
+ from sage.misc.functional import det
216
+ from sage.structure.sage_object import SageObject
217
+ from sage.combinat.words.morphism import WordMorphism
218
+ from sage.misc.lazy_import import lazy_import
219
+ lazy_import("sage.plot.all", "Graphics")
220
+ lazy_import("sage.plot.colors", "Color")
221
+ lazy_import("sage.plot.polygon", "polygon")
222
+ lazy_import("sage.plot.line", "line")
223
+ from sage.rings.integer_ring import ZZ
224
+ from sage.misc.latex import LatexExpr
225
+ from sage.misc.cachefunc import cached_method
226
+ from sage.structure.richcmp import richcmp_by_eq_and_lt, richcmp_method
227
+
228
+ lazy_import('sage.matrix.constructor', 'matrix')
229
+ lazy_import('sage.modules.free_module_element', 'vector')
230
+
231
+
232
+ # matplotlib color maps, loaded on-demand
233
+ cm = None
234
+
235
+
236
+ @richcmp_method
237
+ class Face(SageObject):
238
+ r"""
239
+ A class to model a unit face of arbitrary dimension.
240
+
241
+ A unit face in dimension `d` is represented by
242
+ a `d`-dimensional vector ``v`` and a type ``t`` in `\{1, \ldots, d\}`.
243
+ The type of the face corresponds to the canonical unit vector
244
+ to which the face is orthogonal.
245
+ The optional ``color`` argument is used in plotting functions.
246
+
247
+ INPUT:
248
+
249
+ - ``v`` -- tuple of integers
250
+ - ``t`` -- integer in ``[1, ..., len(v)]``, type of the face. The face of type `i`
251
+ is orthogonal to the canonical vector `e_i`.
252
+ - ``color`` -- color (default: ``None``); color of the face,
253
+ used for plotting only. If ``None``, its value is guessed from the
254
+ face type.
255
+
256
+ EXAMPLES::
257
+
258
+ sage: from sage.combinat.e_one_star import Face
259
+ sage: f = Face((0,2,0), 3)
260
+ sage: f.vector()
261
+ (0, 2, 0)
262
+ sage: f.type()
263
+ 3
264
+
265
+ ::
266
+
267
+ sage: f = Face((0,2,0), 3, color=(0.5, 0.5, 0.5))
268
+ sage: f.color()
269
+ RGB color (0.5, 0.5, 0.5)
270
+ """
271
+
272
+ def __init__(self, v, t, color=None):
273
+ r"""
274
+ Face constructor. See class doc for more information.
275
+
276
+ EXAMPLES::
277
+
278
+ sage: from sage.combinat.e_one_star import Face
279
+ sage: f = Face((0,2,0), 3)
280
+ sage: f.vector()
281
+ (0, 2, 0)
282
+ sage: f.type()
283
+ 3
284
+
285
+ TESTS:
286
+
287
+ We test that types can be given by an int (see :issue:`10699`)::
288
+
289
+ sage: f = Face((0,2,0), int(1))
290
+ """
291
+ self._vector = (ZZ**len(v))(v)
292
+ self._vector.set_immutable()
293
+
294
+ if not ((t in ZZ) and 1 <= t <= len(v)):
295
+ raise ValueError('the type must be an integer between 1 and len(v)')
296
+ self._type = t
297
+
298
+ if color is None:
299
+ if self._type == 1:
300
+ color = Color((1, 0, 0))
301
+ elif self._type == 2:
302
+ color = Color((0, 1, 0))
303
+ elif self._type == 3:
304
+ color = Color((0, 0, 1))
305
+ else:
306
+ color = Color()
307
+ self._color = Color(color)
308
+
309
+ def __repr__(self) -> str:
310
+ r"""
311
+ String representation of a face.
312
+
313
+ EXAMPLES::
314
+
315
+ sage: from sage.combinat.e_one_star import Face
316
+ sage: f = Face((0,0,0,3), 3)
317
+ sage: f
318
+ [(0, 0, 0, 3), 3]*
319
+
320
+ ::
321
+
322
+ sage: f = Face((0,0,0,3), 3)
323
+ sage: f
324
+ [(0, 0, 0, 3), 3]*
325
+ """
326
+ return "[%s, %s]*" % (self.vector(), self.type())
327
+
328
+ __richcmp__ = richcmp_by_eq_and_lt('_eq', '_lt')
329
+
330
+ def _eq(self, other) -> bool:
331
+ r"""
332
+ Equality of faces.
333
+
334
+ EXAMPLES::
335
+
336
+ sage: from sage.combinat.e_one_star import Face
337
+ sage: f = Face((0,0,0,3), 3)
338
+ sage: g = Face((0,0,0,3), 3)
339
+ sage: f == g
340
+ True
341
+ """
342
+ return (isinstance(other, Face) and
343
+ self.vector() == other.vector() and
344
+ self.type() == other.type())
345
+
346
+ def _lt(self, other) -> bool:
347
+ r"""
348
+ Compare ``self`` and ``other``.
349
+
350
+ The vectors of the faces are first compared,
351
+ and the types of the faces are compared if the vectors are equal.
352
+
353
+ EXAMPLES::
354
+
355
+ sage: from sage.combinat.e_one_star import Face
356
+ sage: Face([-2,1,0], 2) < Face([-1,2,2],3)
357
+ True
358
+ sage: Face([-2,1,0], 2) < Face([-2,1,0],3)
359
+ True
360
+ sage: Face([-2,1,0], 2) < Face([-2,1,0],2)
361
+ False
362
+ """
363
+ if self.vector() < other.vector():
364
+ return True
365
+ if self.vector() == other.vector():
366
+ return self.type() < other.type()
367
+ return False
368
+
369
+ def __hash__(self) -> int:
370
+ r"""
371
+ EXAMPLES::
372
+
373
+ sage: from sage.combinat.e_one_star import Face
374
+ sage: f = Face((0,0,0,3), 3)
375
+ sage: g = Face((0,0,0,3), 3)
376
+ sage: hash(f) == hash(g)
377
+ True
378
+ """
379
+ return hash((self.vector(), self.type()))
380
+
381
+ def __add__(self, other):
382
+ r"""
383
+ Addition of ``self`` with a Face, a Patch or a finite iterable of faces.
384
+
385
+ INPUT:
386
+
387
+ - ``other`` -- a Patch or a Face or a finite iterable of faces
388
+
389
+ EXAMPLES::
390
+
391
+ sage: from sage.combinat.e_one_star import Face, Patch
392
+ sage: f = Face([0,0,0], 3)
393
+ sage: g = Face([0,1,-1], 2)
394
+ sage: f + g
395
+ Patch: [[(0, 0, 0), 3]*, [(0, 1, -1), 2]*]
396
+ sage: P = Patch([Face([0,0,0], 1), Face([0,0,0], 2)])
397
+ sage: f + P
398
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
399
+
400
+ Adding a finite iterable of faces::
401
+
402
+ sage: from sage.combinat.e_one_star import Face
403
+ sage: f = Face([0,0,0], 3)
404
+ sage: f + [f,f]
405
+ Patch: [[(0, 0, 0), 3]*]
406
+ """
407
+ if isinstance(other, Face):
408
+ return Patch([self, other])
409
+ else:
410
+ return Patch(other).union(self)
411
+
412
+ def vector(self):
413
+ r"""
414
+ Return the vector of the face.
415
+
416
+ EXAMPLES::
417
+
418
+ sage: from sage.combinat.e_one_star import Face
419
+ sage: f = Face((0,2,0), 3)
420
+ sage: f.vector()
421
+ (0, 2, 0)
422
+ """
423
+ return self._vector
424
+
425
+ def type(self):
426
+ r"""
427
+ Return the type of the face.
428
+
429
+ EXAMPLES::
430
+
431
+ sage: from sage.combinat.e_one_star import Face
432
+ sage: f = Face((0,2,0), 3)
433
+ sage: f.type()
434
+ 3
435
+
436
+ ::
437
+
438
+ sage: f = Face((0,2,0), 3)
439
+ sage: f.type()
440
+ 3
441
+ """
442
+ return self._type
443
+
444
+ def color(self, color=None):
445
+ r"""
446
+ Return or change the color of the face.
447
+
448
+ INPUT:
449
+
450
+ - ``color`` -- string, rgb tuple, color (default: ``None``)
451
+ the new color to assign to the face. If ``None``, it returns the
452
+ color of the face.
453
+
454
+ OUTPUT: color or None
455
+
456
+ EXAMPLES::
457
+
458
+ sage: from sage.combinat.e_one_star import Face
459
+ sage: f = Face((0,2,0), 3)
460
+ sage: f.color()
461
+ RGB color (0.0, 0.0, 1.0)
462
+ sage: f.color('red')
463
+ sage: f.color()
464
+ RGB color (1.0, 0.0, 0.0)
465
+ """
466
+ if color is not None:
467
+ self._color = Color(color)
468
+ else:
469
+ return self._color
470
+
471
+ def _plot(self, projmat, face_contour, opacity) -> Graphics:
472
+ r"""
473
+ Return a 2D graphic object representing the face.
474
+
475
+ INPUT:
476
+
477
+ - ``projmat`` -- 2*3 projection matrix (used only for faces in three dimensions)
478
+ - ``face_contour`` -- dict, maps the face type to vectors describing
479
+ the contour of unit faces (used only for faces in three dimensions)
480
+ - ``opacity`` -- the alpha value for the color of the face
481
+
482
+ OUTPUT: 2D graphic object
483
+
484
+ EXAMPLES::
485
+
486
+ sage: from sage.combinat.e_one_star import Face
487
+ sage: f = Face((0,0,3), 3)
488
+ sage: projmat = matrix(2, [-1.7320508075688772*0.5, 1.7320508075688772*0.5, 0, -0.5, -0.5, 1])
489
+ sage: face_contour = {}
490
+ sage: face_contour[1] = map(vector, [(0,0,0),(0,1,0),(0,1,1),(0,0,1)])
491
+ sage: face_contour[2] = map(vector, [(0,0,0),(0,0,1),(1,0,1),(1,0,0)])
492
+ sage: face_contour[3] = map(vector, [(0,0,0),(1,0,0),(1,1,0),(0,1,0)])
493
+ sage: G = f._plot(projmat, face_contour, 0.75) # needs sage.plot
494
+
495
+ ::
496
+
497
+ sage: f = Face((0,0), 2)
498
+ sage: f._plot(None, None, 1) # needs sage.plot
499
+ Graphics object consisting of 1 graphics primitive
500
+ """
501
+ v = self.vector()
502
+ t = self.type()
503
+ G = Graphics()
504
+
505
+ if len(v) == 2:
506
+ if t == 1:
507
+ G += line([v, v + vector([0, 1])], rgbcolor=self.color(), thickness=1.5, alpha=opacity)
508
+ elif t == 2:
509
+ G += line([v, v + vector([1, 0])], rgbcolor=self.color(), thickness=1.5, alpha=opacity)
510
+
511
+ elif len(v) == 3:
512
+ G += polygon([projmat * (u + v)
513
+ for u in face_contour[t]], alpha=opacity,
514
+ thickness=1, rgbcolor=self.color())
515
+
516
+ else:
517
+ raise NotImplementedError("plotting is implemented only for patches in two or three dimensions.")
518
+
519
+ return G
520
+
521
+ def _plot3d(self, face_contour):
522
+ r"""
523
+ 3D representation of a unit face (Jmol).
524
+
525
+ INPUT:
526
+
527
+ - ``face_contour`` -- dict, maps the face type to vectors describing
528
+ the contour of unit faces
529
+
530
+ EXAMPLES::
531
+
532
+ sage: from sage.combinat.e_one_star import Face
533
+ sage: f = Face((0,0,3), 3)
534
+ sage: face_contour = {1: map(vector, [(0,0,0),(0,1,0),(0,1,1),(0,0,1)]), 2: map(vector, [(0,0,0),(0,0,1),(1,0,1),(1,0,0)]), 3: map(vector, [(0,0,0),(1,0,0),(1,1,0),(0,1,0)])}
535
+ sage: G = f._plot3d(face_contour) #not tested
536
+ """
537
+ v = self.vector()
538
+ t = self.type()
539
+ c = self.color()
540
+ G = polygon([u + v for u in face_contour[t]], rgbcolor=c)
541
+ return G
542
+
543
+
544
+ class Patch(SageObject):
545
+ r"""
546
+ A class to model a collection of faces. A patch is represented by an immutable set of Faces.
547
+
548
+ .. NOTE::
549
+
550
+ The dimension of a patch is the length of the vectors of the faces in the patch,
551
+ which is assumed to be the same for every face in the patch.
552
+
553
+ .. NOTE::
554
+
555
+ Since version 4.7.1, Patches are immutable, except for the colors of the faces,
556
+ which are not taken into account for equality tests and hash functions.
557
+
558
+ INPUT:
559
+
560
+ - ``faces`` -- finite iterable of faces
561
+ - ``face_contour`` -- dictionary (default: ``None``); maps the face
562
+ type to vectors describing the contour of unit faces. If ``None``,
563
+ defaults contour are assumed for faces of type 1, 2, 3 or 1, 2, 3.
564
+ Used in plotting methods only.
565
+
566
+ EXAMPLES::
567
+
568
+ sage: from sage.combinat.e_one_star import Face, Patch
569
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
570
+ sage: P
571
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
572
+
573
+ ::
574
+
575
+ sage: face_contour = {}
576
+ sage: face_contour[1] = map(vector, [(0,0,0),(0,1,0),(0,1,1),(0,0,1)])
577
+ sage: face_contour[2] = map(vector, [(0,0,0),(0,0,1),(1,0,1),(1,0,0)])
578
+ sage: face_contour[3] = map(vector, [(0,0,0),(1,0,0),(1,1,0),(0,1,0)])
579
+ sage: Patch([Face((0,0,0),t) for t in [1,2,3]], face_contour=face_contour)
580
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
581
+ """
582
+
583
+ def __init__(self, faces, face_contour=None):
584
+ r"""
585
+ Constructor of a patch (set of faces).
586
+
587
+ See class doc for more information.
588
+
589
+ EXAMPLES::
590
+
591
+ sage: from sage.combinat.e_one_star import Face, Patch
592
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
593
+ sage: P
594
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
595
+
596
+ TESTS:
597
+
598
+ We test that colors are not anymore mixed up between
599
+ Patches (see :issue:`11255`)::
600
+
601
+ sage: P = Patch([Face([0,0,0],2)])
602
+ sage: Q = Patch(P)
603
+ sage: next(iter(P)).color()
604
+ RGB color (0.0, 1.0, 0.0)
605
+ sage: next(iter(Q)).color('yellow')
606
+ sage: next(iter(P)).color()
607
+ RGB color (0.0, 1.0, 0.0)
608
+ """
609
+ self._faces = frozenset(Face(f.vector(), f.type(), f.color()) for f in faces)
610
+
611
+ try:
612
+ f0 = next(iter(self._faces))
613
+ except StopIteration:
614
+ self._dimension = None
615
+ else:
616
+ self._dimension = len(f0.vector())
617
+
618
+ if face_contour is not None:
619
+ self._face_contour = face_contour
620
+
621
+ else:
622
+ self._face_contour = {
623
+ 1: [vector(t) for t in [(0, 0, 0), (0, 1, 0),
624
+ (0, 1, 1), (0, 0, 1)]],
625
+ 2: [vector(t) for t in [(0, 0, 0), (0, 0, 1),
626
+ (1, 0, 1), (1, 0, 0)]],
627
+ 3: [vector(t) for t in [(0, 0, 0), (1, 0, 0),
628
+ (1, 1, 0), (0, 1, 0)]]
629
+ }
630
+
631
+ def __eq__(self, other) -> bool:
632
+ r"""
633
+ Equality test for Patch.
634
+
635
+ INPUT:
636
+
637
+ - ``other`` -- an object
638
+
639
+ EXAMPLES::
640
+
641
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
642
+ sage: P = Patch([Face((0,0,0),1), Face((0,0,0),2), Face((0,0,0),3)])
643
+ sage: Q = Patch([Face((0,1,0),1), Face((0,0,0),3)])
644
+ sage: P == P
645
+ True
646
+ sage: P == Q
647
+ False
648
+ sage: P == 4
649
+ False
650
+
651
+ ::
652
+
653
+ sage: s = WordMorphism({1:[1,3], 2:[1,2,3], 3:[3]})
654
+ sage: t = WordMorphism({1:[1,2,3], 2:[2,3], 3:[3]})
655
+ sage: P = Patch([Face((0,0,0), 1), Face((0,0,0), 2), Face((0,0,0), 3)])
656
+ sage: E1Star(s)(P) == E1Star(t)(P)
657
+ False
658
+ sage: E1Star(s*t)(P) == E1Star(t)(E1Star(s)(P))
659
+ True
660
+ """
661
+ return (isinstance(other, Patch) and self._faces == other._faces)
662
+
663
+ def __hash__(self) -> int:
664
+ r"""
665
+ Hash function of Patch.
666
+
667
+ EXAMPLES::
668
+
669
+ sage: from sage.combinat.e_one_star import Face, Patch
670
+ sage: x = [Face((0,0,0),t) for t in [1,2,3]]
671
+ sage: P = Patch(x)
672
+ sage: hash(P) #random
673
+ -4839605361791007520
674
+
675
+ TESTS:
676
+
677
+ We test that two equal patches have the same hash (see :issue:`11255`)::
678
+
679
+ sage: P = Patch([Face([0,0,0],1), Face([0,0,0],2)])
680
+ sage: Q = Patch([Face([0,0,0],2), Face([0,0,0],1)])
681
+ sage: P == Q
682
+ True
683
+ sage: hash(P) == hash(Q)
684
+ True
685
+
686
+ Changing the color does not affect the hash value::
687
+
688
+ sage: p = Patch([Face((0,0,0), t) for t in [1,2,3]])
689
+ sage: H1 = hash(p)
690
+ sage: p.repaint(['blue'])
691
+ sage: H2 = hash(p)
692
+ sage: H1 == H2
693
+ True
694
+ """
695
+ return hash(self._faces)
696
+
697
+ def __len__(self) -> int:
698
+ r"""
699
+ Return the number of faces contained in the patch.
700
+
701
+ OUTPUT: integer
702
+
703
+ EXAMPLES::
704
+
705
+ sage: from sage.combinat.e_one_star import Face, Patch
706
+ sage: x = [Face((0,0,0),t) for t in [1,2,3]]
707
+ sage: P = Patch(x)
708
+ sage: len(P) #indirect doctest
709
+ 3
710
+ """
711
+ return len(self._faces)
712
+
713
+ def __iter__(self):
714
+ r"""
715
+ Return an iterator over the faces of the patch.
716
+
717
+ OUTPUT: iterator
718
+
719
+ EXAMPLES::
720
+
721
+ sage: from sage.combinat.e_one_star import Face, Patch
722
+ sage: x = [Face((0,0,0),t) for t in [1,2,3]]
723
+ sage: P = Patch(x)
724
+ sage: it = iter(P)
725
+ sage: type(next(it))
726
+ <class 'sage.combinat.e_one_star.Face'>
727
+ sage: type(next(it))
728
+ <class 'sage.combinat.e_one_star.Face'>
729
+ sage: type(next(it))
730
+ <class 'sage.combinat.e_one_star.Face'>
731
+ sage: type(next(it))
732
+ Traceback (most recent call last):
733
+ ...
734
+ StopIteration
735
+ """
736
+ return iter(self._faces)
737
+
738
+ def __add__(self, other):
739
+ r"""
740
+ Addition of patches (union).
741
+
742
+ INPUT:
743
+
744
+ - ``other`` -- a Patch or a Face or a finite iterable of faces
745
+
746
+ EXAMPLES::
747
+
748
+ sage: from sage.combinat.e_one_star import Face, Patch
749
+ sage: P = Patch([Face([0,0,0], 1), Face([0,0,0], 2)])
750
+ sage: Q = P.translate([1,-1,0])
751
+ sage: P + Q
752
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(1, -1, 0), 1]*, [(1, -1, 0), 2]*]
753
+ sage: P + Face([0,0,0],3)
754
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
755
+ sage: P + [Face([0,0,0],3), Face([1,1,1],2)]
756
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*, [(1, 1, 1), 2]*]
757
+ """
758
+ return self.union(other)
759
+
760
+ def __sub__(self, other):
761
+ r"""
762
+ Subtraction of patches (difference).
763
+
764
+ INPUT:
765
+
766
+ - ``other`` -- a Patch or a Face or a finite iterable of faces
767
+
768
+ EXAMPLES::
769
+
770
+ sage: from sage.combinat.e_one_star import Face, Patch
771
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
772
+ sage: P - Face([0,0,0],2)
773
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 3]*]
774
+ sage: P - P
775
+ Patch: []
776
+ """
777
+ return self.difference(other)
778
+
779
+ def __repr__(self) -> str:
780
+ r"""
781
+ String representation of a patch.
782
+
783
+ Displays all the faces if there less than 20,
784
+ otherwise displays only the number of faces.
785
+
786
+ EXAMPLES::
787
+
788
+ sage: from sage.combinat.e_one_star import Face, Patch
789
+ sage: x = [Face((0,0,0),t) for t in [1,2,3]]
790
+ sage: P = Patch(x)
791
+ sage: P
792
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
793
+
794
+ ::
795
+
796
+ sage: x = [Face((0,0,a),1) for a in range(25)]
797
+ sage: P = Patch(x)
798
+ sage: P
799
+ Patch of 25 faces
800
+ """
801
+ if len(self) <= 20:
802
+ L = list(self)
803
+ L.sort(key=lambda x: (x.vector(), x.type()))
804
+ return "Patch: %s" % L
805
+ else:
806
+ return "Patch of %s faces" % len(self)
807
+
808
+ def union(self, other) -> Patch:
809
+ r"""
810
+ Return a Patch consisting of the union of ``self`` and ``other``.
811
+
812
+ INPUT:
813
+
814
+ - ``other`` -- a Patch or a Face or a finite iterable of faces
815
+
816
+ EXAMPLES::
817
+
818
+ sage: from sage.combinat.e_one_star import Face, Patch
819
+ sage: P = Patch([Face((0,0,0),1), Face((0,0,0),2)])
820
+ sage: P.union(Face((1,2,3), 3))
821
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(1, 2, 3), 3]*]
822
+ sage: P.union([Face((1,2,3), 3), Face((2,3,3), 2)])
823
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(1, 2, 3), 3]*, [(2, 3, 3), 2]*]
824
+ """
825
+ if isinstance(other, Face):
826
+ return Patch(self._faces.union([other]))
827
+ else:
828
+ return Patch(self._faces.union(other))
829
+
830
+ def difference(self, other) -> Patch:
831
+ r"""
832
+ Return the difference of ``self`` and ``other``.
833
+
834
+ INPUT:
835
+
836
+ - ``other`` -- a finite iterable of faces or a single face
837
+
838
+ EXAMPLES::
839
+
840
+ sage: from sage.combinat.e_one_star import Face, Patch
841
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
842
+ sage: P.difference(Face([0,0,0],2))
843
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 3]*]
844
+ sage: P.difference(P)
845
+ Patch: []
846
+ """
847
+ if isinstance(other, Face):
848
+ return Patch(self._faces.difference([other]))
849
+ else:
850
+ return Patch(self._faces.difference(other))
851
+
852
+ def dimension(self) -> None | int:
853
+ r"""
854
+ Return the dimension of the vectors of the faces of ``self``.
855
+
856
+ It returns ``None`` if ``self`` is the empty patch.
857
+
858
+ The dimension of a patch is the length of the vectors of the faces in the patch,
859
+ which is assumed to be the same for every face in the patch.
860
+
861
+ EXAMPLES::
862
+
863
+ sage: from sage.combinat.e_one_star import Face, Patch
864
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
865
+ sage: P.dimension()
866
+ 3
867
+
868
+ TESTS::
869
+
870
+ sage: from sage.combinat.e_one_star import Patch
871
+ sage: p = Patch([])
872
+ sage: p.dimension() is None
873
+ True
874
+
875
+ It works when the patch is created from an iterator::
876
+
877
+ sage: p = Patch(Face((0,0,0),t) for t in [1,2,3])
878
+ sage: p.dimension()
879
+ 3
880
+ """
881
+ return self._dimension
882
+
883
+ def faces_of_vector(self, v) -> list[Face]:
884
+ r"""
885
+ Return a list of the faces whose vector is ``v``.
886
+
887
+ INPUT:
888
+
889
+ - ``v`` -- a vector
890
+
891
+ EXAMPLES::
892
+
893
+ sage: from sage.combinat.e_one_star import Face, Patch
894
+ sage: P = Patch([Face((0,0,0),1), Face((1,2,0),3), Face((1,2,0),1)])
895
+ sage: sorted(P.faces_of_vector([1,2,0]))
896
+ [[(1, 2, 0), 1]*, [(1, 2, 0), 3]*]
897
+ """
898
+ v = vector(v)
899
+ return [f for f in self if f.vector() == v]
900
+
901
+ def faces_of_type(self, t) -> list[Face]:
902
+ r"""
903
+ Return a list of the faces that have type ``t``.
904
+
905
+ INPUT:
906
+
907
+ - ``t`` -- integer or any other type
908
+
909
+ EXAMPLES::
910
+
911
+ sage: from sage.combinat.e_one_star import Face, Patch
912
+ sage: P = Patch([Face((0,0,0),1), Face((1,2,0),3), Face((1,2,0),1)])
913
+ sage: sorted(P.faces_of_type(1))
914
+ [[(0, 0, 0), 1]*, [(1, 2, 0), 1]*]
915
+ """
916
+ return [f for f in self if f.type() == t]
917
+
918
+ def faces_of_color(self, color) -> list[Face]:
919
+ r"""
920
+ Return a list of the faces that have the given color.
921
+
922
+ INPUT:
923
+
924
+ - ``color`` -- color
925
+
926
+ EXAMPLES::
927
+
928
+ sage: from sage.combinat.e_one_star import Face, Patch
929
+ sage: P = Patch([Face((0,0,0),1, 'red'), Face((1,2,0),3, 'blue'), Face((1,2,0),1, 'red')])
930
+ sage: sorted(P.faces_of_color('red'))
931
+ [[(0, 0, 0), 1]*, [(1, 2, 0), 1]*]
932
+ """
933
+ color = tuple(Color(color))
934
+ return [f for f in self if tuple(f.color()) == color]
935
+
936
+ def translate(self, v) -> Patch:
937
+ r"""
938
+ Return a translated copy of ``self`` by vector `v`.
939
+
940
+ INPUT:
941
+
942
+ - ``v`` -- vector or tuple
943
+
944
+ EXAMPLES::
945
+
946
+ sage: from sage.combinat.e_one_star import Face, Patch
947
+ sage: P = Patch([Face((0,0,0),1), Face((1,2,0),3), Face((1,2,0),1)])
948
+ sage: P.translate([-1,-2,0])
949
+ Patch: [[(-1, -2, 0), 1]*, [(0, 0, 0), 1]*, [(0, 0, 0), 3]*]
950
+ """
951
+ v = vector(v)
952
+ return Patch(Face(f.vector() + v, f.type(), f.color()) for f in self)
953
+
954
+ def occurrences_of(self, other) -> list:
955
+ r"""
956
+ Return all positions at which other appears in self, that is,
957
+ all vectors v such that ``set(other.translate(v)) <= set(self)``.
958
+
959
+ INPUT:
960
+
961
+ - ``other`` -- a Patch
962
+
963
+ OUTPUT: list of vectors
964
+
965
+ EXAMPLES::
966
+
967
+ sage: from sage.combinat.e_one_star import Face, Patch, E1Star
968
+ sage: P = Patch([Face([0,0,0], 1), Face([0,0,0], 2), Face([0,0,0], 3)])
969
+ sage: Q = Patch([Face([0,0,0], 1), Face([0,0,0], 2)])
970
+ sage: P.occurrences_of(Q)
971
+ [(0, 0, 0)]
972
+ sage: Q = Q.translate([1,2,3])
973
+ sage: P.occurrences_of(Q)
974
+ [(-1, -2, -3)]
975
+
976
+ ::
977
+
978
+ sage: E = E1Star(WordMorphism({1:[1,2], 2:[1,3], 3:[1]}))
979
+ sage: P = Patch([Face([0,0,0], 1), Face([0,0,0], 2), Face([0,0,0], 3)])
980
+ sage: P = E(P,4)
981
+ sage: Q = Patch([Face([0,0,0], 1), Face([0,0,0], 2)])
982
+ sage: L = P.occurrences_of(Q)
983
+ sage: sorted(L)
984
+ [(0, 0, 0), (0, 0, 1), (0, 1, -1), (1, 0, -1), (1, 1, -3), (1, 1, -2)]
985
+ """
986
+ f0 = next(iter(other))
987
+ x = f0.vector()
988
+ t = f0.type()
989
+ L = self.faces_of_type(t)
990
+ positions = []
991
+ for f in L:
992
+ y = f.vector()
993
+ if other.translate(y - x)._faces.issubset(self._faces):
994
+ positions.append(y - x)
995
+ return positions
996
+
997
+ def repaint(self, cmap='Set1') -> None:
998
+ r"""
999
+ Repaint all the faces of ``self`` from the given color map.
1000
+
1001
+ This only changes the colors of the faces of ``self``.
1002
+
1003
+ INPUT:
1004
+
1005
+ - ``cmap`` -- color map (default: ``'Set1'``). It can be one of the
1006
+ following:
1007
+
1008
+ - ``string`` -- a coloring map; for available coloring map names type:
1009
+ ``sorted(colormaps)``
1010
+ - ``list`` -- list of colors to assign cyclically to the faces
1011
+ A list of a single color colors all the faces with the same color
1012
+ - ``dict`` -- dictionary of face types mapped to colors, to color the
1013
+ faces according to their type
1014
+ - ``{}``, the empty dict -- shortcut for
1015
+ ``{1:'red', 2:'green', 3:'blue'}``
1016
+
1017
+ EXAMPLES:
1018
+
1019
+ Using a color map::
1020
+
1021
+ sage: from sage.combinat.e_one_star import Face, Patch
1022
+ sage: color = (0, 0, 0)
1023
+ sage: P = Patch([Face((0,0,0),t,color) for t in [1,2,3]])
1024
+ sage: for f in P: f.color()
1025
+ RGB color (0.0, 0.0, 0.0)
1026
+ RGB color (0.0, 0.0, 0.0)
1027
+ RGB color (0.0, 0.0, 0.0)
1028
+ sage: P.repaint()
1029
+ sage: next(iter(P)).color() #random
1030
+ RGB color (0.498..., 0.432..., 0.522...)
1031
+
1032
+ Using a list of colors::
1033
+
1034
+ sage: P = Patch([Face((0,0,0),t,color) for t in [1,2,3]])
1035
+ sage: P.repaint([(0.9, 0.9, 0.9), (0.65,0.65,0.65), (0.4,0.4,0.4)])
1036
+ sage: for f in P: f.color()
1037
+ RGB color (0.9, 0.9, 0.9)
1038
+ RGB color (0.65, 0.65, 0.65)
1039
+ RGB color (0.4, 0.4, 0.4)
1040
+
1041
+ Using a dictionary to color faces according to their type::
1042
+
1043
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1044
+ sage: P.repaint({1:'black', 2:'yellow', 3:'green'})
1045
+ sage: P.plot() #not tested
1046
+ sage: P.repaint({})
1047
+ sage: P.plot() #not tested
1048
+ """
1049
+ if cmap == {}:
1050
+ cmap = {1: 'red', 2: 'green', 3: 'blue'}
1051
+
1052
+ if isinstance(cmap, dict):
1053
+ for f in self:
1054
+ f.color(cmap[f.type()])
1055
+
1056
+ elif isinstance(cmap, list):
1057
+ L = len(cmap)
1058
+ for i, f in enumerate(self):
1059
+ f.color(cmap[i % L])
1060
+
1061
+ elif isinstance(cmap, str):
1062
+ # matplotlib color maps
1063
+ global cm
1064
+ if cm is None:
1065
+ from matplotlib import cm
1066
+ assert cm is not None
1067
+ if cmap not in cm.datad:
1068
+ raise RuntimeError("color map %s not known (type sorted(colors) for valid names)" % cmap)
1069
+ cmap = cm.__dict__[cmap]
1070
+ dim = float(len(self))
1071
+ for i, f in enumerate(self):
1072
+ f.color(cmap(i / dim)[:3])
1073
+
1074
+ else:
1075
+ raise TypeError("type of cmap (=%s) must be dict, list or str" % cmap)
1076
+
1077
+ def plot(self, projmat=None, opacity=0.75) -> Graphics:
1078
+ r"""
1079
+ Return a 2D graphic object depicting the patch.
1080
+
1081
+ INPUT:
1082
+
1083
+ - ``projmat`` -- matrix (default: ``None``); the projection
1084
+ matrix. Its number of lines must be two. Its number of columns
1085
+ must equal the dimension of the ambient space of the faces. If
1086
+ ``None``, the isometric projection is used by default.
1087
+
1088
+ - ``opacity`` -- float between ``0`` and ``1`` (default: ``0.75``)
1089
+ opacity of the face
1090
+
1091
+ .. WARNING::
1092
+
1093
+ Plotting is implemented only for patches in two or three dimensions.
1094
+
1095
+ EXAMPLES::
1096
+
1097
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1098
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1099
+ sage: P.plot() # needs sage.plot
1100
+ Graphics object consisting of 3 graphics primitives
1101
+
1102
+ ::
1103
+
1104
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1105
+ sage: E = E1Star(sigma)
1106
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1107
+ sage: P = E(P, 5)
1108
+ sage: P.plot() # needs sage.plot
1109
+ Graphics object consisting of 57 graphics primitives
1110
+
1111
+ Plot with a different projection matrix::
1112
+
1113
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1114
+ sage: E = E1Star(sigma)
1115
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1116
+ sage: M = matrix(2, 3, [1,0,-1,0.3,1,-3])
1117
+ sage: P = E(P, 3)
1118
+ sage: P.plot(projmat=M) # needs sage.plot
1119
+ Graphics object consisting of 17 graphics primitives
1120
+
1121
+ Plot patches made of unit segments::
1122
+
1123
+ sage: P = Patch([Face([0,0], 1), Face([0,0], 2)])
1124
+ sage: E = E1Star(WordMorphism({1:[1,2],2:[1]}))
1125
+ sage: F = E1Star(WordMorphism({1:[1,1,2],2:[2,1]}))
1126
+ sage: E(P,5).plot() # needs sage.plot
1127
+ Graphics object consisting of 21 graphics primitives
1128
+ sage: F(P,3).plot() # needs sage.plot
1129
+ Graphics object consisting of 34 graphics primitives
1130
+ """
1131
+ if self.dimension() == 2:
1132
+ G = Graphics()
1133
+ for face in self:
1134
+ G += face._plot(None, None, 1)
1135
+ G.set_aspect_ratio(1)
1136
+ return G
1137
+
1138
+ if self.dimension() == 3:
1139
+ if projmat is None:
1140
+ projmat = matrix(2, [-1.7320508075688772 * 0.5,
1141
+ 1.7320508075688772 * 0.5,
1142
+ 0, -0.5, -0.5, 1])
1143
+
1144
+ G = Graphics()
1145
+ for face in self:
1146
+ G += face._plot(projmat, self._face_contour, opacity)
1147
+ G.set_aspect_ratio(1)
1148
+ return G
1149
+
1150
+ else:
1151
+ raise NotImplementedError("plotting is implemented only for patches in two or three dimensions.")
1152
+
1153
+ def plot3d(self):
1154
+ r"""
1155
+ Return a 3D graphics object depicting the patch.
1156
+
1157
+ .. WARNING::
1158
+
1159
+ 3D plotting is implemented only for patches in three dimensions.
1160
+
1161
+ EXAMPLES::
1162
+
1163
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1164
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1165
+ sage: P.plot3d() #not tested
1166
+
1167
+ ::
1168
+
1169
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1170
+ sage: E = E1Star(sigma)
1171
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1172
+ sage: P = E(P, 5)
1173
+ sage: P.repaint()
1174
+ sage: P.plot3d() #not tested
1175
+ """
1176
+ if self.dimension() != 3:
1177
+ raise NotImplementedError("3D plotting is implemented only for patches in three dimensions")
1178
+
1179
+ face_list = [face._plot3d(self._face_contour) for face in self]
1180
+ G = sum(face_list)
1181
+ return G
1182
+
1183
+ def plot_tikz(self, projmat=None, print_tikz_env=True, edgecolor='black',
1184
+ scale=0.25, drawzero=False, extra_code_before='', extra_code_after='') -> str:
1185
+ r"""
1186
+ Return a string containing some TikZ code to be included into
1187
+ a LaTeX document, depicting the patch.
1188
+
1189
+ .. WARNING::
1190
+
1191
+ Tikz Plotting is implemented only for patches in three dimensions.
1192
+
1193
+ INPUT:
1194
+
1195
+ - ``projmat`` -- matrix (default: ``None``); the projection
1196
+ matrix. Its number of lines must be two. Its number of columns
1197
+ must equal the dimension of the ambient space of the faces. If
1198
+ ``None``, the isometric projection is used by default.
1199
+ - ``print_tikz_env`` -- boolean (default: ``True``); if ``True``,
1200
+ the tikzpicture environment are printed
1201
+ - ``edgecolor`` -- string (default: ``'black'``); either
1202
+ ``'black'`` or ``'facecolor'`` (color of unit face edges)
1203
+ - ``scale`` -- real number (default: ``0.25``) scaling
1204
+ constant for the whole figure
1205
+ - ``drawzero`` -- boolean (default: ``False``); if ``True``,
1206
+ mark the origin by a black dot
1207
+ - ``extra_code_before`` -- string (default: ``''``); extra code to
1208
+ include in the tikz picture
1209
+ - ``extra_code_after`` -- string (default: ``''``); extra code to
1210
+ include in the tikz picture
1211
+
1212
+ EXAMPLES::
1213
+
1214
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1215
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1216
+ sage: s = P.plot_tikz()
1217
+ sage: len(s)
1218
+ 602
1219
+ sage: print(s) #not tested
1220
+ \begin{tikzpicture}
1221
+ [x={(-0.216506cm,-0.125000cm)}, y={(0.216506cm,-0.125000cm)}, z={(0.000000cm,0.250000cm)}]
1222
+ \definecolor{facecolor}{rgb}{0.000,1.000,0.000}
1223
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
1224
+ (0, 0, 0) -- (0, 0, 1) -- (1, 0, 1) -- (1, 0, 0) -- cycle;
1225
+ \definecolor{facecolor}{rgb}{1.000,0.000,0.000}
1226
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
1227
+ (0, 0, 0) -- (0, 1, 0) -- (0, 1, 1) -- (0, 0, 1) -- cycle;
1228
+ \definecolor{facecolor}{rgb}{0.000,0.000,1.000}
1229
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
1230
+ (0, 0, 0) -- (1, 0, 0) -- (1, 1, 0) -- (0, 1, 0) -- cycle;
1231
+ \end{tikzpicture}
1232
+
1233
+ ::
1234
+
1235
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1236
+ sage: E = E1Star(sigma)
1237
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1238
+ sage: P = E(P, 4)
1239
+ sage: from sage.misc.latex import latex #not tested
1240
+ sage: latex.add_to_preamble('\\usepackage{tikz}') #not tested
1241
+ sage: view(P) #not tested
1242
+
1243
+ Plot using shades of gray (useful for article figures)::
1244
+
1245
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1246
+ sage: E = E1Star(sigma)
1247
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1248
+ sage: P.repaint([(0.9, 0.9, 0.9), (0.65,0.65,0.65), (0.4,0.4,0.4)])
1249
+ sage: P = E(P, 4)
1250
+ sage: s = P.plot_tikz()
1251
+
1252
+ Plotting with various options::
1253
+
1254
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1255
+ sage: E = E1Star(sigma)
1256
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1257
+ sage: M = matrix(2,3,[float(u) for u in [1,0,-0.7071,0,1,-0.7071]])
1258
+ sage: P = E(P, 3)
1259
+ sage: s = P.plot_tikz(projmat=M, edgecolor='facecolor', scale=0.6, drawzero=True)
1260
+
1261
+ Adding X, Y, Z axes using the extra code feature::
1262
+
1263
+ sage: length = 1.5
1264
+ sage: space = 0.3
1265
+ sage: axes = ''
1266
+ sage: axes += "\\draw[->, thick, black] (0,0,0) -- (%s, 0, 0);\n" % length
1267
+ sage: axes += "\\draw[->, thick, black] (0,0,0) -- (0, %s, 0);\n" % length
1268
+ sage: axes += "\\node at (%s,0,0) {$x$};\n" % (length + space)
1269
+ sage: axes += "\\node at (0,%s,0) {$y$};\n" % (length + space)
1270
+ sage: axes += "\\node at (0,0,%s) {$z$};\n" % (length + space)
1271
+ sage: axes += "\\draw[->, thick, black] (0,0,0) -- (0, 0, %s);\n" % length
1272
+ sage: cube = Patch([Face((0,0,0),1), Face((0,0,0),2), Face((0,0,0),3)])
1273
+ sage: options = dict(scale=0.5,drawzero=True,extra_code_before=axes)
1274
+ sage: s = cube.plot_tikz(**options)
1275
+ sage: len(s)
1276
+ 986
1277
+ sage: print(s) #not tested
1278
+ \begin{tikzpicture}
1279
+ [x={(-0.433013cm,-0.250000cm)}, y={(0.433013cm,-0.250000cm)}, z={(0.000000cm,0.500000cm)}]
1280
+ \draw[->, thick, black] (0,0,0) -- (1.50000000000000, 0, 0);
1281
+ \draw[->, thick, black] (0,0,0) -- (0, 1.50000000000000, 0);
1282
+ \node at (1.80000000000000,0,0) {$x$};
1283
+ \node at (0,1.80000000000000,0) {$y$};
1284
+ \node at (0,0,1.80000000000000) {$z$};
1285
+ \draw[->, thick, black] (0,0,0) -- (0, 0, 1.50000000000000);
1286
+ \definecolor{facecolor}{rgb}{0.000,1.000,0.000}
1287
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
1288
+ (0, 0, 0) -- (0, 0, 1) -- (1, 0, 1) -- (1, 0, 0) -- cycle;
1289
+ \definecolor{facecolor}{rgb}{1.000,0.000,0.000}
1290
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
1291
+ (0, 0, 0) -- (0, 1, 0) -- (0, 1, 1) -- (0, 0, 1) -- cycle;
1292
+ \definecolor{facecolor}{rgb}{0.000,0.000,1.000}
1293
+ \fill[fill=facecolor, draw=black, shift={(0,0,0)}]
1294
+ (0, 0, 0) -- (1, 0, 0) -- (1, 1, 0) -- (0, 1, 0) -- cycle;
1295
+ \node[circle,fill=black,draw=black,minimum size=1.5mm,inner sep=0pt] at (0,0,0) {};
1296
+ \end{tikzpicture}
1297
+ """
1298
+ if self.dimension() != 3:
1299
+ raise NotImplementedError("Tikz plotting is implemented only for patches in three dimensions")
1300
+
1301
+ if projmat is None:
1302
+ projmat = matrix(2, [-1.7320508075688772 * 0.5,
1303
+ 1.7320508075688772 * 0.5,
1304
+ 0, -0.5, -0.5, 1]) * scale
1305
+
1306
+ e1 = projmat * vector([1, 0, 0])
1307
+ e2 = projmat * vector([0, 1, 0])
1308
+ e3 = projmat * vector([0, 0, 1])
1309
+ face_contour = self._face_contour
1310
+ color = None
1311
+
1312
+ # string s contains the TiKZ code of the patch
1313
+ s = ''
1314
+
1315
+ if print_tikz_env:
1316
+ s += '\\begin{tikzpicture}\n'
1317
+ s += '[x={(%fcm,%fcm)}, y={(%fcm,%fcm)}, z={(%fcm,%fcm)}]\n' % (e1[0], e1[1], e2[0], e2[1], e3[0], e3[1])
1318
+
1319
+ s += extra_code_before
1320
+
1321
+ for f in self:
1322
+ t = f.type()
1323
+ x, y, z = f.vector()
1324
+
1325
+ if color is None or color != f.color():
1326
+ color = f.color()
1327
+ s += '\\definecolor{facecolor}{rgb}{%.3f,%.3f,%.3f}\n' % (color[0], color[1], color[2])
1328
+
1329
+ s += '\\fill[fill=facecolor, draw=%s, shift={(%d,%d,%d)}]\n' % (edgecolor, x, y, z)
1330
+ s += ' -- '.join(map(str, face_contour[t])) + ' -- cycle;\n'
1331
+
1332
+ s += extra_code_after
1333
+
1334
+ if drawzero:
1335
+ s += '\\node[circle,fill=black,draw=black,minimum size=1.5mm,inner sep=0pt] at (0,0,0) {};\n'
1336
+
1337
+ if print_tikz_env:
1338
+ s += '\\end{tikzpicture}'
1339
+
1340
+ return LatexExpr(s)
1341
+
1342
+ _latex_ = plot_tikz
1343
+
1344
+
1345
+ class E1Star(SageObject):
1346
+ r"""
1347
+ A class to model the `E_1^*(\sigma)` map associated with
1348
+ a unimodular substitution `\sigma`.
1349
+
1350
+ INPUT:
1351
+
1352
+ - ``sigma`` -- unimodular ``WordMorphism``, i.e. such that its incidence
1353
+ matrix has determinant `\pm 1`
1354
+
1355
+ - ``method`` -- 'prefix' or 'suffix' (default: ``'suffix'``);
1356
+ enables to use an alternative definition `E_1^*(\sigma)` substitutions,
1357
+ where the abelianized of the prefix` is used instead of the suffix
1358
+
1359
+ .. NOTE::
1360
+
1361
+ The alphabet of the domain and the codomain of `\sigma` must be
1362
+ equal, and they must be of the form ``[1, ..., d]``, where ``d``
1363
+ is a positive integer corresponding to the length of the vectors
1364
+ of the faces on which `E_1^*(\sigma)` will act.
1365
+
1366
+ EXAMPLES::
1367
+
1368
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1369
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1370
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1371
+ sage: E = E1Star(sigma)
1372
+ sage: E(P)
1373
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*, [(0, 1, -1), 2]*, [(1, 0, -1), 1]*]
1374
+
1375
+ ::
1376
+
1377
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1378
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1379
+ sage: E = E1Star(sigma, method='prefix')
1380
+ sage: E(P)
1381
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*, [(0, 0, 1), 1]*, [(0, 0, 1), 2]*]
1382
+
1383
+ ::
1384
+
1385
+ sage: x = [Face((0,0,0,0),1), Face((0,0,0,0),4)]
1386
+ sage: P = Patch(x)
1387
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1,4], 4:[1]})
1388
+ sage: E = E1Star(sigma)
1389
+ sage: E(P)
1390
+ Patch: [[(0, 0, 0, 0), 3]*, [(0, 0, 0, 0), 4]*, [(0, 0, 1, -1), 3]*, [(0, 1, 0, -1), 2]*, [(1, 0, 0, -1), 1]*]
1391
+ """
1392
+
1393
+ def __init__(self, sigma, method='suffix'):
1394
+ r"""
1395
+ E1Star constructor. See class doc for more information.
1396
+
1397
+ EXAMPLES::
1398
+
1399
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1400
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1401
+ sage: E = E1Star(sigma)
1402
+ sage: E
1403
+ E_1^*(1->12, 2->13, 3->1)
1404
+ """
1405
+ if not isinstance(sigma, WordMorphism):
1406
+ raise TypeError("sigma (=%s) must be an instance of WordMorphism" % sigma)
1407
+
1408
+ if sigma.domain().alphabet() != sigma.codomain().alphabet():
1409
+ raise ValueError("the domain and codomain of (%s) must be the same" % sigma)
1410
+
1411
+ if abs(det(matrix(sigma))) != 1:
1412
+ raise ValueError("the substitution (%s) must be unimodular" % sigma)
1413
+
1414
+ first_letter = sigma.codomain().alphabet()[0]
1415
+ if first_letter not in ZZ or first_letter < 1:
1416
+ raise ValueError(f"the substitution ({sigma}) must be defined on positive integers")
1417
+
1418
+ self._sigma = WordMorphism(sigma)
1419
+ self._d = self._sigma.domain().alphabet().cardinality()
1420
+
1421
+ # self._base_iter is a base for the iteration of the application of self on set
1422
+ # of faces. (Exploits the linearity of `E_1^*(\sigma)` to optimize computation.)
1423
+ alphabet = self._sigma.domain().alphabet()
1424
+ X = {}
1425
+ for k in alphabet:
1426
+ subst_im = self._sigma.image(k)
1427
+ for n, letter in enumerate(subst_im):
1428
+ if method == 'suffix':
1429
+ image_word = subst_im[n + 1:]
1430
+ elif method == 'prefix':
1431
+ image_word = subst_im[:n]
1432
+ else:
1433
+ raise ValueError("option 'method' can only be 'prefix' or 'suffix'")
1434
+ if letter not in X:
1435
+ X[letter] = []
1436
+ v = self.inverse_matrix() * vector(image_word.abelian_vector())
1437
+ X[letter].append((v, k))
1438
+ self._base_iter = X
1439
+
1440
+ def __eq__(self, other) -> bool:
1441
+ r"""
1442
+ Equality test for E1Star morphisms.
1443
+
1444
+ INPUT:
1445
+
1446
+ - ``other`` -- an object
1447
+
1448
+ EXAMPLES::
1449
+
1450
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1451
+ sage: s = WordMorphism({1:[1,3], 2:[1,2,3], 3:[3]})
1452
+ sage: t = WordMorphism({1:[1,2,3], 2:[2,3], 3:[3]})
1453
+ sage: S = E1Star(s)
1454
+ sage: T = E1Star(t)
1455
+ sage: S == T
1456
+ False
1457
+ sage: S2 = E1Star(s, method='prefix')
1458
+ sage: S == S2
1459
+ False
1460
+ """
1461
+ return (isinstance(other, E1Star) and self._base_iter == other._base_iter)
1462
+
1463
+ def __call__(self, patch, iterations=1) -> Patch:
1464
+ r"""
1465
+ Applies a generalized substitution to a Patch; this returns a new object.
1466
+
1467
+ The color of every new face in the image is given the same color as its preimage.
1468
+
1469
+ INPUT:
1470
+
1471
+ - ``patch`` -- a patch
1472
+ - ``iterations`` -- integer (default: 1); number of iterations
1473
+
1474
+ OUTPUT: a patch
1475
+
1476
+ EXAMPLES::
1477
+
1478
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1479
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1480
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1481
+ sage: E = E1Star(sigma)
1482
+ sage: E(P)
1483
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*, [(0, 1, -1), 2]*, [(1, 0, -1), 1]*]
1484
+ sage: E(P, iterations=4)
1485
+ Patch of 31 faces
1486
+
1487
+ TESTS:
1488
+
1489
+ We test that iterations=0 works (see :issue:`10699`)::
1490
+
1491
+ sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]])
1492
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1493
+ sage: E = E1Star(sigma)
1494
+ sage: E(P, iterations=0)
1495
+ Patch: [[(0, 0, 0), 1]*, [(0, 0, 0), 2]*, [(0, 0, 0), 3]*]
1496
+ """
1497
+ if iterations == 0:
1498
+ return Patch(patch)
1499
+ elif iterations < 0:
1500
+ raise ValueError("iterations (=%s) must be >= 0" % iterations)
1501
+ else:
1502
+ old_faces = patch
1503
+ for _ in range(iterations):
1504
+ new_faces = []
1505
+ for f in old_faces:
1506
+ new_faces.extend(self._call_on_face(f, color=f.color()))
1507
+ old_faces = new_faces
1508
+ return Patch(new_faces)
1509
+
1510
+ def __mul__(self, other) -> E1Star:
1511
+ r"""
1512
+ Return the product of ``self`` and ``other``.
1513
+
1514
+ The product satisfies the following rule:
1515
+ `E_1^*(\sigma\circ\sigma') = E_1^*(\sigma')` \circ E_1^*(\sigma)`
1516
+
1517
+ INPUT:
1518
+
1519
+ - ``other`` -- an instance of E1Star
1520
+
1521
+ OUTPUT: an instance of E1Star
1522
+
1523
+ EXAMPLES::
1524
+
1525
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1526
+ sage: s = WordMorphism({1:[2],2:[3],3:[1,2]})
1527
+ sage: t = WordMorphism({1:[1,3,1],2:[1],3:[1,1,3,2]})
1528
+ sage: E1Star(s) * E1Star(t)
1529
+ E_1^*(1->1, 2->1132, 3->1311)
1530
+ sage: E1Star(t * s)
1531
+ E_1^*(1->1, 2->1132, 3->1311)
1532
+ """
1533
+ if not isinstance(other, E1Star):
1534
+ raise TypeError("other (=%s) must be an instance of E1Star" % other)
1535
+ return E1Star(other.sigma() * self.sigma())
1536
+
1537
+ def __repr__(self) -> str:
1538
+ r"""
1539
+ String representation of a patch.
1540
+
1541
+ EXAMPLES::
1542
+
1543
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1544
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1545
+ sage: E = E1Star(sigma)
1546
+ sage: E
1547
+ E_1^*(1->12, 2->13, 3->1)
1548
+ """
1549
+ return "E_1^*(%s)" % str(self._sigma)
1550
+
1551
+ def _call_on_face(self, face, color=None):
1552
+ r"""
1553
+ Return an iterator of faces obtained by applying ``self`` on the face.
1554
+
1555
+ INPUT:
1556
+
1557
+ - ``face`` -- a face
1558
+ - ``color`` -- string (default: ``None``); RGB tuple or color
1559
+
1560
+ OUTPUT: iterator of faces
1561
+
1562
+ EXAMPLES::
1563
+
1564
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1565
+ sage: f = Face((0,2,0), 1)
1566
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1567
+ sage: E = E1Star(sigma)
1568
+ sage: list(E._call_on_face(f))
1569
+ [[(3, 0, -3), 1]*, [(2, 1, -3), 2]*, [(2, 0, -2), 3]*]
1570
+ """
1571
+ if len(face.vector()) != self._d:
1572
+ raise ValueError("the dimension of the faces must be equal to the size of the alphabet of the substitution")
1573
+ x_new = self.inverse_matrix() * face.vector()
1574
+ t = face.type()
1575
+ return (Face(x_new + v, k, color=color) for v, k in self._base_iter[t])
1576
+
1577
+ @cached_method
1578
+ def matrix(self):
1579
+ r"""
1580
+ Return the matrix associated with ``self``.
1581
+
1582
+ EXAMPLES::
1583
+
1584
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1585
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1586
+ sage: E = E1Star(sigma)
1587
+ sage: E.matrix()
1588
+ [1 1 1]
1589
+ [1 0 0]
1590
+ [0 1 0]
1591
+ """
1592
+ return self._sigma.incidence_matrix()
1593
+
1594
+ @cached_method
1595
+ def inverse_matrix(self):
1596
+ r"""
1597
+ Return the inverse of the matrix associated with ``self``.
1598
+
1599
+ EXAMPLES::
1600
+
1601
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1602
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1603
+ sage: E = E1Star(sigma)
1604
+ sage: E.inverse_matrix()
1605
+ [ 0 1 0]
1606
+ [ 0 0 1]
1607
+ [ 1 -1 -1]
1608
+ """
1609
+ return self.matrix().inverse()
1610
+
1611
+ def sigma(self) -> WordMorphism:
1612
+ r"""
1613
+ Return the ``WordMorphism`` associated with ``self``.
1614
+
1615
+ EXAMPLES::
1616
+
1617
+ sage: from sage.combinat.e_one_star import E1Star, Face, Patch
1618
+ sage: sigma = WordMorphism({1:[1,2], 2:[1,3], 3:[1]})
1619
+ sage: E = E1Star(sigma)
1620
+ sage: E.sigma()
1621
+ WordMorphism: 1->12, 2->13, 3->1
1622
+ """
1623
+ return self._sigma