passagemath-combinat 10.6.42__cp314-cp314t-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
- passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
- passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
- passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
- passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
- sage/algebras/affine_nil_temperley_lieb.py +263 -0
- sage/algebras/all.py +24 -0
- sage/algebras/all__sagemath_combinat.py +35 -0
- sage/algebras/askey_wilson.py +935 -0
- sage/algebras/associated_graded.py +345 -0
- sage/algebras/cellular_basis.py +350 -0
- sage/algebras/cluster_algebra.py +2766 -0
- sage/algebras/down_up_algebra.py +860 -0
- sage/algebras/free_algebra.py +1698 -0
- sage/algebras/free_algebra_element.py +345 -0
- sage/algebras/free_algebra_quotient.py +405 -0
- sage/algebras/free_algebra_quotient_element.py +295 -0
- sage/algebras/free_zinbiel_algebra.py +885 -0
- sage/algebras/hall_algebra.py +783 -0
- sage/algebras/hecke_algebras/all.py +4 -0
- sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
- sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
- sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
- sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
- sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
- sage/algebras/iwahori_hecke_algebra.py +3095 -0
- sage/algebras/jordan_algebra.py +1773 -0
- sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
- sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
- sage/algebras/lie_conformal_algebras/all.py +18 -0
- sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
- sage/algebras/lie_conformal_algebras/examples.py +43 -0
- sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
- sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
- sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
- sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
- sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
- sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
- sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
- sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
- sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
- sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
- sage/algebras/nil_coxeter_algebra.py +191 -0
- sage/algebras/q_commuting_polynomials.py +673 -0
- sage/algebras/q_system.py +608 -0
- sage/algebras/quantum_clifford.py +959 -0
- sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
- sage/algebras/quantum_groups/all.py +9 -0
- sage/algebras/quantum_groups/fock_space.py +2219 -0
- sage/algebras/quantum_groups/q_numbers.py +207 -0
- sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
- sage/algebras/quantum_groups/representations.py +591 -0
- sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
- sage/algebras/quantum_oscillator.py +623 -0
- sage/algebras/quaternion_algebra.py +20 -0
- sage/algebras/quaternion_algebra_element.py +55 -0
- sage/algebras/rational_cherednik_algebra.py +525 -0
- sage/algebras/schur_algebra.py +670 -0
- sage/algebras/shuffle_algebra.py +1011 -0
- sage/algebras/splitting_algebra.py +779 -0
- sage/algebras/tensor_algebra.py +709 -0
- sage/algebras/yangian.py +1082 -0
- sage/algebras/yokonuma_hecke_algebra.py +1018 -0
- sage/all__sagemath_combinat.py +44 -0
- sage/combinat/SJT.py +255 -0
- sage/combinat/affine_permutation.py +2405 -0
- sage/combinat/algebraic_combinatorics.py +55 -0
- sage/combinat/all.py +53 -0
- sage/combinat/all__sagemath_combinat.py +195 -0
- sage/combinat/alternating_sign_matrix.py +2063 -0
- sage/combinat/baxter_permutations.py +346 -0
- sage/combinat/bijectionist.py +3220 -0
- sage/combinat/binary_recurrence_sequences.py +1180 -0
- sage/combinat/blob_algebra.py +685 -0
- sage/combinat/catalog_partitions.py +27 -0
- sage/combinat/chas/all.py +23 -0
- sage/combinat/chas/fsym.py +1180 -0
- sage/combinat/chas/wqsym.py +2601 -0
- sage/combinat/cluster_complex.py +326 -0
- sage/combinat/colored_permutations.py +2039 -0
- sage/combinat/colored_permutations_representations.py +964 -0
- sage/combinat/composition_signed.py +142 -0
- sage/combinat/composition_tableau.py +855 -0
- sage/combinat/constellation.py +1729 -0
- sage/combinat/core.py +751 -0
- sage/combinat/counting.py +12 -0
- sage/combinat/crystals/affine.py +742 -0
- sage/combinat/crystals/affine_factorization.py +518 -0
- sage/combinat/crystals/affinization.py +331 -0
- sage/combinat/crystals/alcove_path.py +2013 -0
- sage/combinat/crystals/all.py +22 -0
- sage/combinat/crystals/bkk_crystals.py +141 -0
- sage/combinat/crystals/catalog.py +115 -0
- sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
- sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
- sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
- sage/combinat/crystals/crystals.py +257 -0
- sage/combinat/crystals/direct_sum.py +260 -0
- sage/combinat/crystals/elementary_crystals.py +1251 -0
- sage/combinat/crystals/fast_crystals.py +441 -0
- sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
- sage/combinat/crystals/generalized_young_walls.py +1076 -0
- sage/combinat/crystals/highest_weight_crystals.py +436 -0
- sage/combinat/crystals/induced_structure.py +695 -0
- sage/combinat/crystals/infinity_crystals.py +730 -0
- sage/combinat/crystals/kac_modules.py +863 -0
- sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
- sage/combinat/crystals/kyoto_path_model.py +497 -0
- sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/letters.pxd +79 -0
- sage/combinat/crystals/letters.pyx +3056 -0
- sage/combinat/crystals/littelmann_path.py +1518 -0
- sage/combinat/crystals/monomial_crystals.py +1262 -0
- sage/combinat/crystals/multisegments.py +462 -0
- sage/combinat/crystals/mv_polytopes.py +467 -0
- sage/combinat/crystals/pbw_crystal.py +511 -0
- sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/pbw_datum.pxd +4 -0
- sage/combinat/crystals/pbw_datum.pyx +487 -0
- sage/combinat/crystals/polyhedral_realization.py +372 -0
- sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/spins.pxd +21 -0
- sage/combinat/crystals/spins.pyx +756 -0
- sage/combinat/crystals/star_crystal.py +290 -0
- sage/combinat/crystals/subcrystal.py +464 -0
- sage/combinat/crystals/tensor_product.py +1177 -0
- sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/tensor_product_element.pxd +35 -0
- sage/combinat/crystals/tensor_product_element.pyx +1870 -0
- sage/combinat/crystals/virtual_crystal.py +420 -0
- sage/combinat/cyclic_sieving_phenomenon.py +204 -0
- sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
- sage/combinat/degree_sequences.pyx +588 -0
- sage/combinat/derangements.py +527 -0
- sage/combinat/descent_algebra.py +1008 -0
- sage/combinat/diagram.py +1551 -0
- sage/combinat/diagram_algebras.py +5886 -0
- sage/combinat/dyck_word.py +4349 -0
- sage/combinat/e_one_star.py +1623 -0
- sage/combinat/enumerated_sets.py +123 -0
- sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
- sage/combinat/fast_vector_partitions.pyx +346 -0
- sage/combinat/fqsym.py +1977 -0
- sage/combinat/free_dendriform_algebra.py +954 -0
- sage/combinat/free_prelie_algebra.py +1141 -0
- sage/combinat/fully_commutative_elements.py +1077 -0
- sage/combinat/fully_packed_loop.py +1523 -0
- sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
- sage/combinat/gray_codes.py +311 -0
- sage/combinat/grossman_larson_algebras.py +667 -0
- sage/combinat/growth.py +4352 -0
- sage/combinat/hall_polynomial.py +188 -0
- sage/combinat/hillman_grassl.py +866 -0
- sage/combinat/integer_matrices.py +329 -0
- sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
- sage/combinat/k_tableau.py +4564 -0
- sage/combinat/kazhdan_lusztig.py +215 -0
- sage/combinat/key_polynomial.py +885 -0
- sage/combinat/knutson_tao_puzzles.py +2286 -0
- sage/combinat/lr_tableau.py +311 -0
- sage/combinat/matrices/all.py +24 -0
- sage/combinat/matrices/hadamard_matrix.py +3790 -0
- sage/combinat/matrices/latin.py +2912 -0
- sage/combinat/misc.py +401 -0
- sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
- sage/combinat/ncsf_qsym/all.py +21 -0
- sage/combinat/ncsf_qsym/combinatorics.py +317 -0
- sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
- sage/combinat/ncsf_qsym/ncsf.py +5637 -0
- sage/combinat/ncsf_qsym/qsym.py +4053 -0
- sage/combinat/ncsf_qsym/tutorial.py +447 -0
- sage/combinat/ncsym/all.py +21 -0
- sage/combinat/ncsym/bases.py +855 -0
- sage/combinat/ncsym/dual.py +593 -0
- sage/combinat/ncsym/ncsym.py +2076 -0
- sage/combinat/necklace.py +551 -0
- sage/combinat/non_decreasing_parking_function.py +634 -0
- sage/combinat/nu_dyck_word.py +1474 -0
- sage/combinat/output.py +861 -0
- sage/combinat/parallelogram_polyomino.py +4326 -0
- sage/combinat/parking_functions.py +1602 -0
- sage/combinat/partition_algebra.py +1998 -0
- sage/combinat/partition_kleshchev.py +1982 -0
- sage/combinat/partition_shifting_algebras.py +584 -0
- sage/combinat/partition_tuple.py +3114 -0
- sage/combinat/path_tableaux/all.py +13 -0
- sage/combinat/path_tableaux/catalog.py +29 -0
- sage/combinat/path_tableaux/dyck_path.py +380 -0
- sage/combinat/path_tableaux/frieze.py +476 -0
- sage/combinat/path_tableaux/path_tableau.py +728 -0
- sage/combinat/path_tableaux/semistandard.py +510 -0
- sage/combinat/perfect_matching.py +779 -0
- sage/combinat/plane_partition.py +3300 -0
- sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
- sage/combinat/q_bernoulli.pyx +128 -0
- sage/combinat/quickref.py +81 -0
- sage/combinat/recognizable_series.py +2051 -0
- sage/combinat/regular_sequence.py +4316 -0
- sage/combinat/regular_sequence_bounded.py +543 -0
- sage/combinat/restricted_growth.py +81 -0
- sage/combinat/ribbon.py +20 -0
- sage/combinat/ribbon_shaped_tableau.py +489 -0
- sage/combinat/ribbon_tableau.py +1180 -0
- sage/combinat/rigged_configurations/all.py +46 -0
- sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
- sage/combinat/rigged_configurations/bij_infinity.py +370 -0
- sage/combinat/rigged_configurations/bij_type_A.py +163 -0
- sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
- sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
- sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
- sage/combinat/rigged_configurations/bij_type_B.py +900 -0
- sage/combinat/rigged_configurations/bij_type_C.py +267 -0
- sage/combinat/rigged_configurations/bij_type_D.py +771 -0
- sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
- sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
- sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
- sage/combinat/rigged_configurations/bijection.py +143 -0
- sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
- sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
- sage/combinat/rigged_configurations/rc_crystal.py +461 -0
- sage/combinat/rigged_configurations/rc_infinity.py +540 -0
- sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
- sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
- sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
- sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
- sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
- sage/combinat/rsk.py +3438 -0
- sage/combinat/schubert_polynomial.py +508 -0
- sage/combinat/set_partition.py +3318 -0
- sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
- sage/combinat/set_partition_iterator.pyx +136 -0
- sage/combinat/set_partition_ordered.py +1590 -0
- sage/combinat/sf/abreu_nigro.py +346 -0
- sage/combinat/sf/all.py +52 -0
- sage/combinat/sf/character.py +576 -0
- sage/combinat/sf/classical.py +319 -0
- sage/combinat/sf/dual.py +996 -0
- sage/combinat/sf/elementary.py +549 -0
- sage/combinat/sf/hall_littlewood.py +1028 -0
- sage/combinat/sf/hecke.py +336 -0
- sage/combinat/sf/homogeneous.py +464 -0
- sage/combinat/sf/jack.py +1428 -0
- sage/combinat/sf/k_dual.py +1458 -0
- sage/combinat/sf/kfpoly.py +447 -0
- sage/combinat/sf/llt.py +789 -0
- sage/combinat/sf/macdonald.py +2019 -0
- sage/combinat/sf/monomial.py +525 -0
- sage/combinat/sf/multiplicative.py +113 -0
- sage/combinat/sf/new_kschur.py +1786 -0
- sage/combinat/sf/ns_macdonald.py +964 -0
- sage/combinat/sf/orthogonal.py +246 -0
- sage/combinat/sf/orthotriang.py +355 -0
- sage/combinat/sf/powersum.py +963 -0
- sage/combinat/sf/schur.py +880 -0
- sage/combinat/sf/sf.py +1653 -0
- sage/combinat/sf/sfa.py +7053 -0
- sage/combinat/sf/symplectic.py +253 -0
- sage/combinat/sf/witt.py +721 -0
- sage/combinat/shifted_primed_tableau.py +2735 -0
- sage/combinat/shuffle.py +830 -0
- sage/combinat/sidon_sets.py +146 -0
- sage/combinat/similarity_class_type.py +1721 -0
- sage/combinat/sine_gordon.py +618 -0
- sage/combinat/six_vertex_model.py +784 -0
- sage/combinat/skew_partition.py +2053 -0
- sage/combinat/skew_tableau.py +2989 -0
- sage/combinat/sloane_functions.py +8935 -0
- sage/combinat/specht_module.py +1403 -0
- sage/combinat/species/all.py +48 -0
- sage/combinat/species/characteristic_species.py +321 -0
- sage/combinat/species/composition_species.py +273 -0
- sage/combinat/species/cycle_species.py +284 -0
- sage/combinat/species/empty_species.py +155 -0
- sage/combinat/species/functorial_composition_species.py +148 -0
- sage/combinat/species/generating_series.py +673 -0
- sage/combinat/species/library.py +148 -0
- sage/combinat/species/linear_order_species.py +169 -0
- sage/combinat/species/misc.py +83 -0
- sage/combinat/species/partition_species.py +290 -0
- sage/combinat/species/permutation_species.py +268 -0
- sage/combinat/species/product_species.py +423 -0
- sage/combinat/species/recursive_species.py +476 -0
- sage/combinat/species/set_species.py +192 -0
- sage/combinat/species/species.py +820 -0
- sage/combinat/species/structure.py +539 -0
- sage/combinat/species/subset_species.py +243 -0
- sage/combinat/species/sum_species.py +225 -0
- sage/combinat/subword.py +564 -0
- sage/combinat/subword_complex.py +2122 -0
- sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
- sage/combinat/subword_complex_c.pyx +119 -0
- sage/combinat/super_tableau.py +821 -0
- sage/combinat/superpartition.py +1154 -0
- sage/combinat/symmetric_group_algebra.py +3774 -0
- sage/combinat/symmetric_group_representations.py +1830 -0
- sage/combinat/t_sequences.py +877 -0
- sage/combinat/tableau.py +9506 -0
- sage/combinat/tableau_residues.py +860 -0
- sage/combinat/tableau_tuple.py +5353 -0
- sage/combinat/tiling.py +2432 -0
- sage/combinat/triangles_FHM.py +777 -0
- sage/combinat/tutorial.py +1857 -0
- sage/combinat/vector_partition.py +337 -0
- sage/combinat/words/abstract_word.py +1722 -0
- sage/combinat/words/all.py +59 -0
- sage/combinat/words/alphabet.py +268 -0
- sage/combinat/words/finite_word.py +7201 -0
- sage/combinat/words/infinite_word.py +113 -0
- sage/combinat/words/lyndon_word.py +652 -0
- sage/combinat/words/morphic.py +351 -0
- sage/combinat/words/morphism.py +3878 -0
- sage/combinat/words/paths.py +2932 -0
- sage/combinat/words/shuffle_product.py +278 -0
- sage/combinat/words/suffix_trees.py +1873 -0
- sage/combinat/words/word.py +769 -0
- sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_datatypes.pxd +4 -0
- sage/combinat/words/word_datatypes.pyx +1067 -0
- sage/combinat/words/word_generators.py +2026 -0
- sage/combinat/words/word_infinite_datatypes.py +1218 -0
- sage/combinat/words/word_options.py +99 -0
- sage/combinat/words/words.py +2396 -0
- sage/data_structures/all__sagemath_combinat.py +1 -0
- sage/databases/all__sagemath_combinat.py +13 -0
- sage/databases/findstat.py +4897 -0
- sage/databases/oeis.py +2058 -0
- sage/databases/sloane.py +393 -0
- sage/dynamics/all__sagemath_combinat.py +14 -0
- sage/dynamics/cellular_automata/all.py +7 -0
- sage/dynamics/cellular_automata/catalog.py +34 -0
- sage/dynamics/cellular_automata/elementary.py +612 -0
- sage/dynamics/cellular_automata/glca.py +477 -0
- sage/dynamics/cellular_automata/solitons.py +1463 -0
- sage/dynamics/finite_dynamical_system.py +1249 -0
- sage/dynamics/finite_dynamical_system_catalog.py +382 -0
- sage/games/all.py +7 -0
- sage/games/hexad.py +704 -0
- sage/games/quantumino.py +591 -0
- sage/games/sudoku.py +889 -0
- sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
- sage/games/sudoku_backtrack.pyx +189 -0
- sage/groups/all__sagemath_combinat.py +1 -0
- sage/groups/indexed_free_group.py +489 -0
- sage/libs/all__sagemath_combinat.py +6 -0
- sage/libs/lrcalc/__init__.py +1 -0
- sage/libs/lrcalc/lrcalc.py +525 -0
- sage/libs/symmetrica/__init__.py +7 -0
- sage/libs/symmetrica/all.py +101 -0
- sage/libs/symmetrica/kostka.pxi +168 -0
- sage/libs/symmetrica/part.pxi +193 -0
- sage/libs/symmetrica/plet.pxi +42 -0
- sage/libs/symmetrica/sab.pxi +196 -0
- sage/libs/symmetrica/sb.pxi +332 -0
- sage/libs/symmetrica/sc.pxi +192 -0
- sage/libs/symmetrica/schur.pxi +956 -0
- sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
- sage/libs/symmetrica/symmetrica.pxi +1172 -0
- sage/libs/symmetrica/symmetrica.pyx +39 -0
- sage/monoids/all.py +13 -0
- sage/monoids/automatic_semigroup.py +1054 -0
- sage/monoids/free_abelian_monoid.py +315 -0
- sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
- sage/monoids/free_abelian_monoid_element.pxd +16 -0
- sage/monoids/free_abelian_monoid_element.pyx +397 -0
- sage/monoids/free_monoid.py +335 -0
- sage/monoids/free_monoid_element.py +431 -0
- sage/monoids/hecke_monoid.py +65 -0
- sage/monoids/string_monoid.py +817 -0
- sage/monoids/string_monoid_element.py +547 -0
- sage/monoids/string_ops.py +143 -0
- sage/monoids/trace_monoid.py +972 -0
- sage/rings/all__sagemath_combinat.py +2 -0
- sage/sat/all.py +4 -0
- sage/sat/boolean_polynomials.py +405 -0
- sage/sat/converters/__init__.py +6 -0
- sage/sat/converters/anf2cnf.py +14 -0
- sage/sat/converters/polybori.py +611 -0
- sage/sat/solvers/__init__.py +5 -0
- sage/sat/solvers/cryptominisat.py +287 -0
- sage/sat/solvers/dimacs.py +783 -0
- sage/sat/solvers/picosat.py +228 -0
- sage/sat/solvers/sat_lp.py +156 -0
- sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
|
@@ -0,0 +1,2932 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Word paths
|
|
5
|
+
|
|
6
|
+
This module implements word paths, which is an application of Combinatorics
|
|
7
|
+
on Words to Discrete Geometry. A word path is the representation of a word
|
|
8
|
+
as a discrete path in a vector space using a one-to-one correspondence
|
|
9
|
+
between the alphabet and a set of vectors called steps. Many problems
|
|
10
|
+
surrounding 2d lattice polygons (such as questions of self-intersection,
|
|
11
|
+
area, inertia moment, etc.) can be solved in linear time (linear in the
|
|
12
|
+
length of the perimeter) using theory from Combinatorics on Words.
|
|
13
|
+
|
|
14
|
+
On the square grid, the encoding of a path using a four-letter alphabet
|
|
15
|
+
(for East, North, West and South directions) is also known as the Freeman
|
|
16
|
+
chain code [1,2] (see [3] for further reading).
|
|
17
|
+
|
|
18
|
+
AUTHORS:
|
|
19
|
+
|
|
20
|
+
- Arnaud Bergeron (2008) : Initial version, path on the square grid
|
|
21
|
+
|
|
22
|
+
- Sébastien Labbé (2009-01-14) : New classes and hierarchy, doc and functions.
|
|
23
|
+
|
|
24
|
+
EXAMPLES:
|
|
25
|
+
|
|
26
|
+
The combinatorial class of all paths defined over three given steps::
|
|
27
|
+
|
|
28
|
+
sage: P = WordPaths('abc', steps=[(1,2), (-3,4), (0,-3)]); P
|
|
29
|
+
Word Paths over 3 steps
|
|
30
|
+
|
|
31
|
+
This defines a one-to-one correspondence between alphabet and steps::
|
|
32
|
+
|
|
33
|
+
sage: d = P.letters_to_steps()
|
|
34
|
+
sage: sorted(d.items())
|
|
35
|
+
[('a', (1, 2)), ('b', (-3, 4)), ('c', (0, -3))]
|
|
36
|
+
|
|
37
|
+
Creation of a path from the combinatorial class P defined above::
|
|
38
|
+
|
|
39
|
+
sage: p = P('abaccba'); p
|
|
40
|
+
Path: abaccba
|
|
41
|
+
|
|
42
|
+
Many functions can be used on p: the coordinates of its trajectory,
|
|
43
|
+
ask whether p is a closed path, plot it and many other::
|
|
44
|
+
|
|
45
|
+
sage: list(p.points())
|
|
46
|
+
[(0, 0), (1, 2), (-2, 6), (-1, 8), (-1, 5), (-1, 2), (-4, 6), (-3, 8)]
|
|
47
|
+
sage: p.is_closed()
|
|
48
|
+
False
|
|
49
|
+
sage: p.plot() # needs sage.plot
|
|
50
|
+
Graphics object consisting of 3 graphics primitives
|
|
51
|
+
|
|
52
|
+
To obtain a list of all the available word path specific functions,
|
|
53
|
+
use ``help(p)``::
|
|
54
|
+
|
|
55
|
+
sage: help(p)
|
|
56
|
+
Help on FiniteWordPath_2d_str in module sage.combinat.words.paths object:
|
|
57
|
+
...
|
|
58
|
+
Methods inherited from FiniteWordPath_2d:
|
|
59
|
+
...
|
|
60
|
+
Methods inherited from FiniteWordPath_all:
|
|
61
|
+
...
|
|
62
|
+
|
|
63
|
+
Since p is a finite word, many functions from the word library are available::
|
|
64
|
+
|
|
65
|
+
sage: p.crochemore_factorization()
|
|
66
|
+
(a, b, a, c, c, ba)
|
|
67
|
+
sage: p.is_palindrome()
|
|
68
|
+
False
|
|
69
|
+
sage: p[:3]
|
|
70
|
+
Path: aba
|
|
71
|
+
sage: len(p)
|
|
72
|
+
7
|
|
73
|
+
|
|
74
|
+
P also herits many functions from Words::
|
|
75
|
+
|
|
76
|
+
sage: P = WordPaths('rs', steps=[(1,2), (-1,4)]); P
|
|
77
|
+
Word Paths over 2 steps
|
|
78
|
+
sage: P.alphabet()
|
|
79
|
+
{'r', 's'}
|
|
80
|
+
sage: list(P.iterate_by_length(3))
|
|
81
|
+
[Path: rrr,
|
|
82
|
+
Path: rrs,
|
|
83
|
+
Path: rsr,
|
|
84
|
+
Path: rss,
|
|
85
|
+
Path: srr,
|
|
86
|
+
Path: srs,
|
|
87
|
+
Path: ssr,
|
|
88
|
+
Path: sss]
|
|
89
|
+
|
|
90
|
+
When the number of given steps is half the size of alphabet, the
|
|
91
|
+
opposite of vectors are used::
|
|
92
|
+
|
|
93
|
+
sage: P = WordPaths('abcd', [(1,0), (0,1)])
|
|
94
|
+
sage: sorted(P.letters_to_steps().items())
|
|
95
|
+
[('a', (1, 0)), ('b', (0, 1)), ('c', (-1, 0)), ('d', (0, -1))]
|
|
96
|
+
|
|
97
|
+
Some built-in combinatorial classes of paths::
|
|
98
|
+
|
|
99
|
+
sage: P = WordPaths('abAB', steps='square_grid'); P
|
|
100
|
+
Word Paths on the square grid
|
|
101
|
+
|
|
102
|
+
::
|
|
103
|
+
|
|
104
|
+
sage: D = WordPaths('()', steps='dyck'); D
|
|
105
|
+
Finite Dyck paths
|
|
106
|
+
sage: d = D('()()()(())'); d
|
|
107
|
+
Path: ()()()(())
|
|
108
|
+
sage: d.plot() # needs sage.plot
|
|
109
|
+
Graphics object consisting of 3 graphics primitives
|
|
110
|
+
|
|
111
|
+
::
|
|
112
|
+
|
|
113
|
+
sage: # needs sage.rings.number_field
|
|
114
|
+
sage: P = WordPaths('abcdef', steps='triangle_grid')
|
|
115
|
+
sage: p = P('babaddefadabcadefaadfafabacdefa')
|
|
116
|
+
sage: p.plot() # needs sage.plot
|
|
117
|
+
Graphics object consisting of 3 graphics primitives
|
|
118
|
+
|
|
119
|
+
Vector steps may be in more than 2 dimensions::
|
|
120
|
+
|
|
121
|
+
sage: d = [(1,0,0), (0,1,0), (0,0,1)]
|
|
122
|
+
sage: P = WordPaths(alphabet='abc', steps=d); P
|
|
123
|
+
Word Paths over 3 steps
|
|
124
|
+
sage: p = P('abcabcabcabcaabacabcababcacbabacacabcaccbcac')
|
|
125
|
+
sage: p.plot() # needs sage.plot
|
|
126
|
+
Graphics3d Object
|
|
127
|
+
|
|
128
|
+
::
|
|
129
|
+
|
|
130
|
+
sage: d = [(1,3,5,1), (-5,1,-6,0), (0,0,1,9), (4,2,-1,0)]
|
|
131
|
+
sage: P = WordPaths(alphabet='rstu', steps=d); P
|
|
132
|
+
Word Paths over 4 steps
|
|
133
|
+
sage: p = P('rtusuusususuturrsust'); p
|
|
134
|
+
Path: rtusuusususuturrsust
|
|
135
|
+
sage: p.end_point()
|
|
136
|
+
(5, 31, -26, 30)
|
|
137
|
+
|
|
138
|
+
::
|
|
139
|
+
|
|
140
|
+
sage: CubePaths = WordPaths('abcABC', steps='cube_grid'); CubePaths
|
|
141
|
+
Word Paths on the cube grid
|
|
142
|
+
sage: CubePaths('abcabaabcabAAAAA').plot() # needs sage.plot
|
|
143
|
+
Graphics3d Object
|
|
144
|
+
|
|
145
|
+
The input data may be a str, a list, a tuple,
|
|
146
|
+
a callable or a finite iterator::
|
|
147
|
+
|
|
148
|
+
sage: P = WordPaths([0, 1, 2, 3])
|
|
149
|
+
sage: P([0,1,2,3,2,1,2,3,2])
|
|
150
|
+
Path: 012321232
|
|
151
|
+
sage: P((0,1,2,3,2,1,2,3,2))
|
|
152
|
+
Path: 012321232
|
|
153
|
+
sage: P(lambda n:n%4, length=10)
|
|
154
|
+
Path: 0123012301
|
|
155
|
+
sage: P(iter([0,3,2,1]), length='finite')
|
|
156
|
+
Path: 0321
|
|
157
|
+
|
|
158
|
+
REFERENCES:
|
|
159
|
+
|
|
160
|
+
- [1] Freeman, H.: *On the encoding of arbitrary geometric configurations*.
|
|
161
|
+
IRE Trans. Electronic Computer 10 (1961) 260-268.
|
|
162
|
+
- [2] Freeman, H.: *Boundary encoding and processing*. In Lipkin, B., Rosenfeld,
|
|
163
|
+
A., eds.: Picture Processing and Psychopictorics, Academic Press, New York
|
|
164
|
+
(1970) 241-266.
|
|
165
|
+
- [3] Braquelaire, J.P., Vialard, A.: *Euclidean paths: A new representation of
|
|
166
|
+
boundary of discrete regions*. Graphical Models and Image Processing 61 (1999)
|
|
167
|
+
16-43.
|
|
168
|
+
- [4] :wikipedia:`Regular_tiling`
|
|
169
|
+
- [5] :wikipedia:`Dyck_word`
|
|
170
|
+
"""
|
|
171
|
+
# ****************************************************************************
|
|
172
|
+
# Copyright (C) 2008 Arnaud bergeron <abergeron@gmail.coms>,
|
|
173
|
+
# Copyright (C) 2009 Sebastien Labbe <slabqc@gmail.com>,
|
|
174
|
+
#
|
|
175
|
+
# This program is free software: you can redistribute it and/or modify
|
|
176
|
+
# it under the terms of the GNU General Public License as published by
|
|
177
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
178
|
+
# (at your option) any later version.
|
|
179
|
+
# https://www.gnu.org/licenses/
|
|
180
|
+
# ****************************************************************************
|
|
181
|
+
|
|
182
|
+
from sage.structure.sage_object import SageObject
|
|
183
|
+
from sage.misc.cachefunc import cached_method
|
|
184
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
|
185
|
+
from sage.combinat.words.words import FiniteWords
|
|
186
|
+
from sage.combinat.words.word import FiniteWord_class
|
|
187
|
+
from sage.combinat.words.alphabet import build_alphabet
|
|
188
|
+
from sage.misc.lazy_import import lazy_import
|
|
189
|
+
from sage.modules.free_module_element import vector
|
|
190
|
+
from sage.rings.integer_ring import ZZ
|
|
191
|
+
from sage.rings.real_mpfr import RR
|
|
192
|
+
from .word_datatypes import (WordDatatype_str,
|
|
193
|
+
WordDatatype_list,
|
|
194
|
+
WordDatatype_tuple)
|
|
195
|
+
# WordDatatype_cpp_basic_string)
|
|
196
|
+
|
|
197
|
+
from .word_infinite_datatypes import (
|
|
198
|
+
WordDatatype_iter_with_caching,
|
|
199
|
+
WordDatatype_iter,
|
|
200
|
+
WordDatatype_callable_with_caching,
|
|
201
|
+
WordDatatype_callable)
|
|
202
|
+
from sage.matrix.constructor import vector_on_axis_rotation_matrix
|
|
203
|
+
|
|
204
|
+
lazy_import("sage.plot.all", ["arrow", "line", "polygon", "point", "Graphics"])
|
|
205
|
+
lazy_import('sage.rings.number_field.number_field', 'QuadraticField')
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
#######################################################################
|
|
209
|
+
# #
|
|
210
|
+
# WordPaths function #
|
|
211
|
+
# #
|
|
212
|
+
#######################################################################
|
|
213
|
+
|
|
214
|
+
def WordPaths(alphabet, steps=None):
|
|
215
|
+
r"""
|
|
216
|
+
Return the combinatorial class of paths of the given type of steps.
|
|
217
|
+
|
|
218
|
+
INPUT:
|
|
219
|
+
|
|
220
|
+
- ``alphabet`` -- ordered alphabet
|
|
221
|
+
|
|
222
|
+
- ``steps`` -- (default: ``None``) it can be one of the following:
|
|
223
|
+
|
|
224
|
+
- an iterable ordered container of as many vectors as there are
|
|
225
|
+
letters in the alphabet. The vectors are associated to the letters
|
|
226
|
+
according to their order in steps. The vectors can be a tuple or
|
|
227
|
+
anything that can be passed to vector function.
|
|
228
|
+
|
|
229
|
+
- an iterable ordered container of k vectors where k is half the
|
|
230
|
+
size of alphabet. The vectors and their opposites are associated
|
|
231
|
+
to the letters according to their order in steps (given vectors
|
|
232
|
+
first, opposite vectors after).
|
|
233
|
+
|
|
234
|
+
- ``None`` -- in this case, the type of steps are guessed from the
|
|
235
|
+
length of alphabet
|
|
236
|
+
|
|
237
|
+
- ``'square_grid'`` or ``'square'`` -- (default when size of alphabet is 4)
|
|
238
|
+
The order is : East, North, West, South.
|
|
239
|
+
|
|
240
|
+
- ``'triangle_grid'`` or ``'triangle'``
|
|
241
|
+
|
|
242
|
+
- ``'hexagonal_grid'`` or ``'hexagon'`` -- (default when size of alphabet is 6)
|
|
243
|
+
|
|
244
|
+
- ``'cube_grid'`` or ``'cube'``
|
|
245
|
+
|
|
246
|
+
- ``'north_east'``, ``'ne'`` or ``'NE'`` -- (the default when size of alphabet is 2)
|
|
247
|
+
|
|
248
|
+
- ``'dyck'``
|
|
249
|
+
|
|
250
|
+
OUTPUT: the combinatorial class of all paths of the given type
|
|
251
|
+
|
|
252
|
+
EXAMPLES:
|
|
253
|
+
|
|
254
|
+
The steps can be given explicitly::
|
|
255
|
+
|
|
256
|
+
sage: WordPaths('abc', steps=[(1,2), (-1,4), (0,-3)])
|
|
257
|
+
Word Paths over 3 steps
|
|
258
|
+
|
|
259
|
+
Different type of input alphabet::
|
|
260
|
+
|
|
261
|
+
sage: WordPaths(range(3), steps=[(1,2), (-1,4), (0,-3)])
|
|
262
|
+
Word Paths over 3 steps
|
|
263
|
+
sage: WordPaths(['cric','crac','croc'], steps=[(1,2), (1,4), (0,3)])
|
|
264
|
+
Word Paths over 3 steps
|
|
265
|
+
|
|
266
|
+
Directions can be in three dimensions as well::
|
|
267
|
+
|
|
268
|
+
sage: WordPaths('ab', steps=[(1,2,2),(-1,4,2)])
|
|
269
|
+
Word Paths over 2 steps
|
|
270
|
+
|
|
271
|
+
When the number of given steps is half the size of alphabet, the
|
|
272
|
+
opposite of vectors are used::
|
|
273
|
+
|
|
274
|
+
sage: P = WordPaths('abcd', [(1,0), (0,1)])
|
|
275
|
+
sage: P
|
|
276
|
+
Word Paths over 4 steps
|
|
277
|
+
sage: sorted(P.letters_to_steps().items())
|
|
278
|
+
[('a', (1, 0)), ('b', (0, 1)), ('c', (-1, 0)), ('d', (0, -1))]
|
|
279
|
+
|
|
280
|
+
When no steps are given, default classes are returned::
|
|
281
|
+
|
|
282
|
+
sage: WordPaths('ab')
|
|
283
|
+
Word Paths in North and East steps
|
|
284
|
+
sage: WordPaths(range(4))
|
|
285
|
+
Word Paths on the square grid
|
|
286
|
+
sage: WordPaths(range(6)) # needs sage.rings.number_field
|
|
287
|
+
Word Paths on the hexagonal grid
|
|
288
|
+
|
|
289
|
+
There are many type of built-in steps...
|
|
290
|
+
|
|
291
|
+
On a two letters alphabet::
|
|
292
|
+
|
|
293
|
+
sage: WordPaths('ab', steps='north_east')
|
|
294
|
+
Word Paths in North and East steps
|
|
295
|
+
sage: WordPaths('()', steps='dyck')
|
|
296
|
+
Finite Dyck paths
|
|
297
|
+
|
|
298
|
+
On a four letters alphabet::
|
|
299
|
+
|
|
300
|
+
sage: WordPaths('ruld', steps='square_grid')
|
|
301
|
+
Word Paths on the square grid
|
|
302
|
+
|
|
303
|
+
On a six letters alphabet::
|
|
304
|
+
|
|
305
|
+
sage: WordPaths('abcdef', steps='hexagonal_grid') # needs sage.rings.number_field
|
|
306
|
+
Word Paths on the hexagonal grid
|
|
307
|
+
sage: WordPaths('abcdef', steps='triangle_grid') # needs sage.rings.number_field
|
|
308
|
+
Word Paths on the triangle grid
|
|
309
|
+
sage: WordPaths('abcdef', steps='cube_grid')
|
|
310
|
+
Word Paths on the cube grid
|
|
311
|
+
|
|
312
|
+
TESTS::
|
|
313
|
+
|
|
314
|
+
sage: WordPaths(range(5))
|
|
315
|
+
Traceback (most recent call last):
|
|
316
|
+
...
|
|
317
|
+
TypeError: Unable to make a class WordPaths from {0, 1, 2, 3, 4}
|
|
318
|
+
sage: WordPaths('abAB', steps='square_gridd')
|
|
319
|
+
Traceback (most recent call last):
|
|
320
|
+
...
|
|
321
|
+
TypeError: Unknown type of steps : square_gridd
|
|
322
|
+
"""
|
|
323
|
+
# Construction of the alphabet
|
|
324
|
+
alphabet = build_alphabet(alphabet)
|
|
325
|
+
|
|
326
|
+
# If no steps are given, they are guessed from the alphabet
|
|
327
|
+
if steps is None:
|
|
328
|
+
if alphabet.cardinality() == 2:
|
|
329
|
+
steps = 'north_east'
|
|
330
|
+
elif alphabet.cardinality() == 4:
|
|
331
|
+
steps = 'square_grid'
|
|
332
|
+
elif alphabet.cardinality() == 6:
|
|
333
|
+
steps = 'hexagonal_grid'
|
|
334
|
+
else:
|
|
335
|
+
raise TypeError("Unable to make a class WordPaths from %s" % alphabet)
|
|
336
|
+
|
|
337
|
+
# Return the class of WordPaths according to the given type of paths
|
|
338
|
+
if isinstance(steps, str):
|
|
339
|
+
if steps in ('square_grid', 'square'):
|
|
340
|
+
return WordPaths_square_grid(alphabet=alphabet)
|
|
341
|
+
elif steps in ('triangle_grid', 'triangle'):
|
|
342
|
+
return WordPaths_triangle_grid(alphabet=alphabet)
|
|
343
|
+
elif steps in ('hexagonal_grid', 'hexagon'):
|
|
344
|
+
return WordPaths_hexagonal_grid(alphabet=alphabet)
|
|
345
|
+
elif steps in ('cube_grid', 'cube'):
|
|
346
|
+
return WordPaths_cube_grid(alphabet=alphabet)
|
|
347
|
+
elif steps in ('north_east', 'ne', 'NE'):
|
|
348
|
+
return WordPaths_north_east(alphabet=alphabet)
|
|
349
|
+
elif steps == 'dyck':
|
|
350
|
+
return WordPaths_dyck(alphabet=alphabet)
|
|
351
|
+
else:
|
|
352
|
+
raise TypeError("Unknown type of steps : %s" % steps)
|
|
353
|
+
else:
|
|
354
|
+
return WordPaths_all(alphabet=alphabet, steps=steps)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
#######################################################################
|
|
358
|
+
# #
|
|
359
|
+
# Combinatorial classes of word paths #
|
|
360
|
+
# #
|
|
361
|
+
#######################################################################
|
|
362
|
+
|
|
363
|
+
class WordPaths_all(FiniteWords):
|
|
364
|
+
r"""
|
|
365
|
+
The combinatorial class of all paths, i.e of all words over
|
|
366
|
+
an alphabet where each letter is mapped to a step (a vector).
|
|
367
|
+
"""
|
|
368
|
+
def __init__(self, alphabet, steps):
|
|
369
|
+
r"""
|
|
370
|
+
INPUT:
|
|
371
|
+
|
|
372
|
+
- ``alphabet`` -- an ordered alphabet
|
|
373
|
+
|
|
374
|
+
- ``steps`` -- an iterable (of same length as alphabet or half the
|
|
375
|
+
length of alphabet) of ordered vectors
|
|
376
|
+
|
|
377
|
+
EXAMPLES::
|
|
378
|
+
|
|
379
|
+
sage: from sage.combinat.words.paths import WordPaths_all
|
|
380
|
+
sage: d = ((1,1), (-1,1), (1,-1), (-1,-1))
|
|
381
|
+
sage: P = WordPaths_all('abAB', d); P
|
|
382
|
+
Word Paths over 4 steps
|
|
383
|
+
sage: P == loads(dumps(P))
|
|
384
|
+
True
|
|
385
|
+
|
|
386
|
+
If size of alphabet is twice the number of steps, then opposite
|
|
387
|
+
vectors are used for the second part of the alphabet::
|
|
388
|
+
|
|
389
|
+
sage: WordPaths('abcd',[(2,1),(2,4)])
|
|
390
|
+
Word Paths over 4 steps
|
|
391
|
+
sage: _.letters_to_steps()
|
|
392
|
+
{'a': (2, 1), 'b': (2, 4), 'c': (-2, -1), 'd': (-2, -4)}
|
|
393
|
+
|
|
394
|
+
TESTS::
|
|
395
|
+
|
|
396
|
+
sage: from sage.combinat.words.paths import WordPaths_all
|
|
397
|
+
sage: d = ((1,1), (-1,1), (1,-1), (-1,-1))
|
|
398
|
+
sage: WordPaths_all('abA', d)
|
|
399
|
+
Traceback (most recent call last):
|
|
400
|
+
...
|
|
401
|
+
TypeError: size of steps (=4) must equal the size of alphabet (=3) or half the size of alphabet
|
|
402
|
+
|
|
403
|
+
sage: d = ((1,1), 1)
|
|
404
|
+
sage: WordPaths_all('ab', d)
|
|
405
|
+
Traceback (most recent call last):
|
|
406
|
+
...
|
|
407
|
+
ValueError: cannot make vectors from steps
|
|
408
|
+
|
|
409
|
+
sage: d = ((1,1), (-1,1,0))
|
|
410
|
+
sage: WordPaths_all('ab', d)
|
|
411
|
+
Traceback (most recent call last):
|
|
412
|
+
...
|
|
413
|
+
ValueError: cannot make summable vectors from steps
|
|
414
|
+
"""
|
|
415
|
+
# Construction of the words class
|
|
416
|
+
FiniteWords.__init__(self, alphabet)
|
|
417
|
+
alphabet = self.alphabet()
|
|
418
|
+
|
|
419
|
+
# Checking the size of alphabet and steps
|
|
420
|
+
ls = len(steps)
|
|
421
|
+
la = alphabet.cardinality()
|
|
422
|
+
if la != ls and la != 2 * ls:
|
|
423
|
+
raise TypeError("size of steps (=%s) must equal the size of alphabet (=%s) or half the size of alphabet" % (len(steps), alphabet.cardinality()))
|
|
424
|
+
|
|
425
|
+
# Construction of the steps
|
|
426
|
+
from sage.structure.element import Vector
|
|
427
|
+
if all(isinstance(x, Vector) for x in steps):
|
|
428
|
+
vsteps = steps
|
|
429
|
+
else:
|
|
430
|
+
try:
|
|
431
|
+
vsteps = [vector(s) for s in steps]
|
|
432
|
+
except (TypeError):
|
|
433
|
+
raise ValueError("cannot make vectors from steps")
|
|
434
|
+
try:
|
|
435
|
+
s = sum(vsteps)
|
|
436
|
+
except (TypeError, AttributeError):
|
|
437
|
+
raise ValueError("cannot make summable vectors from steps")
|
|
438
|
+
|
|
439
|
+
# Complete vsteps with the opposite vectors if needed
|
|
440
|
+
if la == 2 * ls:
|
|
441
|
+
vsteps += [-v for v in vsteps]
|
|
442
|
+
|
|
443
|
+
self._steps = dict(zip(alphabet, vsteps))
|
|
444
|
+
self._vector_space = s.parent()
|
|
445
|
+
|
|
446
|
+
def __eq__(self, other):
|
|
447
|
+
r"""
|
|
448
|
+
TESTS::
|
|
449
|
+
|
|
450
|
+
sage: W1 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
|
|
451
|
+
sage: W2 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
|
|
452
|
+
sage: W3 = WordPaths(['a','b'], [vector((0,2)), vector((1,0))])
|
|
453
|
+
sage: W1 == W2
|
|
454
|
+
True
|
|
455
|
+
sage: W1 == W3
|
|
456
|
+
False
|
|
457
|
+
"""
|
|
458
|
+
return self is other or (type(self) is type(other) and
|
|
459
|
+
self.alphabet() == other.alphabet() and
|
|
460
|
+
self.vector_space() == other.vector_space() and
|
|
461
|
+
self.letters_to_steps() == other.letters_to_steps())
|
|
462
|
+
|
|
463
|
+
def __ne__(self, other):
|
|
464
|
+
r"""
|
|
465
|
+
TESTS::
|
|
466
|
+
|
|
467
|
+
sage: W1 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
|
|
468
|
+
sage: W2 = WordPaths(['a','b'], [vector((0,1)), vector((0,2))])
|
|
469
|
+
sage: W3 = WordPaths(['a','b'], [vector((0,2)), vector((1,0))])
|
|
470
|
+
sage: W1 != W2
|
|
471
|
+
False
|
|
472
|
+
sage: W1 != W3
|
|
473
|
+
True
|
|
474
|
+
"""
|
|
475
|
+
return not (self == other)
|
|
476
|
+
|
|
477
|
+
@lazy_attribute
|
|
478
|
+
def _element_classes(self):
|
|
479
|
+
r"""
|
|
480
|
+
Return a dictionary that gives the class of the elements of ``self``.
|
|
481
|
+
|
|
482
|
+
The word may be finite (infinite or of unknown length is not supported
|
|
483
|
+
yet).
|
|
484
|
+
Its data may be str, list, tuple, a callable or an iterable.
|
|
485
|
+
For callable and iterable, the data may be cached.
|
|
486
|
+
The dimension of the path may be 1, 2, 3 or more.
|
|
487
|
+
|
|
488
|
+
TESTS::
|
|
489
|
+
|
|
490
|
+
sage: d = WordPaths('ab',steps=[(1,2),(3,4)])._element_classes
|
|
491
|
+
sage: type(d)
|
|
492
|
+
<class 'dict'>
|
|
493
|
+
sage: len(d)
|
|
494
|
+
7
|
|
495
|
+
sage: d['tuple']
|
|
496
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_2d_tuple'>
|
|
497
|
+
|
|
498
|
+
::
|
|
499
|
+
|
|
500
|
+
sage: d = WordPaths('ab',steps=[(1,2,3),(3,4,5)])._element_classes
|
|
501
|
+
sage: len(d)
|
|
502
|
+
7
|
|
503
|
+
sage: d['tuple']
|
|
504
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_3d_tuple'>
|
|
505
|
+
|
|
506
|
+
::
|
|
507
|
+
|
|
508
|
+
sage: steps = [(1,2,3,4),(3,4,5,6)]
|
|
509
|
+
sage: d = WordPaths('ab',steps=steps)._element_classes
|
|
510
|
+
sage: len(d)
|
|
511
|
+
7
|
|
512
|
+
sage: d['tuple']
|
|
513
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_all_tuple'>
|
|
514
|
+
|
|
515
|
+
::
|
|
516
|
+
|
|
517
|
+
sage: d = WordPaths('ab',steps=[(1,),(3,)])._element_classes
|
|
518
|
+
sage: len(d)
|
|
519
|
+
7
|
|
520
|
+
sage: d['tuple']
|
|
521
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_all_tuple'>
|
|
522
|
+
"""
|
|
523
|
+
dimension = self._vector_space.dimension()
|
|
524
|
+
if dimension == 2:
|
|
525
|
+
return {
|
|
526
|
+
'list': FiniteWordPath_2d_list,
|
|
527
|
+
'str': FiniteWordPath_2d_str,
|
|
528
|
+
'tuple': FiniteWordPath_2d_tuple,
|
|
529
|
+
'callable_with_caching': FiniteWordPath_2d_callable_with_caching,
|
|
530
|
+
'callable': FiniteWordPath_2d_callable,
|
|
531
|
+
'iter_with_caching': FiniteWordPath_2d_iter_with_caching,
|
|
532
|
+
'iter': FiniteWordPath_2d_iter,
|
|
533
|
+
}
|
|
534
|
+
elif dimension == 3:
|
|
535
|
+
return {
|
|
536
|
+
'list': FiniteWordPath_3d_list,
|
|
537
|
+
'str': FiniteWordPath_3d_str,
|
|
538
|
+
'tuple': FiniteWordPath_3d_tuple,
|
|
539
|
+
'callable_with_caching': FiniteWordPath_3d_callable_with_caching,
|
|
540
|
+
'callable': FiniteWordPath_3d_callable,
|
|
541
|
+
'iter_with_caching': FiniteWordPath_3d_iter_with_caching,
|
|
542
|
+
'iter': FiniteWordPath_3d_iter,
|
|
543
|
+
}
|
|
544
|
+
else:
|
|
545
|
+
return {
|
|
546
|
+
'list': FiniteWordPath_all_list,
|
|
547
|
+
'str': FiniteWordPath_all_str,
|
|
548
|
+
'tuple': FiniteWordPath_all_tuple,
|
|
549
|
+
'callable_with_caching': FiniteWordPath_all_callable_with_caching,
|
|
550
|
+
'callable': FiniteWordPath_all_callable,
|
|
551
|
+
'iter_with_caching': FiniteWordPath_all_iter_with_caching,
|
|
552
|
+
'iter': FiniteWordPath_all_iter,
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
def __repr__(self) -> str:
|
|
556
|
+
r"""
|
|
557
|
+
Return a string representation of ``self``.
|
|
558
|
+
|
|
559
|
+
EXAMPLES::
|
|
560
|
+
|
|
561
|
+
sage: from sage.combinat.words.paths import WordPaths_all
|
|
562
|
+
sage: d = (vector((1,1)), vector((-1,1)), vector((1,-1)), vector((-1,-1)))
|
|
563
|
+
sage: WordPaths_all('abAB',d).__repr__()
|
|
564
|
+
'Word Paths over 4 steps'
|
|
565
|
+
"""
|
|
566
|
+
return "Word Paths over %s steps" % self.alphabet().cardinality()
|
|
567
|
+
|
|
568
|
+
def letters_to_steps(self) -> dict:
|
|
569
|
+
r"""
|
|
570
|
+
Return the dictionary mapping letters to vectors (steps).
|
|
571
|
+
|
|
572
|
+
EXAMPLES::
|
|
573
|
+
|
|
574
|
+
sage: d = WordPaths('ab').letters_to_steps()
|
|
575
|
+
sage: sorted(d.items())
|
|
576
|
+
[('a', (0, 1)), ('b', (1, 0))]
|
|
577
|
+
sage: d = WordPaths('abcd').letters_to_steps()
|
|
578
|
+
sage: sorted(d.items())
|
|
579
|
+
[('a', (1, 0)), ('b', (0, 1)), ('c', (-1, 0)), ('d', (0, -1))]
|
|
580
|
+
sage: d = WordPaths('abcdef').letters_to_steps() # needs sage.rings.number_field
|
|
581
|
+
sage: sorted(d.items()) # needs sage.rings.number_field
|
|
582
|
+
[('a', (1, 0)),
|
|
583
|
+
('b', (1/2, 1/2*sqrt3)),
|
|
584
|
+
('c', (-1/2, 1/2*sqrt3)),
|
|
585
|
+
('d', (-1, 0)),
|
|
586
|
+
('e', (-1/2, -1/2*sqrt3)),
|
|
587
|
+
('f', (1/2, -1/2*sqrt3))]
|
|
588
|
+
"""
|
|
589
|
+
return self._steps
|
|
590
|
+
|
|
591
|
+
def vector_space(self):
|
|
592
|
+
r"""
|
|
593
|
+
Return the vector space over which the steps of the paths are defined.
|
|
594
|
+
|
|
595
|
+
EXAMPLES::
|
|
596
|
+
|
|
597
|
+
sage: WordPaths('ab',steps='dyck').vector_space()
|
|
598
|
+
Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
599
|
+
sage: WordPaths('ab',steps='north_east').vector_space()
|
|
600
|
+
Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
601
|
+
sage: WordPaths('abcd',steps='square_grid').vector_space()
|
|
602
|
+
Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
603
|
+
sage: WordPaths('abcdef',steps='hexagonal_grid').vector_space() # needs sage.rings.number_field
|
|
604
|
+
Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?
|
|
605
|
+
sage: WordPaths('abcdef',steps='cube_grid').vector_space()
|
|
606
|
+
Ambient free module of rank 3 over the principal ideal domain Integer Ring
|
|
607
|
+
sage: WordPaths('abcdef',steps='triangle_grid').vector_space() # needs sage.rings.number_field
|
|
608
|
+
Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?
|
|
609
|
+
"""
|
|
610
|
+
return self._vector_space
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
class WordPaths_square_grid(WordPaths_all):
|
|
614
|
+
r"""
|
|
615
|
+
The combinatorial class of all paths on the square grid.
|
|
616
|
+
"""
|
|
617
|
+
def __init__(self, alphabet):
|
|
618
|
+
r"""
|
|
619
|
+
The combinatorial class of all finite paths on the square grid.
|
|
620
|
+
|
|
621
|
+
INPUT:
|
|
622
|
+
|
|
623
|
+
- ``alphabet`` -- ordered alphabet of length 4; the order for the steps
|
|
624
|
+
is : East, North, West, South
|
|
625
|
+
|
|
626
|
+
EXAMPLES::
|
|
627
|
+
|
|
628
|
+
sage: from sage.combinat.words.paths import WordPaths_square_grid
|
|
629
|
+
sage: P = WordPaths_square_grid('abAB'); P
|
|
630
|
+
Word Paths on the square grid
|
|
631
|
+
sage: P == loads(dumps(P))
|
|
632
|
+
True
|
|
633
|
+
"""
|
|
634
|
+
# Construction of the steps
|
|
635
|
+
d = [(1, 0), (0, 1), (-1, 0), (0, -1)]
|
|
636
|
+
|
|
637
|
+
# Construction of the class
|
|
638
|
+
super().__init__(alphabet, steps=d)
|
|
639
|
+
|
|
640
|
+
@lazy_attribute
|
|
641
|
+
def _element_classes(self):
|
|
642
|
+
r"""
|
|
643
|
+
Return a dictionary that gives the class of the elements of ``self``.
|
|
644
|
+
|
|
645
|
+
The word may be finite (infinite or of unknown length is not supported
|
|
646
|
+
yet).
|
|
647
|
+
Its data may be str, list, tuple, a callable or an iterable.
|
|
648
|
+
For callable and iterable, the data may be cached.
|
|
649
|
+
|
|
650
|
+
TESTS::
|
|
651
|
+
|
|
652
|
+
sage: d = WordPaths('abcd')._element_classes
|
|
653
|
+
sage: type(d)
|
|
654
|
+
<class 'dict'>
|
|
655
|
+
sage: len(d)
|
|
656
|
+
7
|
|
657
|
+
sage: d['tuple']
|
|
658
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_square_grid_tuple'>
|
|
659
|
+
"""
|
|
660
|
+
return {
|
|
661
|
+
'list': FiniteWordPath_square_grid_list,
|
|
662
|
+
'str': FiniteWordPath_square_grid_str,
|
|
663
|
+
'tuple': FiniteWordPath_square_grid_tuple,
|
|
664
|
+
'callable_with_caching': FiniteWordPath_square_grid_callable_with_caching,
|
|
665
|
+
'callable': FiniteWordPath_square_grid_callable,
|
|
666
|
+
'iter_with_caching': FiniteWordPath_square_grid_iter_with_caching,
|
|
667
|
+
'iter': FiniteWordPath_square_grid_iter,
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
def __repr__(self) -> str:
|
|
671
|
+
r"""
|
|
672
|
+
EXAMPLES::
|
|
673
|
+
|
|
674
|
+
sage: from sage.combinat.words.paths import WordPaths_square_grid
|
|
675
|
+
sage: WordPaths_square_grid('abAB').__repr__()
|
|
676
|
+
'Word Paths on the square grid'
|
|
677
|
+
"""
|
|
678
|
+
return "Word Paths on the square grid"
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
class WordPaths_triangle_grid(WordPaths_all):
|
|
682
|
+
r"""
|
|
683
|
+
The combinatorial class of all paths on the triangle grid.
|
|
684
|
+
"""
|
|
685
|
+
def __init__(self, alphabet):
|
|
686
|
+
r"""
|
|
687
|
+
The combinatorial class of all finite paths on the triangle grid.
|
|
688
|
+
|
|
689
|
+
INPUT:
|
|
690
|
+
|
|
691
|
+
- ``alphabet`` -- ordered alphabet of length 6. The order for the steps
|
|
692
|
+
is : Right, Up-Right, Up-Left, Left, Down-Left, Down-Right.
|
|
693
|
+
|
|
694
|
+
EXAMPLES::
|
|
695
|
+
|
|
696
|
+
sage: from sage.combinat.words.paths import WordPaths_triangle_grid
|
|
697
|
+
sage: P = WordPaths_triangle_grid('abcdef'); P # needs sage.rings.number_field
|
|
698
|
+
Word Paths on the triangle grid
|
|
699
|
+
sage: P == loads(dumps(P)) # needs sage.rings.number_field
|
|
700
|
+
True
|
|
701
|
+
"""
|
|
702
|
+
K = QuadraticField(3, 'sqrt3')
|
|
703
|
+
sqrt3 = K.gen()
|
|
704
|
+
|
|
705
|
+
# Construction of the steps
|
|
706
|
+
d = (vector(K, (1, 0)),
|
|
707
|
+
vector(K, (ZZ(1) / ZZ(2), sqrt3 / 2)),
|
|
708
|
+
vector(K, (ZZ(-1) / ZZ(2), sqrt3 / 2)),
|
|
709
|
+
vector(K, (-1, 0)),
|
|
710
|
+
vector(K, (ZZ(-1) / ZZ(2), -sqrt3 / 2)),
|
|
711
|
+
vector(K, (ZZ(1) / ZZ(2), -sqrt3 / 2)))
|
|
712
|
+
|
|
713
|
+
# Construction of the class
|
|
714
|
+
super().__init__(alphabet, steps=d)
|
|
715
|
+
|
|
716
|
+
self._infinite_word_class = None
|
|
717
|
+
self._finite_word_class = FiniteWordPath_triangle_grid
|
|
718
|
+
|
|
719
|
+
@lazy_attribute
|
|
720
|
+
def _element_classes(self):
|
|
721
|
+
r"""
|
|
722
|
+
Return a dictionary that gives the class of the elements of ``self``.
|
|
723
|
+
|
|
724
|
+
The word may be finite (infinite or of unknown length is not supported
|
|
725
|
+
yet).
|
|
726
|
+
Its data may be str, list, tuple, a callable or an iterable.
|
|
727
|
+
For callable and iterable, the data may be cached.
|
|
728
|
+
|
|
729
|
+
TESTS::
|
|
730
|
+
|
|
731
|
+
sage: # needs sage.rings.number_field
|
|
732
|
+
sage: d = WordPaths('abcdef', steps='triangle')._element_classes
|
|
733
|
+
sage: len(d)
|
|
734
|
+
7
|
|
735
|
+
sage: type(d)
|
|
736
|
+
<class 'dict'>
|
|
737
|
+
sage: d['tuple']
|
|
738
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_tuple'>
|
|
739
|
+
"""
|
|
740
|
+
return {
|
|
741
|
+
'list': FiniteWordPath_triangle_grid_list,
|
|
742
|
+
'str': FiniteWordPath_triangle_grid_str,
|
|
743
|
+
'tuple': FiniteWordPath_triangle_grid_tuple,
|
|
744
|
+
'callable_with_caching': FiniteWordPath_triangle_grid_callable_with_caching,
|
|
745
|
+
'callable': FiniteWordPath_triangle_grid_callable,
|
|
746
|
+
'iter_with_caching': FiniteWordPath_triangle_grid_iter_with_caching,
|
|
747
|
+
'iter': FiniteWordPath_triangle_grid_iter,
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
def __repr__(self) -> str:
|
|
751
|
+
r"""
|
|
752
|
+
EXAMPLES::
|
|
753
|
+
|
|
754
|
+
sage: from sage.combinat.words.paths import WordPaths_triangle_grid
|
|
755
|
+
sage: WordPaths_triangle_grid('abcdef').__repr__() # needs sage.rings.number_field
|
|
756
|
+
'Word Paths on the triangle grid'
|
|
757
|
+
"""
|
|
758
|
+
return "Word Paths on the triangle grid"
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
class WordPaths_hexagonal_grid(WordPaths_triangle_grid):
|
|
762
|
+
r"""
|
|
763
|
+
The combinatorial class of all paths on the hexagonal grid.
|
|
764
|
+
"""
|
|
765
|
+
def __init__(self, alphabet):
|
|
766
|
+
r"""
|
|
767
|
+
The combinatorial class of all finite paths on the hexagonal grid.
|
|
768
|
+
|
|
769
|
+
INPUT:
|
|
770
|
+
|
|
771
|
+
- ``alphabet`` -- ordered alphabet of length 6. The order for the steps
|
|
772
|
+
is : Right, Up-Right, Up-Left, Left, Down-Left, Down-Right.
|
|
773
|
+
|
|
774
|
+
EXAMPLES::
|
|
775
|
+
|
|
776
|
+
sage: from sage.combinat.words.paths import WordPaths_hexagonal_grid
|
|
777
|
+
sage: P = WordPaths_hexagonal_grid('abcdef'); P # needs sage.rings.number_field
|
|
778
|
+
Word Paths on the hexagonal grid
|
|
779
|
+
sage: P == loads(dumps(P)) # needs sage.rings.number_field
|
|
780
|
+
True
|
|
781
|
+
"""
|
|
782
|
+
# Construction of the class
|
|
783
|
+
super().__init__(alphabet)
|
|
784
|
+
|
|
785
|
+
self._infinite_word_class = None
|
|
786
|
+
self._finite_word_class = FiniteWordPath_hexagonal_grid
|
|
787
|
+
|
|
788
|
+
@lazy_attribute
|
|
789
|
+
def _element_classes(self):
|
|
790
|
+
r"""
|
|
791
|
+
Return a dictionary that gives the class of the elements of ``self``.
|
|
792
|
+
|
|
793
|
+
The word may be finite (infinite or of unknown length is not supported
|
|
794
|
+
yet).
|
|
795
|
+
Its data may be str, list, tuple, a callable or an iterable.
|
|
796
|
+
For callable and iterable, the data may be cached.
|
|
797
|
+
|
|
798
|
+
TESTS::
|
|
799
|
+
|
|
800
|
+
sage: # needs sage.rings.number_field
|
|
801
|
+
sage: d = WordPaths('abcdef', steps='hexagon')._element_classes
|
|
802
|
+
sage: type(d)
|
|
803
|
+
<class 'dict'>
|
|
804
|
+
sage: len(d)
|
|
805
|
+
7
|
|
806
|
+
sage: d['tuple']
|
|
807
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_tuple'>
|
|
808
|
+
"""
|
|
809
|
+
return {
|
|
810
|
+
'list': FiniteWordPath_hexagonal_grid_list,
|
|
811
|
+
'str': FiniteWordPath_hexagonal_grid_str,
|
|
812
|
+
'tuple': FiniteWordPath_hexagonal_grid_tuple,
|
|
813
|
+
'callable_with_caching': FiniteWordPath_hexagonal_grid_callable_with_caching,
|
|
814
|
+
'callable': FiniteWordPath_hexagonal_grid_callable,
|
|
815
|
+
'iter_with_caching': FiniteWordPath_hexagonal_grid_iter_with_caching,
|
|
816
|
+
'iter': FiniteWordPath_hexagonal_grid_iter,
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
def __repr__(self) -> str:
|
|
820
|
+
r"""
|
|
821
|
+
EXAMPLES::
|
|
822
|
+
|
|
823
|
+
sage: from sage.combinat.words.paths import WordPaths_hexagonal_grid # needs sage.rings.number_field
|
|
824
|
+
sage: WordPaths_hexagonal_grid('abcdef').__repr__() # needs sage.rings.number_field
|
|
825
|
+
'Word Paths on the hexagonal grid'
|
|
826
|
+
"""
|
|
827
|
+
return "Word Paths on the hexagonal grid"
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
class WordPaths_cube_grid(WordPaths_all):
|
|
831
|
+
r"""
|
|
832
|
+
The combinatorial class of all paths on the cube grid.
|
|
833
|
+
"""
|
|
834
|
+
def __init__(self, alphabet):
|
|
835
|
+
r"""
|
|
836
|
+
The combinatorial class of all finite paths on the cube grid.
|
|
837
|
+
|
|
838
|
+
INPUT:
|
|
839
|
+
|
|
840
|
+
- ``alphabet`` -- ordered alphabet of length 6. The order for
|
|
841
|
+
the steps is `e_x, e_y, e_z, -e_x, -e_y, -e_z`, where `e_v`
|
|
842
|
+
denotes the canonical basis.
|
|
843
|
+
|
|
844
|
+
EXAMPLES::
|
|
845
|
+
|
|
846
|
+
sage: from sage.combinat.words.paths import WordPaths_cube_grid
|
|
847
|
+
sage: P = WordPaths_cube_grid('abcABC'); P
|
|
848
|
+
Word Paths on the cube grid
|
|
849
|
+
sage: P == loads(dumps(P))
|
|
850
|
+
True
|
|
851
|
+
"""
|
|
852
|
+
# Construction of the class
|
|
853
|
+
d = [(1, 0, 0), (0, 1, 0), (0, 0, 1),
|
|
854
|
+
(-1, 0, 0), (0, -1, 0), (0, 0, -1)]
|
|
855
|
+
super().__init__(alphabet, steps=d)
|
|
856
|
+
self._infinite_word_class = None
|
|
857
|
+
self._finite_word_class = FiniteWordPath_cube_grid
|
|
858
|
+
|
|
859
|
+
@lazy_attribute
|
|
860
|
+
def _element_classes(self):
|
|
861
|
+
r"""
|
|
862
|
+
Return a dictionary that gives the class of the elements of ``self``.
|
|
863
|
+
|
|
864
|
+
The word may be finite (infinite or of unknown length is not supported
|
|
865
|
+
yet).
|
|
866
|
+
Its data may be str, list, tuple, a callable or an iterable.
|
|
867
|
+
For callable and iterable, the data may be cached.
|
|
868
|
+
|
|
869
|
+
TESTS::
|
|
870
|
+
|
|
871
|
+
sage: d = WordPaths('abcdef', steps='cube')._element_classes
|
|
872
|
+
sage: type(d)
|
|
873
|
+
<class 'dict'>
|
|
874
|
+
sage: len(d)
|
|
875
|
+
7
|
|
876
|
+
sage: d['tuple']
|
|
877
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_tuple'>
|
|
878
|
+
"""
|
|
879
|
+
return {'list': FiniteWordPath_cube_grid_list,
|
|
880
|
+
'str': FiniteWordPath_cube_grid_str,
|
|
881
|
+
'tuple': FiniteWordPath_cube_grid_tuple,
|
|
882
|
+
'callable_with_caching': FiniteWordPath_cube_grid_callable_with_caching,
|
|
883
|
+
'callable': FiniteWordPath_cube_grid_callable,
|
|
884
|
+
'iter_with_caching': FiniteWordPath_cube_grid_iter_with_caching,
|
|
885
|
+
'iter': FiniteWordPath_cube_grid_iter,
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
def __repr__(self) -> str:
|
|
889
|
+
r"""
|
|
890
|
+
EXAMPLES::
|
|
891
|
+
|
|
892
|
+
sage: from sage.combinat.words.paths import WordPaths_cube_grid
|
|
893
|
+
sage: WordPaths_cube_grid('abcABC').__repr__()
|
|
894
|
+
'Word Paths on the cube grid'
|
|
895
|
+
"""
|
|
896
|
+
return "Word Paths on the cube grid"
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
class WordPaths_dyck(WordPaths_all):
|
|
900
|
+
r"""
|
|
901
|
+
The combinatorial class of all Dyck paths.
|
|
902
|
+
"""
|
|
903
|
+
def __init__(self, alphabet):
|
|
904
|
+
r"""
|
|
905
|
+
The combinatorial class of all finite Dyck paths.
|
|
906
|
+
|
|
907
|
+
INPUT:
|
|
908
|
+
|
|
909
|
+
- ``alphabet`` -- ordered alphabet of length 2. The order for the steps
|
|
910
|
+
is : (1,1), (1,-1)
|
|
911
|
+
|
|
912
|
+
EXAMPLES::
|
|
913
|
+
|
|
914
|
+
sage: from sage.combinat.words.paths import WordPaths_dyck
|
|
915
|
+
sage: P = WordPaths_dyck('[]'); P
|
|
916
|
+
Finite Dyck paths
|
|
917
|
+
sage: P == loads(dumps(P))
|
|
918
|
+
True
|
|
919
|
+
"""
|
|
920
|
+
# Construction of the class
|
|
921
|
+
d = [(1, 1), (1, -1)]
|
|
922
|
+
super().__init__(alphabet, steps=d)
|
|
923
|
+
|
|
924
|
+
self._infinite_word_class = None
|
|
925
|
+
self._finite_word_class = FiniteWordPath_dyck
|
|
926
|
+
|
|
927
|
+
@lazy_attribute
|
|
928
|
+
def _element_classes(self):
|
|
929
|
+
r"""
|
|
930
|
+
Return a dictionary that gives the class of the elements of ``self``.
|
|
931
|
+
|
|
932
|
+
The word may be finite (infinite or of unknown length is not supported
|
|
933
|
+
yet).
|
|
934
|
+
Its data may be str, list, tuple, a callable or an iterable.
|
|
935
|
+
For callable and iterable, the data may be cached.
|
|
936
|
+
|
|
937
|
+
TESTS::
|
|
938
|
+
|
|
939
|
+
sage: d = WordPaths('ab', steps='dyck')._element_classes
|
|
940
|
+
sage: type(d)
|
|
941
|
+
<class 'dict'>
|
|
942
|
+
sage: len(d)
|
|
943
|
+
7
|
|
944
|
+
sage: d['tuple']
|
|
945
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_dyck_tuple'>
|
|
946
|
+
"""
|
|
947
|
+
return {'list': FiniteWordPath_dyck_list,
|
|
948
|
+
'str': FiniteWordPath_dyck_str,
|
|
949
|
+
'tuple': FiniteWordPath_dyck_tuple,
|
|
950
|
+
'callable_with_caching': FiniteWordPath_dyck_callable_with_caching,
|
|
951
|
+
'callable': FiniteWordPath_dyck_callable,
|
|
952
|
+
'iter_with_caching': FiniteWordPath_dyck_iter_with_caching,
|
|
953
|
+
'iter': FiniteWordPath_dyck_iter,
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
def __repr__(self) -> str:
|
|
957
|
+
r"""
|
|
958
|
+
EXAMPLES::
|
|
959
|
+
|
|
960
|
+
sage: from sage.combinat.words.paths import WordPaths_dyck
|
|
961
|
+
sage: WordPaths_dyck('()').__repr__()
|
|
962
|
+
'Finite Dyck paths'
|
|
963
|
+
"""
|
|
964
|
+
return "Finite Dyck paths"
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
class WordPaths_north_east(WordPaths_all):
|
|
968
|
+
r"""
|
|
969
|
+
The combinatorial class of all paths using North and East directions.
|
|
970
|
+
"""
|
|
971
|
+
def __init__(self, alphabet):
|
|
972
|
+
r"""
|
|
973
|
+
The combinatorial class of all finite paths using only north and east
|
|
974
|
+
steps on the square grid.
|
|
975
|
+
|
|
976
|
+
INPUT:
|
|
977
|
+
|
|
978
|
+
- ``alphabet`` -- ordered alphabet of length 2. The order for the steps
|
|
979
|
+
is North, East
|
|
980
|
+
|
|
981
|
+
EXAMPLES::
|
|
982
|
+
|
|
983
|
+
sage: from sage.combinat.words.paths import WordPaths_north_east
|
|
984
|
+
sage: P = WordPaths_north_east('ab'); P
|
|
985
|
+
Word Paths in North and East steps
|
|
986
|
+
sage: P == loads(dumps(P))
|
|
987
|
+
True
|
|
988
|
+
"""
|
|
989
|
+
# Construction of the class
|
|
990
|
+
d = [(0, 1), (1, 0)]
|
|
991
|
+
super().__init__(alphabet, steps=d)
|
|
992
|
+
self._infinite_word_class = None
|
|
993
|
+
self._finite_word_class = FiniteWordPath_north_east
|
|
994
|
+
|
|
995
|
+
@lazy_attribute
|
|
996
|
+
def _element_classes(self):
|
|
997
|
+
r"""
|
|
998
|
+
Return a dictionary that gives the class of the elements of ``self``.
|
|
999
|
+
|
|
1000
|
+
The word may be finite (infinite or of unknown length is not supported
|
|
1001
|
+
yet).
|
|
1002
|
+
Its data may be str, list, tuple, a callable or an iterable.
|
|
1003
|
+
For callable and iterable, the data may be cached.
|
|
1004
|
+
|
|
1005
|
+
TESTS::
|
|
1006
|
+
|
|
1007
|
+
sage: d = WordPaths('ab', steps='NE')._element_classes
|
|
1008
|
+
sage: type(d)
|
|
1009
|
+
<class 'dict'>
|
|
1010
|
+
sage: len(d)
|
|
1011
|
+
7
|
|
1012
|
+
sage: d['tuple']
|
|
1013
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_north_east_tuple'>
|
|
1014
|
+
"""
|
|
1015
|
+
return {'list': FiniteWordPath_north_east_list,
|
|
1016
|
+
'str': FiniteWordPath_north_east_str,
|
|
1017
|
+
'tuple': FiniteWordPath_north_east_tuple,
|
|
1018
|
+
'callable_with_caching': FiniteWordPath_north_east_callable_with_caching,
|
|
1019
|
+
'callable': FiniteWordPath_north_east_callable,
|
|
1020
|
+
'iter_with_caching': FiniteWordPath_north_east_iter_with_caching,
|
|
1021
|
+
'iter': FiniteWordPath_north_east_iter,
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
def __repr__(self) -> str:
|
|
1025
|
+
r"""
|
|
1026
|
+
EXAMPLES::
|
|
1027
|
+
|
|
1028
|
+
sage: from sage.combinat.words.paths import WordPaths_north_east
|
|
1029
|
+
sage: WordPaths_north_east('ab').__repr__()
|
|
1030
|
+
'Word Paths in North and East steps'
|
|
1031
|
+
"""
|
|
1032
|
+
return "Word Paths in North and East steps"
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
#######################################################################
|
|
1036
|
+
# #
|
|
1037
|
+
# Abstract word path classes #
|
|
1038
|
+
# (all, 2d, 3d, ...) #
|
|
1039
|
+
# #
|
|
1040
|
+
#######################################################################
|
|
1041
|
+
|
|
1042
|
+
class FiniteWordPath_all(SageObject):
|
|
1043
|
+
def _repr_(self) -> str:
|
|
1044
|
+
r"""
|
|
1045
|
+
Return a string representation of this path.
|
|
1046
|
+
|
|
1047
|
+
EXAMPLES::
|
|
1048
|
+
|
|
1049
|
+
sage: F = WordPaths('ab',[(1,0,0,0),(0,1,0,0)]); F
|
|
1050
|
+
Word Paths over 2 steps
|
|
1051
|
+
sage: f = F('ababab')
|
|
1052
|
+
sage: f._repr_()
|
|
1053
|
+
'Path: ababab'
|
|
1054
|
+
"""
|
|
1055
|
+
return "Path: %s" % self.string_rep()
|
|
1056
|
+
|
|
1057
|
+
def points(self, include_last=True):
|
|
1058
|
+
r"""
|
|
1059
|
+
Return an iterator yielding a list of points used to draw the path
|
|
1060
|
+
represented by this word.
|
|
1061
|
+
|
|
1062
|
+
INPUT:
|
|
1063
|
+
|
|
1064
|
+
- ``include_last`` -- boolean (default: ``True``); whether to include the
|
|
1065
|
+
last point
|
|
1066
|
+
|
|
1067
|
+
EXAMPLES:
|
|
1068
|
+
|
|
1069
|
+
A simple closed square::
|
|
1070
|
+
|
|
1071
|
+
sage: P = WordPaths('abAB')
|
|
1072
|
+
sage: list(P('abAB').points())
|
|
1073
|
+
[(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]
|
|
1074
|
+
|
|
1075
|
+
A simple closed square without the last point::
|
|
1076
|
+
|
|
1077
|
+
sage: list(P('abAB').points(include_last=False))
|
|
1078
|
+
[(0, 0), (1, 0), (1, 1), (0, 1)]
|
|
1079
|
+
|
|
1080
|
+
::
|
|
1081
|
+
|
|
1082
|
+
sage: list(P('abaB').points())
|
|
1083
|
+
[(0, 0), (1, 0), (1, 1), (2, 1), (2, 0)]
|
|
1084
|
+
"""
|
|
1085
|
+
curpt = self.start_point()
|
|
1086
|
+
yield curpt
|
|
1087
|
+
end = len(self) if include_last else -1
|
|
1088
|
+
for l in self[:end]:
|
|
1089
|
+
curpt += self.parent().letters_to_steps()[l]
|
|
1090
|
+
yield curpt
|
|
1091
|
+
|
|
1092
|
+
def start_point(self):
|
|
1093
|
+
r"""
|
|
1094
|
+
Return the starting point of ``self``.
|
|
1095
|
+
|
|
1096
|
+
OUTPUT: vector
|
|
1097
|
+
|
|
1098
|
+
EXAMPLES::
|
|
1099
|
+
|
|
1100
|
+
sage: # needs sage.rings.number_field
|
|
1101
|
+
sage: WordPaths('abcdef')('abcdef').start_point()
|
|
1102
|
+
(0, 0)
|
|
1103
|
+
sage: WordPaths('abcdef', steps='cube_grid')('abcdef').start_point()
|
|
1104
|
+
(0, 0, 0)
|
|
1105
|
+
sage: P = WordPaths('ab', steps=[(1,0,0,0),(0,1,0,0)])
|
|
1106
|
+
sage: P('abbba').start_point()
|
|
1107
|
+
(0, 0, 0, 0)
|
|
1108
|
+
"""
|
|
1109
|
+
return self.parent().vector_space()(0)
|
|
1110
|
+
|
|
1111
|
+
@cached_method
|
|
1112
|
+
def end_point(self):
|
|
1113
|
+
r"""
|
|
1114
|
+
Return the end point of the path.
|
|
1115
|
+
|
|
1116
|
+
EXAMPLES::
|
|
1117
|
+
|
|
1118
|
+
sage: # needs sage.rings.number_field
|
|
1119
|
+
sage: WordPaths('abcdef')('abababab').end_point()
|
|
1120
|
+
(6, 2*sqrt3)
|
|
1121
|
+
sage: WordPaths('abAB')('abababab').end_point()
|
|
1122
|
+
(4, 4)
|
|
1123
|
+
sage: P = WordPaths('abcABC', steps='cube_grid')
|
|
1124
|
+
sage: P('ababababCC').end_point()
|
|
1125
|
+
(4, 4, -2)
|
|
1126
|
+
sage: WordPaths('abcdef')('abcdef').end_point()
|
|
1127
|
+
(0, 0)
|
|
1128
|
+
sage: P = WordPaths('abc', steps=[(1,3,7,9),(-4,1,0,0),(0,32,1,8)])
|
|
1129
|
+
sage: P('abcabababacaacccbbcac').end_point()
|
|
1130
|
+
(-16, 254, 63, 128)
|
|
1131
|
+
"""
|
|
1132
|
+
last = None
|
|
1133
|
+
for pt in self.points():
|
|
1134
|
+
last = pt
|
|
1135
|
+
return last
|
|
1136
|
+
|
|
1137
|
+
def directive_vector(self):
|
|
1138
|
+
r"""
|
|
1139
|
+
Return the directive vector of ``self``.
|
|
1140
|
+
|
|
1141
|
+
The directive vector is the vector starting at the start point
|
|
1142
|
+
and ending at the end point of the path ``self``.
|
|
1143
|
+
|
|
1144
|
+
EXAMPLES::
|
|
1145
|
+
|
|
1146
|
+
sage: # needs sage.rings.number_field
|
|
1147
|
+
sage: WordPaths('abcdef')('abababab').directive_vector()
|
|
1148
|
+
(6, 2*sqrt3)
|
|
1149
|
+
sage: WordPaths('abAB')('abababab').directive_vector()
|
|
1150
|
+
(4, 4)
|
|
1151
|
+
sage: P = WordPaths('abcABC', steps='cube_grid')
|
|
1152
|
+
sage: P('ababababCC').directive_vector()
|
|
1153
|
+
(4, 4, -2)
|
|
1154
|
+
sage: WordPaths('abcdef')('abcdef').directive_vector()
|
|
1155
|
+
(0, 0)
|
|
1156
|
+
sage: P = WordPaths('abc', steps=[(1,3,7,9),(-4,1,0,0),(0,32,1,8)])
|
|
1157
|
+
sage: P('abcabababacaacccbbcac').directive_vector()
|
|
1158
|
+
(-16, 254, 63, 128)
|
|
1159
|
+
"""
|
|
1160
|
+
return self.end_point() - self.start_point()
|
|
1161
|
+
|
|
1162
|
+
def is_closed(self) -> bool:
|
|
1163
|
+
r"""
|
|
1164
|
+
Return ``True`` if the path is closed.
|
|
1165
|
+
|
|
1166
|
+
A path is closed if the origin and the end of
|
|
1167
|
+
the path are equal.
|
|
1168
|
+
|
|
1169
|
+
EXAMPLES::
|
|
1170
|
+
|
|
1171
|
+
sage: P = WordPaths('abcd', steps=[(1,0),(0,1),(-1,0),(0,-1)])
|
|
1172
|
+
sage: P('abcd').is_closed()
|
|
1173
|
+
True
|
|
1174
|
+
sage: P('abc').is_closed()
|
|
1175
|
+
False
|
|
1176
|
+
sage: P().is_closed()
|
|
1177
|
+
True
|
|
1178
|
+
sage: P('aacacc').is_closed()
|
|
1179
|
+
True
|
|
1180
|
+
"""
|
|
1181
|
+
return self.start_point() == self.end_point()
|
|
1182
|
+
|
|
1183
|
+
def is_simple(self) -> bool:
|
|
1184
|
+
r"""
|
|
1185
|
+
Return ``True`` if the path is simple.
|
|
1186
|
+
|
|
1187
|
+
A path is simple if all its points are
|
|
1188
|
+
distinct.
|
|
1189
|
+
|
|
1190
|
+
If the path is closed, the last point is not considered.
|
|
1191
|
+
|
|
1192
|
+
EXAMPLES::
|
|
1193
|
+
|
|
1194
|
+
sage: # needs sage.rings.number_field
|
|
1195
|
+
sage: P = WordPaths('abcdef', steps='triangle_grid'); P
|
|
1196
|
+
Word Paths on the triangle grid
|
|
1197
|
+
sage: P('abc').is_simple()
|
|
1198
|
+
True
|
|
1199
|
+
sage: P('abcde').is_simple()
|
|
1200
|
+
True
|
|
1201
|
+
sage: P('abcdef').is_simple()
|
|
1202
|
+
True
|
|
1203
|
+
sage: P('ad').is_simple()
|
|
1204
|
+
True
|
|
1205
|
+
sage: P('aabdee').is_simple()
|
|
1206
|
+
False
|
|
1207
|
+
"""
|
|
1208
|
+
n = 0
|
|
1209
|
+
s = set()
|
|
1210
|
+
include_last = not self.is_closed()
|
|
1211
|
+
for p in self.points(include_last=include_last):
|
|
1212
|
+
# We need the elements to have a common parent,
|
|
1213
|
+
# so we convert the points to immutable vectors.
|
|
1214
|
+
v = vector(p)
|
|
1215
|
+
v.set_immutable()
|
|
1216
|
+
s.add(v)
|
|
1217
|
+
n += 1
|
|
1218
|
+
if len(s) != n:
|
|
1219
|
+
return False
|
|
1220
|
+
return True
|
|
1221
|
+
|
|
1222
|
+
def tikz_trajectory(self) -> str:
|
|
1223
|
+
r"""
|
|
1224
|
+
Return the trajectory of ``self`` as a ``tikz`` string.
|
|
1225
|
+
|
|
1226
|
+
EXAMPLES::
|
|
1227
|
+
|
|
1228
|
+
sage: # needs sage.rings.number_field
|
|
1229
|
+
sage: P = WordPaths('abcdef')
|
|
1230
|
+
sage: p = P('abcde')
|
|
1231
|
+
sage: p.tikz_trajectory()
|
|
1232
|
+
'(0.000, 0.000) -- (1.00, 0.000) -- (1.50, 0.866) -- (1.00, 1.73) -- (0.000, 1.73) -- (-0.500, 0.866)'
|
|
1233
|
+
"""
|
|
1234
|
+
from sage.misc.functional import N as n
|
|
1235
|
+
l = (str(tuple(n(x, digits=3) for x in pt)) for pt in self.points())
|
|
1236
|
+
return ' -- '.join(l)
|
|
1237
|
+
|
|
1238
|
+
def projected_point_iterator(self, v=None, ring=None):
|
|
1239
|
+
r"""
|
|
1240
|
+
Return an iterator of the projection of the orbit points of the
|
|
1241
|
+
path into the space orthogonal to the given vector.
|
|
1242
|
+
|
|
1243
|
+
INPUT:
|
|
1244
|
+
|
|
1245
|
+
- ``v`` -- vector (default: ``None``); if ``None``, the directive
|
|
1246
|
+
vector (i.e. the end point minus starting point) of the path is
|
|
1247
|
+
considered
|
|
1248
|
+
|
|
1249
|
+
- ``ring`` -- ring (default: ``None``); where to do the
|
|
1250
|
+
computations. If ``None``, RealField(53) is used.
|
|
1251
|
+
|
|
1252
|
+
OUTPUT: iterator of points
|
|
1253
|
+
|
|
1254
|
+
EXAMPLES:
|
|
1255
|
+
|
|
1256
|
+
Projected points of the Rauzy fractal::
|
|
1257
|
+
|
|
1258
|
+
sage: # needs sage.rings.number_field
|
|
1259
|
+
sage: s = WordMorphism('1->12,2->13,3->1')
|
|
1260
|
+
sage: D = s.fixed_point('1')
|
|
1261
|
+
sage: v = s.pisot_eigenvector_right()
|
|
1262
|
+
sage: P = WordPaths('123',[(1,0,0),(0,1,0),(0,0,1)])
|
|
1263
|
+
sage: w = P(D[:200])
|
|
1264
|
+
sage: it = w.projected_point_iterator(v)
|
|
1265
|
+
sage: for i in range(6): next(it)
|
|
1266
|
+
(0.000000000000000, 0.000000000000000)
|
|
1267
|
+
(-0.526233343362516, 0.000000000000000)
|
|
1268
|
+
(0.220830337618112, -0.477656250512816)
|
|
1269
|
+
(-0.305403005744404, -0.477656250512816)
|
|
1270
|
+
(0.100767309386062, 0.400890564600664)
|
|
1271
|
+
(-0.425466033976454, 0.400890564600664)
|
|
1272
|
+
|
|
1273
|
+
Projected points of a 2d path::
|
|
1274
|
+
|
|
1275
|
+
sage: P = WordPaths('ab','ne')
|
|
1276
|
+
sage: p = P('aabbabbab')
|
|
1277
|
+
sage: it = p.projected_point_iterator(ring=RealField(20))
|
|
1278
|
+
sage: for i in range(8): next(it)
|
|
1279
|
+
(0.00000)
|
|
1280
|
+
(0.78087)
|
|
1281
|
+
(1.5617)
|
|
1282
|
+
(0.93704)
|
|
1283
|
+
(0.31235)
|
|
1284
|
+
(1.0932)
|
|
1285
|
+
(0.46852)
|
|
1286
|
+
(-0.15617)
|
|
1287
|
+
"""
|
|
1288
|
+
if v is None:
|
|
1289
|
+
v = self.directive_vector()
|
|
1290
|
+
if ring is None:
|
|
1291
|
+
ring = RR
|
|
1292
|
+
R = vector_on_axis_rotation_matrix(v, 0, ring=ring)[1:]
|
|
1293
|
+
for q in self.points():
|
|
1294
|
+
yield R * q
|
|
1295
|
+
|
|
1296
|
+
def plot_projection(self, v=None, letters=None, color=None, ring=None,
|
|
1297
|
+
size=12, kind='right'):
|
|
1298
|
+
r"""
|
|
1299
|
+
Return an image of the projection of the successive points of the
|
|
1300
|
+
path into the space orthogonal to the given vector.
|
|
1301
|
+
|
|
1302
|
+
INPUT:
|
|
1303
|
+
|
|
1304
|
+
- ``self`` -- a word path in a 3 or 4 dimension vector space
|
|
1305
|
+
|
|
1306
|
+
- ``v`` -- vector (default: ``None``); if ``None``, the directive
|
|
1307
|
+
vector (i.e. the end point minus starting point) of the path is
|
|
1308
|
+
considered.
|
|
1309
|
+
|
|
1310
|
+
- ``letters`` -- iterable (default: ``None``); of the letters
|
|
1311
|
+
to be projected. If ``None``, then all the letters are considered.
|
|
1312
|
+
|
|
1313
|
+
- ``color`` -- dictionary (default: ``None``); of the letters
|
|
1314
|
+
mapped to colors. If ``None``, automatic colors are chosen.
|
|
1315
|
+
|
|
1316
|
+
- ``ring`` -- ring (default: ``None``); where to do the
|
|
1317
|
+
computations. If ``None``, RealField(53) is used.
|
|
1318
|
+
|
|
1319
|
+
- ``size`` -- number (default: ``12``); size of the points
|
|
1320
|
+
|
|
1321
|
+
- ``kind`` -- string (default: ``'right'``); either
|
|
1322
|
+
``'right'`` or ``'left'``. The color of a letter is given to the
|
|
1323
|
+
projected prefix to the right or the left of the letter.
|
|
1324
|
+
|
|
1325
|
+
OUTPUT: 2d or 3d Graphic object
|
|
1326
|
+
|
|
1327
|
+
EXAMPLES:
|
|
1328
|
+
|
|
1329
|
+
The Rauzy fractal::
|
|
1330
|
+
|
|
1331
|
+
sage: # needs sage.rings.number_field
|
|
1332
|
+
sage: s = WordMorphism('1->12,2->13,3->1')
|
|
1333
|
+
sage: D = s.fixed_point('1')
|
|
1334
|
+
sage: v = s.pisot_eigenvector_right()
|
|
1335
|
+
sage: P = WordPaths('123',[(1,0,0),(0,1,0),(0,0,1)])
|
|
1336
|
+
sage: w = P(D[:200])
|
|
1337
|
+
sage: w.plot_projection(v) # long time (2s)
|
|
1338
|
+
Graphics object consisting of 200 graphics primitives
|
|
1339
|
+
|
|
1340
|
+
In this case, the abelianized vector doesn't give a good
|
|
1341
|
+
projection::
|
|
1342
|
+
|
|
1343
|
+
sage: w.plot_projection() # long time (2s) # needs sage.rings.number_field
|
|
1344
|
+
Graphics object consisting of 200 graphics primitives
|
|
1345
|
+
|
|
1346
|
+
You can project only the letters you want::
|
|
1347
|
+
|
|
1348
|
+
sage: w.plot_projection(v, letters='12') # long time (2s) # needs sage.rings.number_field
|
|
1349
|
+
Graphics object consisting of 168 graphics primitives
|
|
1350
|
+
|
|
1351
|
+
You can increase or decrease the precision of the computations by
|
|
1352
|
+
changing the ring of the projection matrix::
|
|
1353
|
+
|
|
1354
|
+
sage: w.plot_projection(v, ring=RealField(20)) # long time (2s) # needs sage.rings.number_field
|
|
1355
|
+
Graphics object consisting of 200 graphics primitives
|
|
1356
|
+
|
|
1357
|
+
You can change the size of the points::
|
|
1358
|
+
|
|
1359
|
+
sage: w.plot_projection(v, size=30) # long time (2s) # needs sage.rings.number_field
|
|
1360
|
+
Graphics object consisting of 200 graphics primitives
|
|
1361
|
+
|
|
1362
|
+
You can assign the color of a letter to the projected prefix to the
|
|
1363
|
+
right or the left of the letter::
|
|
1364
|
+
|
|
1365
|
+
sage: w.plot_projection(v, kind='left') # long time (2s) # needs sage.rings.number_field
|
|
1366
|
+
Graphics object consisting of 200 graphics primitives
|
|
1367
|
+
|
|
1368
|
+
To remove the axis, do like this::
|
|
1369
|
+
|
|
1370
|
+
sage: # needs sage.rings.number_field
|
|
1371
|
+
sage: r = w.plot_projection(v) # needs sage.plot
|
|
1372
|
+
sage: r.axes(False) # needs sage.plot
|
|
1373
|
+
sage: r # long time (2s) # needs sage.plot
|
|
1374
|
+
Graphics object consisting of 200 graphics primitives
|
|
1375
|
+
|
|
1376
|
+
You can assign different colors to each letter::
|
|
1377
|
+
|
|
1378
|
+
sage: # needs sage.rings.number_field
|
|
1379
|
+
sage: color = {'1': 'purple', '2': (.2,.3,.4), '3': 'magenta'}
|
|
1380
|
+
sage: w.plot_projection(v, color=color) # long time (2s) # needs sage.plot
|
|
1381
|
+
Graphics object consisting of 200 graphics primitives
|
|
1382
|
+
|
|
1383
|
+
The 3d-Rauzy fractal::
|
|
1384
|
+
|
|
1385
|
+
sage: # needs sage.rings.number_field
|
|
1386
|
+
sage: s = WordMorphism('1->12,2->13,3->14,4->1')
|
|
1387
|
+
sage: D = s.fixed_point('1')
|
|
1388
|
+
sage: v = s.pisot_eigenvector_right()
|
|
1389
|
+
sage: P = WordPaths('1234',[(1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1)])
|
|
1390
|
+
sage: w = P(D[:200])
|
|
1391
|
+
sage: w.plot_projection(v) # needs sage.plot
|
|
1392
|
+
Graphics3d Object
|
|
1393
|
+
|
|
1394
|
+
The dimension of vector space of the parent must be 3 or 4::
|
|
1395
|
+
|
|
1396
|
+
sage: # needs sage.rings.number_field
|
|
1397
|
+
sage: P = WordPaths('ab', [(1, 0), (0, 1)])
|
|
1398
|
+
sage: p = P('aabbabbab')
|
|
1399
|
+
sage: p.plot_projection() # needs sage.plot
|
|
1400
|
+
Traceback (most recent call last):
|
|
1401
|
+
...
|
|
1402
|
+
TypeError: The dimension of the vector space (=2) must be 3 or 4
|
|
1403
|
+
"""
|
|
1404
|
+
dimension = self.parent().vector_space().dimension()
|
|
1405
|
+
if dimension not in (3, 4):
|
|
1406
|
+
msg = "The dimension of the vector space (=%s) must be 3 or 4" % dimension
|
|
1407
|
+
raise TypeError(msg)
|
|
1408
|
+
if letters is None:
|
|
1409
|
+
letters = self.parent().alphabet()
|
|
1410
|
+
if color is None:
|
|
1411
|
+
from sage.plot.all import hue
|
|
1412
|
+
A = self.parent().alphabet()
|
|
1413
|
+
color = {a: hue(A.rank(a) / float(A.cardinality())) for a in A}
|
|
1414
|
+
it = self.projected_point_iterator(v, ring=ring)
|
|
1415
|
+
if kind == 'right':
|
|
1416
|
+
next(it)
|
|
1417
|
+
elif kind != 'left':
|
|
1418
|
+
raise ValueError('unknown value for kind (=%s)' % kind)
|
|
1419
|
+
tout = [point([c], color=color[a], size=size)
|
|
1420
|
+
for a, c in zip(self, it) if a in letters]
|
|
1421
|
+
return sum(tout)
|
|
1422
|
+
|
|
1423
|
+
def projected_path(self, v=None, ring=None):
|
|
1424
|
+
r"""
|
|
1425
|
+
Return the path projected into the space orthogonal to the given
|
|
1426
|
+
vector.
|
|
1427
|
+
|
|
1428
|
+
INPUT:
|
|
1429
|
+
|
|
1430
|
+
- ``v`` -- vector (default: ``None``); if ``None``, the directive
|
|
1431
|
+
vector (i.e. the end point minus starting point) of the path is
|
|
1432
|
+
considered.
|
|
1433
|
+
|
|
1434
|
+
- ``ring`` -- ring (default: ``None``); where to do the
|
|
1435
|
+
computations. If ``None``, RealField(53) is used.
|
|
1436
|
+
|
|
1437
|
+
OUTPUT: word path
|
|
1438
|
+
|
|
1439
|
+
EXAMPLES:
|
|
1440
|
+
|
|
1441
|
+
The projected path of the tribonacci word::
|
|
1442
|
+
|
|
1443
|
+
sage: # needs sage.rings.number_field
|
|
1444
|
+
sage: s = WordMorphism('1->12,2->13,3->1')
|
|
1445
|
+
sage: D = s.fixed_point('1')
|
|
1446
|
+
sage: v = s.pisot_eigenvector_right()
|
|
1447
|
+
sage: P = WordPaths('123',[(1,0,0),(0,1,0),(0,0,1)])
|
|
1448
|
+
sage: w = P(D[:1000])
|
|
1449
|
+
sage: p = w.projected_path(v)
|
|
1450
|
+
sage: p
|
|
1451
|
+
Path: 1213121121312121312112131213121121312121...
|
|
1452
|
+
sage: p[:20].plot() # needs sage.plot
|
|
1453
|
+
Graphics object consisting of 3 graphics primitives
|
|
1454
|
+
|
|
1455
|
+
The ``ring`` argument allows to change the precision of the
|
|
1456
|
+
projected steps::
|
|
1457
|
+
|
|
1458
|
+
sage: # needs sage.rings.number_field
|
|
1459
|
+
sage: p = w.projected_path(v, RealField(10))
|
|
1460
|
+
sage: p
|
|
1461
|
+
Path: 1213121121312121312112131213121121312121...
|
|
1462
|
+
sage: p.parent().letters_to_steps()
|
|
1463
|
+
{'1': (-0.53, 0.00), '2': (0.75, -0.48), '3': (0.41, 0.88)}
|
|
1464
|
+
"""
|
|
1465
|
+
if v is None:
|
|
1466
|
+
v = self.directive_vector()
|
|
1467
|
+
if ring is None:
|
|
1468
|
+
ring = RR
|
|
1469
|
+
R = vector_on_axis_rotation_matrix(v, 0, ring=ring)[1:]
|
|
1470
|
+
d = self.parent().letters_to_steps()
|
|
1471
|
+
A = self.parent().alphabet()
|
|
1472
|
+
nvvectors = [R * d[a] for a in A]
|
|
1473
|
+
projected_parent = WordPaths(A, nvvectors)
|
|
1474
|
+
return projected_parent(self)
|
|
1475
|
+
|
|
1476
|
+
def is_tangent(self):
|
|
1477
|
+
r"""
|
|
1478
|
+
The is_tangent() method, which is implemented for words, has
|
|
1479
|
+
an extended meaning for word paths, which is not implemented yet.
|
|
1480
|
+
|
|
1481
|
+
TESTS::
|
|
1482
|
+
|
|
1483
|
+
sage: WordPaths('ab')('abbab').is_tangent()
|
|
1484
|
+
Traceback (most recent call last):
|
|
1485
|
+
...
|
|
1486
|
+
NotImplementedError
|
|
1487
|
+
|
|
1488
|
+
AUTHOR:
|
|
1489
|
+
|
|
1490
|
+
- Thierry Monteil
|
|
1491
|
+
"""
|
|
1492
|
+
raise NotImplementedError
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
class FiniteWordPath_2d(FiniteWordPath_all):
|
|
1496
|
+
def plot(self, pathoptions={"rgbcolor": 'red', "thickness": 3},
|
|
1497
|
+
fill=True, filloptions={"rgbcolor": 'red', "alpha": 0.2},
|
|
1498
|
+
startpoint=True, startoptions={"rgbcolor": 'red', "pointsize": 100},
|
|
1499
|
+
endarrow=True, arrowoptions={"rgbcolor": 'red', "arrowsize": 20, "width": 3},
|
|
1500
|
+
gridlines=False, gridoptions={}):
|
|
1501
|
+
r"""
|
|
1502
|
+
Return a 2d Graphics illustrating the path.
|
|
1503
|
+
|
|
1504
|
+
INPUT:
|
|
1505
|
+
|
|
1506
|
+
- ``pathoptions`` -- (dict,
|
|
1507
|
+
default:dict(rgbcolor='red',thickness=3)), options for the
|
|
1508
|
+
path drawing
|
|
1509
|
+
|
|
1510
|
+
- ``fill`` -- boolean (default: ``True``); if fill is ``True`` and if
|
|
1511
|
+
the path is closed, the inside is colored
|
|
1512
|
+
|
|
1513
|
+
- ``filloptions`` -- (dict,
|
|
1514
|
+
default:dict(rgbcolor='red',alpha=0.2)), options for the
|
|
1515
|
+
inside filling
|
|
1516
|
+
|
|
1517
|
+
- ``startpoint`` -- boolean (default: ``True``); draw the start point?
|
|
1518
|
+
|
|
1519
|
+
- ``startoptions`` -- (dict,
|
|
1520
|
+
default:dict(rgbcolor='red',pointsize=100)) options for the
|
|
1521
|
+
start point drawing
|
|
1522
|
+
|
|
1523
|
+
- ``endarrow`` -- boolean (default: ``True``); draw an arrow end at the end?
|
|
1524
|
+
|
|
1525
|
+
- ``arrowoptions`` -- (dict,
|
|
1526
|
+
default:dict(rgbcolor='red',arrowsize=20, width=3)) options
|
|
1527
|
+
for the end point arrow
|
|
1528
|
+
|
|
1529
|
+
- ``gridlines`` -- boolean (default: ``False``); show gridlines?
|
|
1530
|
+
|
|
1531
|
+
- ``gridoptions`` -- (dict, default: {}), options for the gridlines
|
|
1532
|
+
|
|
1533
|
+
EXAMPLES:
|
|
1534
|
+
|
|
1535
|
+
A non closed path on the square grid::
|
|
1536
|
+
|
|
1537
|
+
sage: P = WordPaths('abAB')
|
|
1538
|
+
sage: P('abababAABAB').plot() # needs sage.plot
|
|
1539
|
+
Graphics object consisting of 3 graphics primitives
|
|
1540
|
+
|
|
1541
|
+
A closed path on the square grid::
|
|
1542
|
+
|
|
1543
|
+
sage: P('abababAABABB').plot() # needs sage.plot
|
|
1544
|
+
Graphics object consisting of 4 graphics primitives
|
|
1545
|
+
|
|
1546
|
+
A Dyck path::
|
|
1547
|
+
|
|
1548
|
+
sage: P = WordPaths('()', steps='dyck')
|
|
1549
|
+
sage: P('()()()((()))').plot() # needs sage.plot
|
|
1550
|
+
Graphics object consisting of 3 graphics primitives
|
|
1551
|
+
|
|
1552
|
+
A path in the triangle grid::
|
|
1553
|
+
|
|
1554
|
+
sage: # needs sage.rings.number_field
|
|
1555
|
+
sage: P = WordPaths('abcdef', steps='triangle_grid')
|
|
1556
|
+
sage: P('abcdedededefab').plot() # needs sage.plot
|
|
1557
|
+
Graphics object consisting of 3 graphics primitives
|
|
1558
|
+
|
|
1559
|
+
A polygon of length 220 that tiles the plane in two ways::
|
|
1560
|
+
|
|
1561
|
+
sage: P = WordPaths('abAB')
|
|
1562
|
+
sage: P('aBababAbabaBaBABaBabaBaBABAbABABaBabaBaBABaBababAbabaBaBABaBabaBaBABAbABABaBABAbAbabAbABABaBABAbABABaBabaBaBABAbABABaBABAbAbabAbABAbAbabaBababAbABAbAbabAbABABaBABAbAbabAbABAbAbabaBababAbabaBaBABaBababAbabaBababAbABAbAbab').plot() # needs sage.plot
|
|
1563
|
+
Graphics object consisting of 4 graphics primitives
|
|
1564
|
+
|
|
1565
|
+
With gridlines::
|
|
1566
|
+
|
|
1567
|
+
sage: P('ababababab').plot(gridlines=True) # needs sage.plot
|
|
1568
|
+
|
|
1569
|
+
TESTS::
|
|
1570
|
+
|
|
1571
|
+
sage: P = WordPaths('abAB')
|
|
1572
|
+
sage: P().plot() # needs sage.plot
|
|
1573
|
+
Graphics object consisting of 3 graphics primitives
|
|
1574
|
+
sage: sum(map(plot,map(P,['a','A','b','B']))) # needs sage.plot
|
|
1575
|
+
Graphics object consisting of 12 graphics primitives
|
|
1576
|
+
"""
|
|
1577
|
+
G = Graphics()
|
|
1578
|
+
pts = list(self.points())
|
|
1579
|
+
|
|
1580
|
+
####################
|
|
1581
|
+
####################
|
|
1582
|
+
# FIXME Bug: plot needs float for coordinates
|
|
1583
|
+
####################
|
|
1584
|
+
####################
|
|
1585
|
+
pts = [[RR(i) for i in x] for x in pts]
|
|
1586
|
+
|
|
1587
|
+
# Inside
|
|
1588
|
+
if fill and self.is_closed():
|
|
1589
|
+
G += polygon(pts, **filloptions)
|
|
1590
|
+
|
|
1591
|
+
# Startpoint
|
|
1592
|
+
if startpoint:
|
|
1593
|
+
G += point(pts[0], **startoptions)
|
|
1594
|
+
|
|
1595
|
+
# The path itself
|
|
1596
|
+
if endarrow and not self.is_empty():
|
|
1597
|
+
G += line(pts[:-1], **pathoptions)
|
|
1598
|
+
G += arrow(pts[-2], pts[-1], **arrowoptions)
|
|
1599
|
+
else:
|
|
1600
|
+
G += line(pts, **pathoptions)
|
|
1601
|
+
|
|
1602
|
+
G.axes(False)
|
|
1603
|
+
G.set_aspect_ratio(1)
|
|
1604
|
+
|
|
1605
|
+
# gridlines
|
|
1606
|
+
# ############## BUG ##############
|
|
1607
|
+
# Gridlines doesn't work fine.
|
|
1608
|
+
# It should be gridlines="integers"
|
|
1609
|
+
# ############## BUG ##############
|
|
1610
|
+
if gridlines:
|
|
1611
|
+
G = G.show(gridlines=True, **gridoptions)
|
|
1612
|
+
|
|
1613
|
+
return G
|
|
1614
|
+
|
|
1615
|
+
def animate(self):
|
|
1616
|
+
r"""
|
|
1617
|
+
Return an animation object illustrating the path growing step by step.
|
|
1618
|
+
|
|
1619
|
+
EXAMPLES::
|
|
1620
|
+
|
|
1621
|
+
sage: P = WordPaths('abAB')
|
|
1622
|
+
sage: p = P('aaababbb')
|
|
1623
|
+
sage: a = p.animate(); print(a) # needs sage.plot
|
|
1624
|
+
Animation with 9 frames
|
|
1625
|
+
sage: show(a) # long time, optional - imagemagick, needs sage.plot
|
|
1626
|
+
sage: show(a, delay=35, iterations=3) # long time, optional - imagemagick, needs sage.plot
|
|
1627
|
+
|
|
1628
|
+
::
|
|
1629
|
+
|
|
1630
|
+
sage: # needs sage.rings.number_field
|
|
1631
|
+
sage: P = WordPaths('abcdef', steps='triangle')
|
|
1632
|
+
sage: p = P('abcdef')
|
|
1633
|
+
sage: a = p.animate(); print(a) # needs sage.plot
|
|
1634
|
+
Animation with 8 frames
|
|
1635
|
+
sage: show(a) # long time, optional - imagemagick, needs sage.plot
|
|
1636
|
+
|
|
1637
|
+
If the path is closed, the plain polygon is added at the end of the
|
|
1638
|
+
animation::
|
|
1639
|
+
|
|
1640
|
+
sage: P = WordPaths('abAB')
|
|
1641
|
+
sage: p = P('ababAbABABaB')
|
|
1642
|
+
sage: a = p.animate(); print(a) # needs sage.plot
|
|
1643
|
+
Animation with 14 frames
|
|
1644
|
+
sage: show(a) # long time, optional - imagemagick, needs sage.plot
|
|
1645
|
+
|
|
1646
|
+
Another example illustrating a Fibonacci tile::
|
|
1647
|
+
|
|
1648
|
+
sage: w = words.fibonacci_tile(2)
|
|
1649
|
+
sage: a = w.animate(); print(a) # needs sage.plot
|
|
1650
|
+
Animation with 54 frames
|
|
1651
|
+
sage: show(a) # long time, optional - imagemagick, needs sage.plot
|
|
1652
|
+
|
|
1653
|
+
The first 4 Fibonacci tiles in an animation::
|
|
1654
|
+
|
|
1655
|
+
sage: # needs sage.plot
|
|
1656
|
+
sage: a = words.fibonacci_tile(0).animate()
|
|
1657
|
+
sage: b = words.fibonacci_tile(1).animate()
|
|
1658
|
+
sage: c = words.fibonacci_tile(2).animate()
|
|
1659
|
+
sage: d = words.fibonacci_tile(3).animate()
|
|
1660
|
+
sage: print(a*b*c*d)
|
|
1661
|
+
Animation with 296 frames
|
|
1662
|
+
sage: show(a*b*c*d) # long time, optional - imagemagick
|
|
1663
|
+
|
|
1664
|
+
.. NOTE::
|
|
1665
|
+
|
|
1666
|
+
If ImageMagick is not installed, you will get an error
|
|
1667
|
+
message like this::
|
|
1668
|
+
|
|
1669
|
+
convert: not found
|
|
1670
|
+
|
|
1671
|
+
Error: ImageMagick does not appear to be installed. Saving an
|
|
1672
|
+
animation to a GIF file or displaying an animation requires
|
|
1673
|
+
ImageMagick, so please install it and try again.
|
|
1674
|
+
|
|
1675
|
+
See www.imagemagick.org, for example.
|
|
1676
|
+
"""
|
|
1677
|
+
from sage.plot.all import line, polygon, animate
|
|
1678
|
+
|
|
1679
|
+
pts = list(self.points())
|
|
1680
|
+
|
|
1681
|
+
####################
|
|
1682
|
+
####################
|
|
1683
|
+
# Bug: plot needs float for coordinates
|
|
1684
|
+
####################
|
|
1685
|
+
####################
|
|
1686
|
+
pts = [[RR(i) for i in x] for x in pts]
|
|
1687
|
+
|
|
1688
|
+
images = [line(pts[:i]) for i in range(1, len(pts) + 1)]
|
|
1689
|
+
|
|
1690
|
+
if self.is_closed():
|
|
1691
|
+
images.append(polygon(pts))
|
|
1692
|
+
|
|
1693
|
+
# Get the window of the last image
|
|
1694
|
+
last_image = images[-1]
|
|
1695
|
+
kwds = {}
|
|
1696
|
+
kwds['xmin'] = last_image.xmin()
|
|
1697
|
+
kwds['xmax'] = last_image.xmax()
|
|
1698
|
+
kwds['ymin'] = last_image.ymin()
|
|
1699
|
+
kwds['ymax'] = last_image.ymax()
|
|
1700
|
+
kwds['aspect_ratio'] = 1
|
|
1701
|
+
kwds['axes'] = False
|
|
1702
|
+
|
|
1703
|
+
return animate(images, **kwds)
|
|
1704
|
+
|
|
1705
|
+
def plot_directive_vector(self, options={"rgbcolor": 'blue'}):
|
|
1706
|
+
r"""
|
|
1707
|
+
Return an arrow 2d graphics that goes from the start of the path
|
|
1708
|
+
to the end.
|
|
1709
|
+
|
|
1710
|
+
INPUT:
|
|
1711
|
+
|
|
1712
|
+
- ``options`` -- dictionary, default: {'rgbcolor': 'blue'} graphic
|
|
1713
|
+
options for the arrow
|
|
1714
|
+
|
|
1715
|
+
If the start is the same as the end, a single point is returned.
|
|
1716
|
+
|
|
1717
|
+
EXAMPLES::
|
|
1718
|
+
|
|
1719
|
+
sage: P = WordPaths('abcd'); P
|
|
1720
|
+
Word Paths on the square grid
|
|
1721
|
+
sage: p = P('aaaccaccacacacaccccccbbdd'); p
|
|
1722
|
+
Path: aaaccaccacacacaccccccbbdd
|
|
1723
|
+
sage: R = p.plot() + p.plot_directive_vector() # needs sage.plot
|
|
1724
|
+
sage: R.axes(False) # needs sage.plot
|
|
1725
|
+
sage: R.set_aspect_ratio(1) # needs sage.plot
|
|
1726
|
+
sage: R.plot() # needs sage.plot
|
|
1727
|
+
Graphics object consisting of 4 graphics primitives
|
|
1728
|
+
|
|
1729
|
+
TESTS:
|
|
1730
|
+
|
|
1731
|
+
A closed path::
|
|
1732
|
+
|
|
1733
|
+
sage: P('acbd').plot_directive_vector() # needs sage.plot
|
|
1734
|
+
Graphics object consisting of 1 graphics primitive
|
|
1735
|
+
"""
|
|
1736
|
+
start = self.start_point()
|
|
1737
|
+
end = self.end_point()
|
|
1738
|
+
if (start == end):
|
|
1739
|
+
G = point(start, pointsize=10, **options)
|
|
1740
|
+
else:
|
|
1741
|
+
G = arrow(start, end, **options)
|
|
1742
|
+
G.axes(False)
|
|
1743
|
+
G.set_aspect_ratio(1)
|
|
1744
|
+
return G
|
|
1745
|
+
|
|
1746
|
+
def area(self):
|
|
1747
|
+
r"""
|
|
1748
|
+
Return the area of a closed path.
|
|
1749
|
+
|
|
1750
|
+
INPUT:
|
|
1751
|
+
|
|
1752
|
+
- ``self`` -- a closed path
|
|
1753
|
+
|
|
1754
|
+
EXAMPLES::
|
|
1755
|
+
|
|
1756
|
+
sage: P = WordPaths('abcd',steps=[(1,1),(-1,1),(-1,-1),(1,-1)])
|
|
1757
|
+
sage: p = P('abcd')
|
|
1758
|
+
sage: p.area() #todo: not implemented
|
|
1759
|
+
2
|
|
1760
|
+
"""
|
|
1761
|
+
if not self.is_closed():
|
|
1762
|
+
raise TypeError("the path must be closed to compute its area")
|
|
1763
|
+
return NotImplemented
|
|
1764
|
+
|
|
1765
|
+
def height(self):
|
|
1766
|
+
r"""
|
|
1767
|
+
Return the height of ``self``.
|
|
1768
|
+
|
|
1769
|
+
The height of a `2d`-path is merely the difference
|
|
1770
|
+
between the highest and the lowest `y`-coordinate of each
|
|
1771
|
+
points traced by it.
|
|
1772
|
+
|
|
1773
|
+
OUTPUT: nonnegative real number
|
|
1774
|
+
|
|
1775
|
+
EXAMPLES::
|
|
1776
|
+
|
|
1777
|
+
sage: Freeman = WordPaths('abAB')
|
|
1778
|
+
sage: Freeman('aababaabbbAA').height()
|
|
1779
|
+
5
|
|
1780
|
+
|
|
1781
|
+
The function is well-defined if ``self`` is not simple or close::
|
|
1782
|
+
|
|
1783
|
+
sage: Freeman('aabAAB').height()
|
|
1784
|
+
1
|
|
1785
|
+
sage: Freeman('abbABa').height()
|
|
1786
|
+
2
|
|
1787
|
+
|
|
1788
|
+
This works for any `2d`-paths::
|
|
1789
|
+
|
|
1790
|
+
sage: Paths = WordPaths('ab', steps=[(1,0),(1,1)])
|
|
1791
|
+
sage: p = Paths('abbaa')
|
|
1792
|
+
sage: p.height()
|
|
1793
|
+
2
|
|
1794
|
+
sage: DyckPaths = WordPaths('ab', steps='dyck')
|
|
1795
|
+
sage: p = DyckPaths('abaabb')
|
|
1796
|
+
sage: p.height()
|
|
1797
|
+
2
|
|
1798
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
|
|
1799
|
+
sage: w.height() # needs sage.rings.number_field
|
|
1800
|
+
2.59807621135332
|
|
1801
|
+
"""
|
|
1802
|
+
return self.ymax() - self.ymin()
|
|
1803
|
+
|
|
1804
|
+
def height_vector(self):
|
|
1805
|
+
r"""
|
|
1806
|
+
Return the height at each point.
|
|
1807
|
+
|
|
1808
|
+
EXAMPLES::
|
|
1809
|
+
|
|
1810
|
+
sage: Paths = WordPaths('ab', steps=[(1,0),(0,1)])
|
|
1811
|
+
sage: p = Paths('abbba')
|
|
1812
|
+
sage: p.height_vector()
|
|
1813
|
+
[0, 0, 1, 2, 3, 3]
|
|
1814
|
+
"""
|
|
1815
|
+
h_vec = []
|
|
1816
|
+
y_min = None
|
|
1817
|
+
y_max = None
|
|
1818
|
+
for _, y in self.points():
|
|
1819
|
+
if y_min is None:
|
|
1820
|
+
y_min = y
|
|
1821
|
+
y_max = y
|
|
1822
|
+
else:
|
|
1823
|
+
y_max = max(y, y_max)
|
|
1824
|
+
y_min = min(y, y_min)
|
|
1825
|
+
h_vec.append(y_max - y_min)
|
|
1826
|
+
return h_vec
|
|
1827
|
+
|
|
1828
|
+
def width(self):
|
|
1829
|
+
r"""
|
|
1830
|
+
Return the width of ``self``.
|
|
1831
|
+
|
|
1832
|
+
The height of a `2d`-path is merely the difference
|
|
1833
|
+
between the rightmost and the leftmost `x`-coordinate of each
|
|
1834
|
+
points traced by it.
|
|
1835
|
+
|
|
1836
|
+
OUTPUT: nonnegative real number
|
|
1837
|
+
|
|
1838
|
+
EXAMPLES::
|
|
1839
|
+
|
|
1840
|
+
sage: Freeman = WordPaths('abAB')
|
|
1841
|
+
sage: Freeman('aababaabbbAA').width()
|
|
1842
|
+
5
|
|
1843
|
+
|
|
1844
|
+
The function is well-defined if ``self`` is not simple or close::
|
|
1845
|
+
|
|
1846
|
+
sage: Freeman('aabAAB').width()
|
|
1847
|
+
2
|
|
1848
|
+
sage: Freeman('abbABa').width()
|
|
1849
|
+
1
|
|
1850
|
+
|
|
1851
|
+
This works for any `2d`-paths::
|
|
1852
|
+
|
|
1853
|
+
sage: Paths = WordPaths('ab', steps=[(1,0),(1,1)])
|
|
1854
|
+
sage: p = Paths('abbaa')
|
|
1855
|
+
sage: p.width()
|
|
1856
|
+
5
|
|
1857
|
+
sage: DyckPaths = WordPaths('ab', steps='dyck')
|
|
1858
|
+
sage: p = DyckPaths('abaabb')
|
|
1859
|
+
sage: p.width()
|
|
1860
|
+
6
|
|
1861
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
|
|
1862
|
+
sage: w.width() # needs sage.rings.number_field
|
|
1863
|
+
4.50000000000000
|
|
1864
|
+
"""
|
|
1865
|
+
return self.xmax() - self.xmin()
|
|
1866
|
+
|
|
1867
|
+
def width_vector(self):
|
|
1868
|
+
r"""
|
|
1869
|
+
Return the width at each point.
|
|
1870
|
+
|
|
1871
|
+
EXAMPLES::
|
|
1872
|
+
|
|
1873
|
+
sage: Paths = WordPaths('ab', steps=[(1,0),(0,1)])
|
|
1874
|
+
sage: p = Paths('abbba')
|
|
1875
|
+
sage: p.width_vector()
|
|
1876
|
+
[0, 1, 1, 1, 1, 2]
|
|
1877
|
+
"""
|
|
1878
|
+
w_vec = []
|
|
1879
|
+
x_min = None
|
|
1880
|
+
x_max = None
|
|
1881
|
+
for x, _ in self.points():
|
|
1882
|
+
if x_min is None:
|
|
1883
|
+
x_min = x
|
|
1884
|
+
x_max = x
|
|
1885
|
+
else:
|
|
1886
|
+
x_max = max(x, x_max)
|
|
1887
|
+
x_min = min(x, x_min)
|
|
1888
|
+
w_vec.append(x_max - x_min)
|
|
1889
|
+
return w_vec
|
|
1890
|
+
|
|
1891
|
+
def xmin(self):
|
|
1892
|
+
r"""
|
|
1893
|
+
Return the minimum of the x-coordinates of the path.
|
|
1894
|
+
|
|
1895
|
+
EXAMPLES::
|
|
1896
|
+
|
|
1897
|
+
sage: P = WordPaths('0123')
|
|
1898
|
+
sage: p = P('0101013332')
|
|
1899
|
+
sage: p.xmin()
|
|
1900
|
+
0
|
|
1901
|
+
|
|
1902
|
+
This works for any `2d`-paths::
|
|
1903
|
+
|
|
1904
|
+
sage: Paths = WordPaths('ab', steps=[(1,0),(-1,1)])
|
|
1905
|
+
sage: p = Paths('abbba')
|
|
1906
|
+
sage: p.xmin()
|
|
1907
|
+
-2
|
|
1908
|
+
sage: DyckPaths = WordPaths('ab', steps='dyck')
|
|
1909
|
+
sage: p = DyckPaths('abaabb')
|
|
1910
|
+
sage: p.xmin()
|
|
1911
|
+
0
|
|
1912
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
|
|
1913
|
+
sage: w.xmin() # needs sage.rings.number_field
|
|
1914
|
+
0.000000000000000
|
|
1915
|
+
"""
|
|
1916
|
+
return min(x for (x, _) in self.points())
|
|
1917
|
+
|
|
1918
|
+
def ymin(self):
|
|
1919
|
+
r"""
|
|
1920
|
+
Return the minimum of the y-coordinates of the path.
|
|
1921
|
+
|
|
1922
|
+
EXAMPLES::
|
|
1923
|
+
|
|
1924
|
+
sage: P = WordPaths('0123')
|
|
1925
|
+
sage: p = P('0101013332')
|
|
1926
|
+
sage: p.ymin()
|
|
1927
|
+
0
|
|
1928
|
+
|
|
1929
|
+
This works for any `2d`-paths::
|
|
1930
|
+
|
|
1931
|
+
sage: Paths = WordPaths('ab', steps=[(1,-1),(-1,1)])
|
|
1932
|
+
sage: p = Paths('ababa')
|
|
1933
|
+
sage: p.ymin()
|
|
1934
|
+
-1
|
|
1935
|
+
sage: DyckPaths = WordPaths('ab', steps='dyck')
|
|
1936
|
+
sage: p = DyckPaths('abaabb')
|
|
1937
|
+
sage: p.ymin()
|
|
1938
|
+
0
|
|
1939
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
|
|
1940
|
+
sage: w.ymin() # needs sage.rings.number_field
|
|
1941
|
+
0.000000000000000
|
|
1942
|
+
"""
|
|
1943
|
+
return min(y for (_, y) in self.points())
|
|
1944
|
+
|
|
1945
|
+
def xmax(self):
|
|
1946
|
+
r"""
|
|
1947
|
+
Return the maximum of the x-coordinates of the path.
|
|
1948
|
+
|
|
1949
|
+
EXAMPLES::
|
|
1950
|
+
|
|
1951
|
+
sage: P = WordPaths('0123')
|
|
1952
|
+
sage: p = P('0101013332')
|
|
1953
|
+
sage: p.xmax()
|
|
1954
|
+
3
|
|
1955
|
+
|
|
1956
|
+
This works for any `2d`-paths::
|
|
1957
|
+
|
|
1958
|
+
sage: Paths = WordPaths('ab', steps=[(1,-1),(-1,1)])
|
|
1959
|
+
sage: p = Paths('ababa')
|
|
1960
|
+
sage: p.xmax()
|
|
1961
|
+
1
|
|
1962
|
+
sage: DyckPaths = WordPaths('ab', steps='dyck')
|
|
1963
|
+
sage: p = DyckPaths('abaabb')
|
|
1964
|
+
sage: p.xmax()
|
|
1965
|
+
6
|
|
1966
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
|
|
1967
|
+
sage: w.xmax() # needs sage.rings.number_field
|
|
1968
|
+
4.50000000000000
|
|
1969
|
+
"""
|
|
1970
|
+
return max(x for (x, _) in self.points())
|
|
1971
|
+
|
|
1972
|
+
def ymax(self):
|
|
1973
|
+
r"""
|
|
1974
|
+
Return the maximum of the y-coordinates of the path.
|
|
1975
|
+
|
|
1976
|
+
EXAMPLES::
|
|
1977
|
+
|
|
1978
|
+
sage: P = WordPaths('0123')
|
|
1979
|
+
sage: p = P('0101013332')
|
|
1980
|
+
sage: p.ymax()
|
|
1981
|
+
3
|
|
1982
|
+
|
|
1983
|
+
This works for any `2d`-paths::
|
|
1984
|
+
|
|
1985
|
+
sage: Paths = WordPaths('ab', steps=[(1,-1),(-1,1)])
|
|
1986
|
+
sage: p = Paths('ababa')
|
|
1987
|
+
sage: p.ymax()
|
|
1988
|
+
0
|
|
1989
|
+
sage: DyckPaths = WordPaths('ab', steps='dyck')
|
|
1990
|
+
sage: p = DyckPaths('abaabb')
|
|
1991
|
+
sage: p.ymax()
|
|
1992
|
+
2
|
|
1993
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC') # needs sage.rings.number_field
|
|
1994
|
+
sage: w.ymax() # needs sage.rings.number_field
|
|
1995
|
+
2.59807621135332
|
|
1996
|
+
"""
|
|
1997
|
+
return max(y for (_, y) in self.points())
|
|
1998
|
+
|
|
1999
|
+
|
|
2000
|
+
class FiniteWordPath_3d(FiniteWordPath_all):
|
|
2001
|
+
def plot(self, pathoptions={"rgbcolor": 'red', "arrow_head": True, "thickness": 3},
|
|
2002
|
+
startpoint=True, startoptions={"rgbcolor": 'red', "size": 10}):
|
|
2003
|
+
r"""
|
|
2004
|
+
INPUT:
|
|
2005
|
+
|
|
2006
|
+
- ``pathoptions`` -- (dict, default:dict(rgbcolor='red',arrow_head=True,
|
|
2007
|
+
thickness=3)), options for the path drawing
|
|
2008
|
+
|
|
2009
|
+
- ``startpoint`` -- boolean (default: ``True``); draw the start point?
|
|
2010
|
+
|
|
2011
|
+
- ``startoptions`` -- (dict, default:dict(rgbcolor='red',size=10))
|
|
2012
|
+
options for the start point drawing
|
|
2013
|
+
|
|
2014
|
+
EXAMPLES::
|
|
2015
|
+
|
|
2016
|
+
sage: d = ( vector((1,3,2)), vector((2,-4,5)) )
|
|
2017
|
+
sage: P = WordPaths(alphabet='ab', steps=d); P
|
|
2018
|
+
Word Paths over 2 steps
|
|
2019
|
+
sage: p = P('ababab'); p
|
|
2020
|
+
Path: ababab
|
|
2021
|
+
sage: p.plot() # needs sage.plot
|
|
2022
|
+
Graphics3d Object
|
|
2023
|
+
|
|
2024
|
+
sage: P = WordPaths('abcABC', steps='cube_grid')
|
|
2025
|
+
sage: p = P('abcabcAABBC')
|
|
2026
|
+
sage: p.plot() # needs sage.plot
|
|
2027
|
+
Graphics3d Object
|
|
2028
|
+
"""
|
|
2029
|
+
# The following line seems not to work for 3d
|
|
2030
|
+
# G = Graphics()
|
|
2031
|
+
# so we draw to start a small almost invisible point instead:
|
|
2032
|
+
G = point([self.start_point()], size=1)
|
|
2033
|
+
pts = list(self.points())
|
|
2034
|
+
if startpoint:
|
|
2035
|
+
G += point([pts[0]], **startoptions)
|
|
2036
|
+
G += line(pts, **pathoptions)
|
|
2037
|
+
return G
|
|
2038
|
+
|
|
2039
|
+
|
|
2040
|
+
#######################################################################
|
|
2041
|
+
# #
|
|
2042
|
+
# Abstract word path classes #
|
|
2043
|
+
# (square grid, hexagonal grid, etc.) #
|
|
2044
|
+
# #
|
|
2045
|
+
#######################################################################
|
|
2046
|
+
|
|
2047
|
+
class FiniteWordPath_square_grid(FiniteWordPath_2d):
|
|
2048
|
+
def is_closed(self) -> bool:
|
|
2049
|
+
r"""
|
|
2050
|
+
Return whether ``self`` represents a closed path.
|
|
2051
|
+
|
|
2052
|
+
EXAMPLES::
|
|
2053
|
+
|
|
2054
|
+
sage: P = WordPaths('abAB', steps='square_grid')
|
|
2055
|
+
sage: P('aA').is_closed()
|
|
2056
|
+
True
|
|
2057
|
+
sage: P('abAB').is_closed()
|
|
2058
|
+
True
|
|
2059
|
+
sage: P('ababAABB').is_closed()
|
|
2060
|
+
True
|
|
2061
|
+
sage: P('aaabbbAABB').is_closed()
|
|
2062
|
+
False
|
|
2063
|
+
sage: P('ab').is_closed()
|
|
2064
|
+
False
|
|
2065
|
+
"""
|
|
2066
|
+
tab = self.abelian_vector()
|
|
2067
|
+
return tab[0] == tab[2] and tab[1] == tab[3]
|
|
2068
|
+
|
|
2069
|
+
def area(self):
|
|
2070
|
+
r"""
|
|
2071
|
+
Return the area of a closed path.
|
|
2072
|
+
|
|
2073
|
+
INPUT:
|
|
2074
|
+
|
|
2075
|
+
- ``self`` -- a closed path
|
|
2076
|
+
|
|
2077
|
+
EXAMPLES::
|
|
2078
|
+
|
|
2079
|
+
sage: P = WordPaths('abAB', steps='square_grid')
|
|
2080
|
+
sage: P('abAB').area()
|
|
2081
|
+
1
|
|
2082
|
+
sage: P('aabbAABB').area()
|
|
2083
|
+
4
|
|
2084
|
+
sage: P('aabbABAB').area()
|
|
2085
|
+
3
|
|
2086
|
+
|
|
2087
|
+
The area of the Fibonacci tiles::
|
|
2088
|
+
|
|
2089
|
+
sage: [words.fibonacci_tile(i).area() for i in range(6)]
|
|
2090
|
+
[1, 5, 29, 169, 985, 5741]
|
|
2091
|
+
sage: [words.dual_fibonacci_tile(i).area() for i in range(6)]
|
|
2092
|
+
[1, 5, 29, 169, 985, 5741]
|
|
2093
|
+
sage: oeis(_)[0] # optional -- internet
|
|
2094
|
+
A001653: Numbers k such that 2*k^2 - 1 is a square.
|
|
2095
|
+
sage: _.first_terms() # optional -- internet
|
|
2096
|
+
(1,
|
|
2097
|
+
5,
|
|
2098
|
+
29,
|
|
2099
|
+
169,
|
|
2100
|
+
985,
|
|
2101
|
+
5741,
|
|
2102
|
+
33461,
|
|
2103
|
+
195025,
|
|
2104
|
+
1136689,
|
|
2105
|
+
6625109,
|
|
2106
|
+
38613965,
|
|
2107
|
+
225058681,
|
|
2108
|
+
1311738121,
|
|
2109
|
+
7645370045,
|
|
2110
|
+
44560482149,
|
|
2111
|
+
259717522849,
|
|
2112
|
+
1513744654945,
|
|
2113
|
+
8822750406821,
|
|
2114
|
+
51422757785981,
|
|
2115
|
+
299713796309065,
|
|
2116
|
+
1746860020068409,
|
|
2117
|
+
10181446324101389,
|
|
2118
|
+
59341817924539925)
|
|
2119
|
+
|
|
2120
|
+
TESTS::
|
|
2121
|
+
|
|
2122
|
+
sage: P = WordPaths('abAB', steps='square_grid')
|
|
2123
|
+
sage: P('a').area()
|
|
2124
|
+
Traceback (most recent call last):
|
|
2125
|
+
...
|
|
2126
|
+
TypeError: the path must be closed to compute its area
|
|
2127
|
+
"""
|
|
2128
|
+
if not self.is_closed():
|
|
2129
|
+
raise TypeError("the path must be closed to compute its area")
|
|
2130
|
+
return abs(self._area_vh())
|
|
2131
|
+
|
|
2132
|
+
def _area_vh(self, x=0, y=0):
|
|
2133
|
+
r"""
|
|
2134
|
+
Return the area of ``self``, with starting point (x,y).
|
|
2135
|
+
|
|
2136
|
+
This is using VH algorithm.
|
|
2137
|
+
|
|
2138
|
+
INPUT:
|
|
2139
|
+
|
|
2140
|
+
- x, y -- starting point (default: (0, 0))
|
|
2141
|
+
|
|
2142
|
+
EXAMPLES::
|
|
2143
|
+
|
|
2144
|
+
sage: P = WordPaths('abAB', steps='square_grid')
|
|
2145
|
+
sage: P('abAB')._area_vh()
|
|
2146
|
+
-1
|
|
2147
|
+
sage: P('aabbAABB')._area_vh()
|
|
2148
|
+
-4
|
|
2149
|
+
sage: P('aabbABAB')._area_vh()
|
|
2150
|
+
-3
|
|
2151
|
+
|
|
2152
|
+
REFERENCES:
|
|
2153
|
+
|
|
2154
|
+
Annie Lacasse Memoire.
|
|
2155
|
+
"""
|
|
2156
|
+
area = 0
|
|
2157
|
+
a, b, A, B = self.parent().alphabet()
|
|
2158
|
+
|
|
2159
|
+
for move in self:
|
|
2160
|
+
if move == b:
|
|
2161
|
+
area -= x
|
|
2162
|
+
y += 1
|
|
2163
|
+
elif move == B:
|
|
2164
|
+
area += x
|
|
2165
|
+
y -= 1
|
|
2166
|
+
elif move == a:
|
|
2167
|
+
area += y
|
|
2168
|
+
x += 1
|
|
2169
|
+
elif move == A:
|
|
2170
|
+
area -= y
|
|
2171
|
+
x -= 1
|
|
2172
|
+
return area // 2
|
|
2173
|
+
|
|
2174
|
+
def is_simple(self) -> bool:
|
|
2175
|
+
r"""
|
|
2176
|
+
Return whether the path is simple.
|
|
2177
|
+
|
|
2178
|
+
A path is simple if all its points are
|
|
2179
|
+
distinct.
|
|
2180
|
+
|
|
2181
|
+
If the path is closed, the last point is not considered.
|
|
2182
|
+
|
|
2183
|
+
.. NOTE::
|
|
2184
|
+
|
|
2185
|
+
The linear algorithm described in the thesis of Xavier Provençal
|
|
2186
|
+
should be implemented here.
|
|
2187
|
+
|
|
2188
|
+
EXAMPLES::
|
|
2189
|
+
|
|
2190
|
+
sage: P = WordPaths('abAB', steps='square_grid')
|
|
2191
|
+
sage: P('abab').is_simple()
|
|
2192
|
+
True
|
|
2193
|
+
sage: P('abAB').is_simple()
|
|
2194
|
+
True
|
|
2195
|
+
sage: P('abA').is_simple()
|
|
2196
|
+
True
|
|
2197
|
+
sage: P('aabABB').is_simple()
|
|
2198
|
+
False
|
|
2199
|
+
sage: P().is_simple()
|
|
2200
|
+
True
|
|
2201
|
+
sage: P('A').is_simple()
|
|
2202
|
+
True
|
|
2203
|
+
sage: P('aA').is_simple()
|
|
2204
|
+
True
|
|
2205
|
+
sage: P('aaA').is_simple()
|
|
2206
|
+
False
|
|
2207
|
+
|
|
2208
|
+
REFERENCES:
|
|
2209
|
+
|
|
2210
|
+
- Provençal, X., *Combinatoires des mots, géometrie discrète et
|
|
2211
|
+
pavages*, Thèse de doctorat en Mathématiques, Montréal, UQAM,
|
|
2212
|
+
septembre 2008, 115 pages.
|
|
2213
|
+
"""
|
|
2214
|
+
return super().is_simple()
|
|
2215
|
+
|
|
2216
|
+
def tikz_trajectory(self) -> str:
|
|
2217
|
+
r"""
|
|
2218
|
+
Return the trajectory of ``self`` as a ``tikz`` string.
|
|
2219
|
+
|
|
2220
|
+
EXAMPLES::
|
|
2221
|
+
|
|
2222
|
+
sage: f = words.fibonacci_tile(1)
|
|
2223
|
+
sage: f.tikz_trajectory()
|
|
2224
|
+
'(0, 0) -- (0, -1) -- (-1, -1) -- (-1, -2) -- (0, -2) -- (0, -3) -- (1, -3) -- (1, -2) -- (2, -2) -- (2, -1) -- (1, -1) -- (1, 0) -- (0, 0)'
|
|
2225
|
+
"""
|
|
2226
|
+
return ' -- '.join(map(str, self.points()))
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
class FiniteWordPath_triangle_grid(FiniteWordPath_2d):
|
|
2230
|
+
# Triangle grid paths are implemented with quadratic fields,
|
|
2231
|
+
# and the ordering of such elements is currently problematic:
|
|
2232
|
+
#
|
|
2233
|
+
# sage: Q.<sqrt3> = QuadraticField(3)
|
|
2234
|
+
# sage: sqrt3 > 0
|
|
2235
|
+
# True
|
|
2236
|
+
# sage: 0 < sqrt3
|
|
2237
|
+
# False
|
|
2238
|
+
# sage: max(2*sqrt3, sqrt3/10)
|
|
2239
|
+
# 1/10*sqrt3
|
|
2240
|
+
#
|
|
2241
|
+
# Therefore, the functions xmin(), xmax(), ymin() and ymax() are
|
|
2242
|
+
# redefined here with conversion to RR in order to avoid this problem
|
|
2243
|
+
def xmin(self):
|
|
2244
|
+
r"""
|
|
2245
|
+
Return the minimum of the x-coordinates of the path.
|
|
2246
|
+
|
|
2247
|
+
EXAMPLES::
|
|
2248
|
+
|
|
2249
|
+
sage: # needs sage.rings.number_field
|
|
2250
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
|
|
2251
|
+
sage: w.xmin()
|
|
2252
|
+
0.000000000000000
|
|
2253
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
|
|
2254
|
+
sage: w.xmin()
|
|
2255
|
+
-3.00000000000000
|
|
2256
|
+
"""
|
|
2257
|
+
return min(RR(x) for (x, _) in self.points())
|
|
2258
|
+
|
|
2259
|
+
def ymin(self):
|
|
2260
|
+
r"""
|
|
2261
|
+
Return the minimum of the y-coordinates of the path.
|
|
2262
|
+
|
|
2263
|
+
EXAMPLES::
|
|
2264
|
+
|
|
2265
|
+
sage: # needs sage.rings.number_field
|
|
2266
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
|
|
2267
|
+
sage: w.ymin()
|
|
2268
|
+
0.000000000000000
|
|
2269
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
|
|
2270
|
+
sage: w.ymin()
|
|
2271
|
+
-0.866025403784439
|
|
2272
|
+
"""
|
|
2273
|
+
return min(RR(y) for (_, y) in self.points())
|
|
2274
|
+
|
|
2275
|
+
def xmax(self):
|
|
2276
|
+
r"""
|
|
2277
|
+
Return the maximum of the x-coordinates of the path.
|
|
2278
|
+
|
|
2279
|
+
EXAMPLES::
|
|
2280
|
+
|
|
2281
|
+
sage: # needs sage.rings.number_field
|
|
2282
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
|
|
2283
|
+
sage: w.xmax()
|
|
2284
|
+
4.50000000000000
|
|
2285
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
|
|
2286
|
+
sage: w.xmax()
|
|
2287
|
+
4.00000000000000
|
|
2288
|
+
"""
|
|
2289
|
+
return max(RR(x) for (x, _) in self.points())
|
|
2290
|
+
|
|
2291
|
+
def ymax(self):
|
|
2292
|
+
r"""
|
|
2293
|
+
Return the maximum of the y-coordinates of the path.
|
|
2294
|
+
|
|
2295
|
+
EXAMPLES::
|
|
2296
|
+
|
|
2297
|
+
sage: # needs sage.rings.number_field
|
|
2298
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ababcaaBC')
|
|
2299
|
+
sage: w.ymax()
|
|
2300
|
+
2.59807621135332
|
|
2301
|
+
sage: w = WordPaths('abcABC', steps='triangle')('ABAcacacababababcbcbAC')
|
|
2302
|
+
sage: w.ymax()
|
|
2303
|
+
8.66025403784439
|
|
2304
|
+
"""
|
|
2305
|
+
return max(RR(y) for (_, y) in self.points())
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
# TODO: faire une verification du mot pour etre sur hexagonal grid
|
|
2309
|
+
class FiniteWordPath_hexagonal_grid(FiniteWordPath_triangle_grid):
|
|
2310
|
+
def __init__(self, parent, *args, **kwds):
|
|
2311
|
+
r"""
|
|
2312
|
+
INPUT:
|
|
2313
|
+
|
|
2314
|
+
- ``parent`` -- a parent object inheriting from Words_all
|
|
2315
|
+
that has the alphabet attribute defined
|
|
2316
|
+
|
|
2317
|
+
- ``*args``, ``**kwds`` -- arguments accepted by AbstractWord
|
|
2318
|
+
|
|
2319
|
+
EXAMPLES::
|
|
2320
|
+
|
|
2321
|
+
sage: # needs sage.rings.number_field
|
|
2322
|
+
sage: F = WordPaths('abcdef', steps='hexagon'); F
|
|
2323
|
+
Word Paths on the hexagonal grid
|
|
2324
|
+
sage: f = F('aaabbbccddef'); f
|
|
2325
|
+
Path: aaabbbccddef
|
|
2326
|
+
|
|
2327
|
+
::
|
|
2328
|
+
|
|
2329
|
+
sage: f == loads(dumps(f)) # needs sage.rings.number_field
|
|
2330
|
+
True
|
|
2331
|
+
"""
|
|
2332
|
+
super().__init__(parent, *args, **kwds)
|
|
2333
|
+
|
|
2334
|
+
|
|
2335
|
+
class FiniteWordPath_cube_grid(FiniteWordPath_3d):
|
|
2336
|
+
pass
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
class FiniteWordPath_north_east(FiniteWordPath_2d):
|
|
2340
|
+
pass
|
|
2341
|
+
|
|
2342
|
+
|
|
2343
|
+
class FiniteWordPath_dyck(FiniteWordPath_2d):
|
|
2344
|
+
pass
|
|
2345
|
+
|
|
2346
|
+
|
|
2347
|
+
#######################################################################
|
|
2348
|
+
# #
|
|
2349
|
+
# Concrete word path classes #
|
|
2350
|
+
# #
|
|
2351
|
+
# It would be nice if those were created inline... #
|
|
2352
|
+
# We must ask if Nicolas Thiery was able to convince Sage #
|
|
2353
|
+
# people about this. #
|
|
2354
|
+
# #
|
|
2355
|
+
#######################################################################
|
|
2356
|
+
|
|
2357
|
+
# #### Finite paths ####
|
|
2358
|
+
|
|
2359
|
+
class FiniteWordPath_all_list(WordDatatype_list, FiniteWordPath_all, FiniteWord_class):
|
|
2360
|
+
r"""
|
|
2361
|
+
TESTS::
|
|
2362
|
+
|
|
2363
|
+
sage: P = WordPaths(['a','b'],[(1,2,0,0),(3,4,0,0)])
|
|
2364
|
+
sage: p = P(['a','b','a']);p
|
|
2365
|
+
Path: aba
|
|
2366
|
+
sage: type(p)
|
|
2367
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_all_list'>
|
|
2368
|
+
sage: p == loads(dumps(p))
|
|
2369
|
+
True
|
|
2370
|
+
"""
|
|
2371
|
+
pass
|
|
2372
|
+
|
|
2373
|
+
|
|
2374
|
+
class FiniteWordPath_all_str(WordDatatype_str, FiniteWordPath_all, FiniteWord_class):
|
|
2375
|
+
r"""
|
|
2376
|
+
TESTS::
|
|
2377
|
+
|
|
2378
|
+
sage: P = WordPaths('ab',[(1,2,0,0),(3,4,0,0)])
|
|
2379
|
+
sage: p = P('aabbb'); p
|
|
2380
|
+
Path: aabbb
|
|
2381
|
+
sage: type(p)
|
|
2382
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_all_str'>
|
|
2383
|
+
sage: p == loads(dumps(p))
|
|
2384
|
+
True
|
|
2385
|
+
"""
|
|
2386
|
+
pass
|
|
2387
|
+
|
|
2388
|
+
|
|
2389
|
+
class FiniteWordPath_all_tuple(WordDatatype_tuple, FiniteWordPath_all, FiniteWord_class):
|
|
2390
|
+
r"""
|
|
2391
|
+
TESTS::
|
|
2392
|
+
|
|
2393
|
+
sage: P = WordPaths('ab',[(1,2,0,0),(3,4,0,0)])
|
|
2394
|
+
sage: p = P( ('a','b','b') ); p
|
|
2395
|
+
Path: abb
|
|
2396
|
+
sage: type(p)
|
|
2397
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_all_tuple'>
|
|
2398
|
+
sage: p == loads(dumps(p))
|
|
2399
|
+
True
|
|
2400
|
+
"""
|
|
2401
|
+
pass
|
|
2402
|
+
|
|
2403
|
+
|
|
2404
|
+
class FiniteWordPath_all_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_all, FiniteWord_class):
|
|
2405
|
+
pass
|
|
2406
|
+
|
|
2407
|
+
|
|
2408
|
+
class FiniteWordPath_all_iter(WordDatatype_iter, FiniteWordPath_all, FiniteWord_class):
|
|
2409
|
+
pass
|
|
2410
|
+
|
|
2411
|
+
|
|
2412
|
+
class FiniteWordPath_all_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_all, FiniteWord_class):
|
|
2413
|
+
pass
|
|
2414
|
+
|
|
2415
|
+
|
|
2416
|
+
class FiniteWordPath_all_callable(WordDatatype_callable, FiniteWordPath_all, FiniteWord_class):
|
|
2417
|
+
pass
|
|
2418
|
+
|
|
2419
|
+
|
|
2420
|
+
# #### Finite paths on 2d ####
|
|
2421
|
+
|
|
2422
|
+
class FiniteWordPath_2d_list(WordDatatype_list, FiniteWordPath_2d, FiniteWord_class):
|
|
2423
|
+
r"""
|
|
2424
|
+
TESTS::
|
|
2425
|
+
|
|
2426
|
+
sage: P = WordPaths(['a','b'],[(1,2),(3,4)])
|
|
2427
|
+
sage: p = P(['a','b','a']);p
|
|
2428
|
+
Path: aba
|
|
2429
|
+
sage: type(p)
|
|
2430
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_2d_list'>
|
|
2431
|
+
sage: p == loads(dumps(p))
|
|
2432
|
+
True
|
|
2433
|
+
"""
|
|
2434
|
+
pass
|
|
2435
|
+
|
|
2436
|
+
|
|
2437
|
+
class FiniteWordPath_2d_str(WordDatatype_str, FiniteWordPath_2d, FiniteWord_class):
|
|
2438
|
+
r"""
|
|
2439
|
+
TESTS::
|
|
2440
|
+
|
|
2441
|
+
sage: P = WordPaths(['a','b'],[(1,2),(3,4)])
|
|
2442
|
+
sage: p = P('aba'); p
|
|
2443
|
+
Path: aba
|
|
2444
|
+
sage: type(p)
|
|
2445
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_2d_str'>
|
|
2446
|
+
sage: p == loads(dumps(p))
|
|
2447
|
+
True
|
|
2448
|
+
"""
|
|
2449
|
+
pass
|
|
2450
|
+
|
|
2451
|
+
|
|
2452
|
+
class FiniteWordPath_2d_tuple(WordDatatype_tuple, FiniteWordPath_2d, FiniteWord_class):
|
|
2453
|
+
r"""
|
|
2454
|
+
TESTS::
|
|
2455
|
+
|
|
2456
|
+
sage: P = WordPaths(['a','b'],[(1,2),(3,4)])
|
|
2457
|
+
sage: p = P(('a','b','a'));p
|
|
2458
|
+
Path: aba
|
|
2459
|
+
sage: type(p)
|
|
2460
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_2d_tuple'>
|
|
2461
|
+
sage: p == loads(dumps(p))
|
|
2462
|
+
True
|
|
2463
|
+
"""
|
|
2464
|
+
pass
|
|
2465
|
+
|
|
2466
|
+
|
|
2467
|
+
class FiniteWordPath_2d_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_2d, FiniteWord_class):
|
|
2468
|
+
pass
|
|
2469
|
+
|
|
2470
|
+
|
|
2471
|
+
class FiniteWordPath_2d_iter(WordDatatype_iter, FiniteWordPath_2d, FiniteWord_class):
|
|
2472
|
+
pass
|
|
2473
|
+
|
|
2474
|
+
|
|
2475
|
+
class FiniteWordPath_2d_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_2d, FiniteWord_class):
|
|
2476
|
+
pass
|
|
2477
|
+
|
|
2478
|
+
|
|
2479
|
+
class FiniteWordPath_2d_callable(WordDatatype_callable, FiniteWordPath_2d, FiniteWord_class):
|
|
2480
|
+
pass
|
|
2481
|
+
|
|
2482
|
+
|
|
2483
|
+
# #### Finite paths on 3d ####
|
|
2484
|
+
|
|
2485
|
+
class FiniteWordPath_3d_list(WordDatatype_list, FiniteWordPath_3d, FiniteWord_class):
|
|
2486
|
+
r"""
|
|
2487
|
+
TESTS::
|
|
2488
|
+
|
|
2489
|
+
sage: P = WordPaths(['a','b'],[(1,2,0),(3,4,0)])
|
|
2490
|
+
sage: p = P(['a','b','a']);p
|
|
2491
|
+
Path: aba
|
|
2492
|
+
sage: type(p)
|
|
2493
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_3d_list'>
|
|
2494
|
+
sage: p == loads(dumps(p))
|
|
2495
|
+
True
|
|
2496
|
+
"""
|
|
2497
|
+
pass
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
class FiniteWordPath_3d_str(WordDatatype_str, FiniteWordPath_3d, FiniteWord_class):
|
|
2501
|
+
r"""
|
|
2502
|
+
TESTS::
|
|
2503
|
+
|
|
2504
|
+
sage: P = WordPaths(['a','b'],[(1,2,0),(3,4,0)])
|
|
2505
|
+
sage: p = P('aba'); p
|
|
2506
|
+
Path: aba
|
|
2507
|
+
sage: type(p)
|
|
2508
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_3d_str'>
|
|
2509
|
+
sage: p == loads(dumps(p))
|
|
2510
|
+
True
|
|
2511
|
+
"""
|
|
2512
|
+
pass
|
|
2513
|
+
|
|
2514
|
+
|
|
2515
|
+
class FiniteWordPath_3d_tuple(WordDatatype_tuple, FiniteWordPath_3d, FiniteWord_class):
|
|
2516
|
+
r"""
|
|
2517
|
+
TESTS::
|
|
2518
|
+
|
|
2519
|
+
sage: P = WordPaths(['a','b'],[(1,2,0),(3,4,0)])
|
|
2520
|
+
sage: p = P(('a','b','a'));p
|
|
2521
|
+
Path: aba
|
|
2522
|
+
sage: type(p)
|
|
2523
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_3d_tuple'>
|
|
2524
|
+
sage: p == loads(dumps(p))
|
|
2525
|
+
True
|
|
2526
|
+
"""
|
|
2527
|
+
pass
|
|
2528
|
+
|
|
2529
|
+
|
|
2530
|
+
class FiniteWordPath_3d_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_3d, FiniteWord_class):
|
|
2531
|
+
pass
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
class FiniteWordPath_3d_iter(WordDatatype_iter, FiniteWordPath_3d, FiniteWord_class):
|
|
2535
|
+
pass
|
|
2536
|
+
|
|
2537
|
+
|
|
2538
|
+
class FiniteWordPath_3d_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_3d, FiniteWord_class):
|
|
2539
|
+
pass
|
|
2540
|
+
|
|
2541
|
+
|
|
2542
|
+
class FiniteWordPath_3d_callable(WordDatatype_callable, FiniteWordPath_3d, FiniteWord_class):
|
|
2543
|
+
pass
|
|
2544
|
+
|
|
2545
|
+
|
|
2546
|
+
# #### Finite paths on square grid ####
|
|
2547
|
+
|
|
2548
|
+
class FiniteWordPath_square_grid_list(WordDatatype_list, FiniteWordPath_square_grid, FiniteWord_class):
|
|
2549
|
+
r"""
|
|
2550
|
+
TESTS::
|
|
2551
|
+
|
|
2552
|
+
sage: P = WordPaths('abcd', steps='square')
|
|
2553
|
+
sage: p = P(['a','b','b']); p
|
|
2554
|
+
Path: abb
|
|
2555
|
+
sage: type(p)
|
|
2556
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_square_grid_list'>
|
|
2557
|
+
sage: p == loads(dumps(p))
|
|
2558
|
+
True
|
|
2559
|
+
"""
|
|
2560
|
+
pass
|
|
2561
|
+
|
|
2562
|
+
|
|
2563
|
+
class FiniteWordPath_square_grid_str(WordDatatype_str, FiniteWordPath_square_grid, FiniteWord_class):
|
|
2564
|
+
r"""
|
|
2565
|
+
TESTS::
|
|
2566
|
+
|
|
2567
|
+
sage: P = WordPaths('abcd', steps='square')
|
|
2568
|
+
sage: p = P('abccc'); p
|
|
2569
|
+
Path: abccc
|
|
2570
|
+
sage: type(p)
|
|
2571
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_square_grid_str'>
|
|
2572
|
+
sage: p == loads(dumps(p))
|
|
2573
|
+
True
|
|
2574
|
+
"""
|
|
2575
|
+
pass
|
|
2576
|
+
|
|
2577
|
+
|
|
2578
|
+
class FiniteWordPath_square_grid_tuple(WordDatatype_tuple, FiniteWordPath_square_grid, FiniteWord_class):
|
|
2579
|
+
r"""
|
|
2580
|
+
TESTS::
|
|
2581
|
+
|
|
2582
|
+
sage: P = WordPaths('abcd', steps='square')
|
|
2583
|
+
sage: p = P(('a','b','b')); p
|
|
2584
|
+
Path: abb
|
|
2585
|
+
sage: type(p)
|
|
2586
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_square_grid_tuple'>
|
|
2587
|
+
sage: p == loads(dumps(p))
|
|
2588
|
+
True
|
|
2589
|
+
"""
|
|
2590
|
+
pass
|
|
2591
|
+
|
|
2592
|
+
|
|
2593
|
+
class FiniteWordPath_square_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_square_grid, FiniteWord_class):
|
|
2594
|
+
pass
|
|
2595
|
+
|
|
2596
|
+
|
|
2597
|
+
class FiniteWordPath_square_grid_iter(WordDatatype_iter, FiniteWordPath_square_grid, FiniteWord_class):
|
|
2598
|
+
pass
|
|
2599
|
+
|
|
2600
|
+
|
|
2601
|
+
class FiniteWordPath_square_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_square_grid, FiniteWord_class):
|
|
2602
|
+
pass
|
|
2603
|
+
|
|
2604
|
+
|
|
2605
|
+
class FiniteWordPath_square_grid_callable(WordDatatype_callable, FiniteWordPath_square_grid, FiniteWord_class):
|
|
2606
|
+
pass
|
|
2607
|
+
|
|
2608
|
+
|
|
2609
|
+
# #### Unknown length paths on square grid (experimental) ####
|
|
2610
|
+
|
|
2611
|
+
# class WordPath_square_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_square_grid, Word_class):
|
|
2612
|
+
# pass
|
|
2613
|
+
|
|
2614
|
+
# #### Finite paths on triangle grid ####
|
|
2615
|
+
|
|
2616
|
+
class FiniteWordPath_triangle_grid_list(WordDatatype_list, FiniteWordPath_triangle_grid, FiniteWord_class):
|
|
2617
|
+
r"""
|
|
2618
|
+
TESTS::
|
|
2619
|
+
|
|
2620
|
+
sage: # needs sage.rings.number_field
|
|
2621
|
+
sage: P = WordPaths('abcdef', steps='triangle')
|
|
2622
|
+
sage: p = P(['a','b','b']); p
|
|
2623
|
+
Path: abb
|
|
2624
|
+
sage: type(p)
|
|
2625
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_list'>
|
|
2626
|
+
sage: p == loads(dumps(p))
|
|
2627
|
+
True
|
|
2628
|
+
"""
|
|
2629
|
+
pass
|
|
2630
|
+
|
|
2631
|
+
|
|
2632
|
+
class FiniteWordPath_triangle_grid_str(WordDatatype_str, FiniteWordPath_triangle_grid, FiniteWord_class):
|
|
2633
|
+
r"""
|
|
2634
|
+
TESTS::
|
|
2635
|
+
|
|
2636
|
+
sage: # needs sage.rings.number_field
|
|
2637
|
+
sage: P = WordPaths('abcdef', steps='triangle')
|
|
2638
|
+
sage: p = P('abb'); p
|
|
2639
|
+
Path: abb
|
|
2640
|
+
sage: type(p)
|
|
2641
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_str'>
|
|
2642
|
+
sage: p == loads(dumps(p))
|
|
2643
|
+
True
|
|
2644
|
+
"""
|
|
2645
|
+
pass
|
|
2646
|
+
|
|
2647
|
+
|
|
2648
|
+
class FiniteWordPath_triangle_grid_tuple(WordDatatype_tuple, FiniteWordPath_triangle_grid, FiniteWord_class):
|
|
2649
|
+
r"""
|
|
2650
|
+
TESTS::
|
|
2651
|
+
|
|
2652
|
+
sage: # needs sage.rings.number_field
|
|
2653
|
+
sage: P = WordPaths('abcdef', steps='triangle')
|
|
2654
|
+
sage: p = P(('a','b','b')); p
|
|
2655
|
+
Path: abb
|
|
2656
|
+
sage: type(p)
|
|
2657
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_triangle_grid_tuple'>
|
|
2658
|
+
sage: p == loads(dumps(p))
|
|
2659
|
+
True
|
|
2660
|
+
"""
|
|
2661
|
+
pass
|
|
2662
|
+
|
|
2663
|
+
|
|
2664
|
+
class FiniteWordPath_triangle_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_triangle_grid, FiniteWord_class):
|
|
2665
|
+
pass
|
|
2666
|
+
|
|
2667
|
+
|
|
2668
|
+
class FiniteWordPath_triangle_grid_iter(WordDatatype_iter, FiniteWordPath_triangle_grid, FiniteWord_class):
|
|
2669
|
+
pass
|
|
2670
|
+
|
|
2671
|
+
|
|
2672
|
+
class FiniteWordPath_triangle_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_triangle_grid, FiniteWord_class):
|
|
2673
|
+
pass
|
|
2674
|
+
|
|
2675
|
+
|
|
2676
|
+
class FiniteWordPath_triangle_grid_callable(WordDatatype_callable, FiniteWordPath_triangle_grid, FiniteWord_class):
|
|
2677
|
+
pass
|
|
2678
|
+
|
|
2679
|
+
|
|
2680
|
+
# #### Finite paths on hexagonal grid ####
|
|
2681
|
+
|
|
2682
|
+
class FiniteWordPath_hexagonal_grid_list(WordDatatype_list, FiniteWordPath_hexagonal_grid, FiniteWord_class):
|
|
2683
|
+
r"""
|
|
2684
|
+
TESTS::
|
|
2685
|
+
|
|
2686
|
+
sage: # needs sage.rings.number_field
|
|
2687
|
+
sage: P = WordPaths('abcdef', steps='hexagon')
|
|
2688
|
+
sage: p = P(['a','b','b']); p
|
|
2689
|
+
Path: abb
|
|
2690
|
+
sage: type(p)
|
|
2691
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_list'>
|
|
2692
|
+
sage: p == loads(dumps(p))
|
|
2693
|
+
True
|
|
2694
|
+
"""
|
|
2695
|
+
pass
|
|
2696
|
+
|
|
2697
|
+
|
|
2698
|
+
class FiniteWordPath_hexagonal_grid_str(WordDatatype_str, FiniteWordPath_hexagonal_grid, FiniteWord_class):
|
|
2699
|
+
r"""
|
|
2700
|
+
TESTS::
|
|
2701
|
+
|
|
2702
|
+
sage: # needs sage.rings.number_field
|
|
2703
|
+
sage: P = WordPaths('abcdef', steps='hexagon')
|
|
2704
|
+
sage: p = P('abb'); p
|
|
2705
|
+
Path: abb
|
|
2706
|
+
sage: type(p)
|
|
2707
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_str'>
|
|
2708
|
+
sage: p == loads(dumps(p))
|
|
2709
|
+
True
|
|
2710
|
+
"""
|
|
2711
|
+
pass
|
|
2712
|
+
|
|
2713
|
+
|
|
2714
|
+
class FiniteWordPath_hexagonal_grid_tuple(WordDatatype_tuple, FiniteWordPath_hexagonal_grid, FiniteWord_class):
|
|
2715
|
+
r"""
|
|
2716
|
+
TESTS::
|
|
2717
|
+
|
|
2718
|
+
sage: # needs sage.rings.number_field
|
|
2719
|
+
sage: P = WordPaths('abcdef', steps='hexagon')
|
|
2720
|
+
sage: p = P(('a','b','b')); p
|
|
2721
|
+
Path: abb
|
|
2722
|
+
sage: type(p)
|
|
2723
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_hexagonal_grid_tuple'>
|
|
2724
|
+
sage: p == loads(dumps(p))
|
|
2725
|
+
True
|
|
2726
|
+
"""
|
|
2727
|
+
pass
|
|
2728
|
+
|
|
2729
|
+
|
|
2730
|
+
class FiniteWordPath_hexagonal_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_hexagonal_grid, FiniteWord_class):
|
|
2731
|
+
pass
|
|
2732
|
+
|
|
2733
|
+
|
|
2734
|
+
class FiniteWordPath_hexagonal_grid_iter(WordDatatype_iter, FiniteWordPath_hexagonal_grid, FiniteWord_class):
|
|
2735
|
+
pass
|
|
2736
|
+
|
|
2737
|
+
|
|
2738
|
+
class FiniteWordPath_hexagonal_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_hexagonal_grid, FiniteWord_class):
|
|
2739
|
+
pass
|
|
2740
|
+
|
|
2741
|
+
|
|
2742
|
+
class FiniteWordPath_hexagonal_grid_callable(WordDatatype_callable, FiniteWordPath_hexagonal_grid, FiniteWord_class):
|
|
2743
|
+
pass
|
|
2744
|
+
|
|
2745
|
+
|
|
2746
|
+
# #### Finite paths on cube grid ####
|
|
2747
|
+
|
|
2748
|
+
class FiniteWordPath_cube_grid_list(WordDatatype_list, FiniteWordPath_cube_grid, FiniteWord_class):
|
|
2749
|
+
r"""
|
|
2750
|
+
TESTS::
|
|
2751
|
+
|
|
2752
|
+
sage: P = WordPaths('abcdef', steps='cube')
|
|
2753
|
+
sage: p = P(['a','b','b']); p
|
|
2754
|
+
Path: abb
|
|
2755
|
+
sage: type(p)
|
|
2756
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_list'>
|
|
2757
|
+
sage: p == loads(dumps(p))
|
|
2758
|
+
True
|
|
2759
|
+
"""
|
|
2760
|
+
pass
|
|
2761
|
+
|
|
2762
|
+
|
|
2763
|
+
class FiniteWordPath_cube_grid_str(WordDatatype_str, FiniteWordPath_cube_grid, FiniteWord_class):
|
|
2764
|
+
r"""
|
|
2765
|
+
TESTS::
|
|
2766
|
+
|
|
2767
|
+
sage: P = WordPaths('abcdef', steps='cube')
|
|
2768
|
+
sage: p = P('abb'); p
|
|
2769
|
+
Path: abb
|
|
2770
|
+
sage: type(p)
|
|
2771
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_str'>
|
|
2772
|
+
sage: p == loads(dumps(p))
|
|
2773
|
+
True
|
|
2774
|
+
"""
|
|
2775
|
+
pass
|
|
2776
|
+
|
|
2777
|
+
|
|
2778
|
+
class FiniteWordPath_cube_grid_tuple(WordDatatype_tuple, FiniteWordPath_cube_grid, FiniteWord_class):
|
|
2779
|
+
r"""
|
|
2780
|
+
TESTS::
|
|
2781
|
+
|
|
2782
|
+
sage: P = WordPaths('abcdef', steps='cube')
|
|
2783
|
+
sage: p = P(('a','b','b')); p
|
|
2784
|
+
Path: abb
|
|
2785
|
+
sage: type(p)
|
|
2786
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_cube_grid_tuple'>
|
|
2787
|
+
sage: p == loads(dumps(p))
|
|
2788
|
+
True
|
|
2789
|
+
"""
|
|
2790
|
+
pass
|
|
2791
|
+
|
|
2792
|
+
|
|
2793
|
+
class FiniteWordPath_cube_grid_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_cube_grid, FiniteWord_class):
|
|
2794
|
+
pass
|
|
2795
|
+
|
|
2796
|
+
|
|
2797
|
+
class FiniteWordPath_cube_grid_iter(WordDatatype_iter, FiniteWordPath_cube_grid, FiniteWord_class):
|
|
2798
|
+
pass
|
|
2799
|
+
|
|
2800
|
+
|
|
2801
|
+
class FiniteWordPath_cube_grid_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_cube_grid, FiniteWord_class):
|
|
2802
|
+
pass
|
|
2803
|
+
|
|
2804
|
+
|
|
2805
|
+
class FiniteWordPath_cube_grid_callable(WordDatatype_callable, FiniteWordPath_cube_grid, FiniteWord_class):
|
|
2806
|
+
pass
|
|
2807
|
+
|
|
2808
|
+
|
|
2809
|
+
# #### Finite paths on north_east ####
|
|
2810
|
+
|
|
2811
|
+
class FiniteWordPath_north_east_list(WordDatatype_list, FiniteWordPath_north_east, FiniteWord_class):
|
|
2812
|
+
r"""
|
|
2813
|
+
TESTS::
|
|
2814
|
+
|
|
2815
|
+
sage: P = WordPaths('ab', steps='ne')
|
|
2816
|
+
sage: p = P(['a','b','b']); p
|
|
2817
|
+
Path: abb
|
|
2818
|
+
sage: type(p)
|
|
2819
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_north_east_list'>
|
|
2820
|
+
sage: p == loads(dumps(p))
|
|
2821
|
+
True
|
|
2822
|
+
"""
|
|
2823
|
+
pass
|
|
2824
|
+
|
|
2825
|
+
|
|
2826
|
+
class FiniteWordPath_north_east_str(WordDatatype_str, FiniteWordPath_north_east, FiniteWord_class):
|
|
2827
|
+
r"""
|
|
2828
|
+
TESTS::
|
|
2829
|
+
|
|
2830
|
+
sage: P = WordPaths('ab', steps='ne')
|
|
2831
|
+
sage: p = P('abb'); p
|
|
2832
|
+
Path: abb
|
|
2833
|
+
sage: type(p)
|
|
2834
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_north_east_str'>
|
|
2835
|
+
sage: p == loads(dumps(p))
|
|
2836
|
+
True
|
|
2837
|
+
"""
|
|
2838
|
+
pass
|
|
2839
|
+
|
|
2840
|
+
|
|
2841
|
+
class FiniteWordPath_north_east_tuple(WordDatatype_tuple, FiniteWordPath_north_east, FiniteWord_class):
|
|
2842
|
+
r"""
|
|
2843
|
+
TESTS::
|
|
2844
|
+
|
|
2845
|
+
sage: P = WordPaths('ab', steps='ne')
|
|
2846
|
+
sage: p = P(('a','b','b')); p
|
|
2847
|
+
Path: abb
|
|
2848
|
+
sage: type(p)
|
|
2849
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_north_east_tuple'>
|
|
2850
|
+
sage: p == loads(dumps(p))
|
|
2851
|
+
True
|
|
2852
|
+
"""
|
|
2853
|
+
pass
|
|
2854
|
+
|
|
2855
|
+
|
|
2856
|
+
class FiniteWordPath_north_east_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_north_east, FiniteWord_class):
|
|
2857
|
+
pass
|
|
2858
|
+
|
|
2859
|
+
|
|
2860
|
+
class FiniteWordPath_north_east_iter(WordDatatype_iter, FiniteWordPath_north_east, FiniteWord_class):
|
|
2861
|
+
pass
|
|
2862
|
+
|
|
2863
|
+
|
|
2864
|
+
class FiniteWordPath_north_east_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_north_east, FiniteWord_class):
|
|
2865
|
+
pass
|
|
2866
|
+
|
|
2867
|
+
|
|
2868
|
+
class FiniteWordPath_north_east_callable(WordDatatype_callable, FiniteWordPath_north_east, FiniteWord_class):
|
|
2869
|
+
pass
|
|
2870
|
+
|
|
2871
|
+
|
|
2872
|
+
# #### Finite paths on dyck ####
|
|
2873
|
+
|
|
2874
|
+
class FiniteWordPath_dyck_list(WordDatatype_list, FiniteWordPath_dyck, FiniteWord_class):
|
|
2875
|
+
r"""
|
|
2876
|
+
TESTS::
|
|
2877
|
+
|
|
2878
|
+
sage: P = WordPaths('ab', steps='dyck')
|
|
2879
|
+
sage: p = P(['a','b','b']); p
|
|
2880
|
+
Path: abb
|
|
2881
|
+
sage: type(p)
|
|
2882
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_dyck_list'>
|
|
2883
|
+
sage: p == loads(dumps(p))
|
|
2884
|
+
True
|
|
2885
|
+
"""
|
|
2886
|
+
pass
|
|
2887
|
+
|
|
2888
|
+
|
|
2889
|
+
class FiniteWordPath_dyck_str(WordDatatype_str, FiniteWordPath_dyck, FiniteWord_class):
|
|
2890
|
+
r"""
|
|
2891
|
+
TESTS::
|
|
2892
|
+
|
|
2893
|
+
sage: P = WordPaths('ab', steps='dyck')
|
|
2894
|
+
sage: p = P('abb'); p
|
|
2895
|
+
Path: abb
|
|
2896
|
+
sage: type(p)
|
|
2897
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_dyck_str'>
|
|
2898
|
+
sage: p == loads(dumps(p))
|
|
2899
|
+
True
|
|
2900
|
+
"""
|
|
2901
|
+
pass
|
|
2902
|
+
|
|
2903
|
+
|
|
2904
|
+
class FiniteWordPath_dyck_tuple(WordDatatype_tuple, FiniteWordPath_dyck, FiniteWord_class):
|
|
2905
|
+
r"""
|
|
2906
|
+
TESTS::
|
|
2907
|
+
|
|
2908
|
+
sage: P = WordPaths('ab', steps='dyck')
|
|
2909
|
+
sage: p = P(('a','b','b')); p
|
|
2910
|
+
Path: abb
|
|
2911
|
+
sage: type(p)
|
|
2912
|
+
<class 'sage.combinat.words.paths.FiniteWordPath_dyck_tuple'>
|
|
2913
|
+
sage: p == loads(dumps(p))
|
|
2914
|
+
True
|
|
2915
|
+
"""
|
|
2916
|
+
pass
|
|
2917
|
+
|
|
2918
|
+
|
|
2919
|
+
class FiniteWordPath_dyck_iter_with_caching(WordDatatype_iter_with_caching, FiniteWordPath_dyck, FiniteWord_class):
|
|
2920
|
+
pass
|
|
2921
|
+
|
|
2922
|
+
|
|
2923
|
+
class FiniteWordPath_dyck_iter(WordDatatype_iter, FiniteWordPath_dyck, FiniteWord_class):
|
|
2924
|
+
pass
|
|
2925
|
+
|
|
2926
|
+
|
|
2927
|
+
class FiniteWordPath_dyck_callable_with_caching(WordDatatype_callable_with_caching, FiniteWordPath_dyck, FiniteWord_class):
|
|
2928
|
+
pass
|
|
2929
|
+
|
|
2930
|
+
|
|
2931
|
+
class FiniteWordPath_dyck_callable(WordDatatype_callable, FiniteWordPath_dyck, FiniteWord_class):
|
|
2932
|
+
pass
|