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,820 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
"""
|
|
3
|
+
Combinatorial species
|
|
4
|
+
|
|
5
|
+
This file defines the main classes for working with combinatorial
|
|
6
|
+
species, operations on them, as well as some implementations of
|
|
7
|
+
basic species required for other constructions.
|
|
8
|
+
|
|
9
|
+
This code is based on the work of Ralf Hemmecke and Martin Rubey's
|
|
10
|
+
Aldor-Combinat, which can be found at
|
|
11
|
+
http://www.risc.uni-linz.ac.at/people/hemmecke/aldor/combinat/index.html.
|
|
12
|
+
In particular, the relevant section for this file can be found at
|
|
13
|
+
http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatse8.html.
|
|
14
|
+
|
|
15
|
+
Weighted Species:
|
|
16
|
+
|
|
17
|
+
As a first application of weighted species, we count unlabeled
|
|
18
|
+
ordered trees by total number of nodes and number of internal
|
|
19
|
+
nodes. To achieve this, we assign a weight of `1` to the
|
|
20
|
+
leaves and of `q` to internal nodes::
|
|
21
|
+
|
|
22
|
+
sage: q = QQ['q'].gen()
|
|
23
|
+
sage: leaf = species.SingletonSpecies()
|
|
24
|
+
sage: internal_node = species.SingletonSpecies(weight=q)
|
|
25
|
+
sage: L = species.LinearOrderSpecies(min=1)
|
|
26
|
+
sage: T = species.CombinatorialSpecies(min=1)
|
|
27
|
+
sage: T.define(leaf + internal_node*L(T))
|
|
28
|
+
sage: T.isotype_generating_series()[0:6] # needs sage.modules
|
|
29
|
+
[0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q]
|
|
30
|
+
|
|
31
|
+
Consider the following::
|
|
32
|
+
|
|
33
|
+
sage: T.isotype_generating_series().coefficient(4) # needs sage.modules
|
|
34
|
+
q^3 + 3*q^2 + q
|
|
35
|
+
|
|
36
|
+
This means that, among the trees on `4` nodes, one has a
|
|
37
|
+
single internal node, three have two internal nodes, and one has
|
|
38
|
+
three internal nodes.
|
|
39
|
+
"""
|
|
40
|
+
# ****************************************************************************
|
|
41
|
+
# Copyright (C) 2008 Mike Hansen <mhansen@gmail.com>,
|
|
42
|
+
#
|
|
43
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
44
|
+
#
|
|
45
|
+
# This code is distributed in the hope that it will be useful,
|
|
46
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
47
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
48
|
+
# General Public License for more details.
|
|
49
|
+
#
|
|
50
|
+
# The full text of the GPL is available at:
|
|
51
|
+
#
|
|
52
|
+
# https://www.gnu.org/licenses/
|
|
53
|
+
# ****************************************************************************
|
|
54
|
+
from .generating_series import OrdinaryGeneratingSeriesRing, ExponentialGeneratingSeriesRing, CycleIndexSeriesRing
|
|
55
|
+
from sage.rings.rational_field import QQ
|
|
56
|
+
from sage.structure.sage_object import SageObject
|
|
57
|
+
from sage.misc.cachefunc import cached_method
|
|
58
|
+
from sage.combinat.species.misc import accept_size
|
|
59
|
+
from sage.combinat.species.structure import StructuresWrapper, IsotypesWrapper
|
|
60
|
+
from functools import reduce
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class GenericCombinatorialSpecies(SageObject):
|
|
64
|
+
def __init__(self, min=None, max=None, weight=None):
|
|
65
|
+
"""
|
|
66
|
+
TESTS::
|
|
67
|
+
|
|
68
|
+
sage: P = species.PermutationSpecies(size=3)
|
|
69
|
+
sage: P._weight
|
|
70
|
+
1
|
|
71
|
+
sage: P._min
|
|
72
|
+
3
|
|
73
|
+
sage: P._max
|
|
74
|
+
4
|
|
75
|
+
"""
|
|
76
|
+
self._weight = weight if weight is not None else QQ(1)
|
|
77
|
+
self._min = min
|
|
78
|
+
self._max = max
|
|
79
|
+
|
|
80
|
+
def __hash__(self):
|
|
81
|
+
"""
|
|
82
|
+
Return a hash of the unique info tuple.
|
|
83
|
+
|
|
84
|
+
EXAMPLES::
|
|
85
|
+
|
|
86
|
+
sage: hash(species.SetSpecies()) #random
|
|
87
|
+
-152204909943771174
|
|
88
|
+
"""
|
|
89
|
+
return hash(self._unique_info())
|
|
90
|
+
|
|
91
|
+
def _unique_info(self):
|
|
92
|
+
"""
|
|
93
|
+
Return a tuple which should uniquely identify the species.
|
|
94
|
+
|
|
95
|
+
EXAMPLES::
|
|
96
|
+
|
|
97
|
+
sage: species.SetSpecies()._unique_info()
|
|
98
|
+
(<class 'sage.combinat.species.set_species.SetSpecies'>, None, None, 1)
|
|
99
|
+
sage: species.SingletonSpecies()._unique_info()
|
|
100
|
+
(<class 'sage.combinat.species.characteristic_species.SingletonSpecies'>,
|
|
101
|
+
None,
|
|
102
|
+
None,
|
|
103
|
+
1)
|
|
104
|
+
|
|
105
|
+
::
|
|
106
|
+
|
|
107
|
+
sage: X = species.SingletonSpecies()
|
|
108
|
+
sage: Y = X + X
|
|
109
|
+
sage: Y._unique_info()
|
|
110
|
+
(<class 'sage.combinat.species.sum_species.SumSpecies'>,
|
|
111
|
+
None,
|
|
112
|
+
None,
|
|
113
|
+
1,
|
|
114
|
+
Singleton species,
|
|
115
|
+
Singleton species)
|
|
116
|
+
"""
|
|
117
|
+
info = (self.__class__, self._min, self._max, self._weight)
|
|
118
|
+
if hasattr(self, "_state_info") and self._state_info:
|
|
119
|
+
info += tuple(self._state_info)
|
|
120
|
+
return info
|
|
121
|
+
|
|
122
|
+
def __eq__(self, x):
|
|
123
|
+
"""
|
|
124
|
+
Test equality between two species.
|
|
125
|
+
|
|
126
|
+
EXAMPLES::
|
|
127
|
+
|
|
128
|
+
sage: X = species.SingletonSpecies()
|
|
129
|
+
sage: X + X == X + X
|
|
130
|
+
True
|
|
131
|
+
sage: X == X
|
|
132
|
+
True
|
|
133
|
+
sage: X == species.EmptySetSpecies()
|
|
134
|
+
False
|
|
135
|
+
sage: X == X*X
|
|
136
|
+
False
|
|
137
|
+
|
|
138
|
+
::
|
|
139
|
+
|
|
140
|
+
sage: X = species.SingletonSpecies()
|
|
141
|
+
sage: E = species.EmptySetSpecies()
|
|
142
|
+
sage: L = CombinatorialSpecies()
|
|
143
|
+
sage: L.define(E+X*L)
|
|
144
|
+
sage: K = CombinatorialSpecies()
|
|
145
|
+
sage: K.define(E+X*L)
|
|
146
|
+
sage: L == K
|
|
147
|
+
True
|
|
148
|
+
"""
|
|
149
|
+
if not isinstance(x, GenericCombinatorialSpecies):
|
|
150
|
+
return False
|
|
151
|
+
return self._unique_info() == x._unique_info()
|
|
152
|
+
|
|
153
|
+
def __ne__(self, other):
|
|
154
|
+
"""
|
|
155
|
+
Check whether ``self`` and ``other`` are not equal.
|
|
156
|
+
|
|
157
|
+
EXAMPLES::
|
|
158
|
+
|
|
159
|
+
sage: X = species.SingletonSpecies()
|
|
160
|
+
sage: X + X == X + X
|
|
161
|
+
True
|
|
162
|
+
sage: X != X
|
|
163
|
+
False
|
|
164
|
+
sage: X != species.EmptySetSpecies()
|
|
165
|
+
True
|
|
166
|
+
sage: X != X*X
|
|
167
|
+
True
|
|
168
|
+
|
|
169
|
+
sage: X = species.SingletonSpecies()
|
|
170
|
+
sage: E = species.EmptySetSpecies()
|
|
171
|
+
sage: L = CombinatorialSpecies()
|
|
172
|
+
sage: L.define(E+X*L)
|
|
173
|
+
sage: K = CombinatorialSpecies()
|
|
174
|
+
sage: K.define(E+X*L)
|
|
175
|
+
sage: L != K
|
|
176
|
+
False
|
|
177
|
+
"""
|
|
178
|
+
return not (self == other)
|
|
179
|
+
|
|
180
|
+
def __getstate__(self):
|
|
181
|
+
r"""
|
|
182
|
+
This is used during the pickling process and returns a dictionary
|
|
183
|
+
of the data needed to create this object during the unpickling
|
|
184
|
+
process. It returns an (\*args, \*\*kwds) tuple which is to be
|
|
185
|
+
passed into the constructor for the class of this species. Any
|
|
186
|
+
subclass should define a ``_state_info`` list for any arguments which
|
|
187
|
+
need to be passed in the constructor.
|
|
188
|
+
|
|
189
|
+
EXAMPLES::
|
|
190
|
+
|
|
191
|
+
sage: C = species.CharacteristicSpecies(5)
|
|
192
|
+
sage: args, kwds = C.__getstate__()
|
|
193
|
+
sage: args
|
|
194
|
+
{0: 5}
|
|
195
|
+
sage: sorted(kwds.items())
|
|
196
|
+
[('max', None), ('min', None), ('weight', 1)]
|
|
197
|
+
"""
|
|
198
|
+
kwds = {'weight': self._weight, 'min': self._min, 'max': self._max}
|
|
199
|
+
try:
|
|
200
|
+
return (dict(enumerate(self._state_info)), kwds)
|
|
201
|
+
except AttributeError:
|
|
202
|
+
return ({}, kwds)
|
|
203
|
+
|
|
204
|
+
def __setstate__(self, state):
|
|
205
|
+
"""
|
|
206
|
+
This is used during unpickling to recreate this object from the
|
|
207
|
+
data provided by the ``__getstate__`` method.
|
|
208
|
+
|
|
209
|
+
TESTS::
|
|
210
|
+
|
|
211
|
+
sage: C2 = species.CharacteristicSpecies(2)
|
|
212
|
+
sage: C4 = species.CharacteristicSpecies(4)
|
|
213
|
+
sage: C2
|
|
214
|
+
Characteristic species of order 2
|
|
215
|
+
sage: C2.__setstate__(C4.__getstate__()); C2
|
|
216
|
+
Characteristic species of order 4
|
|
217
|
+
"""
|
|
218
|
+
args_dict, kwds = state
|
|
219
|
+
self.__class__.__init__(self, *[args_dict[i] for i in range(len(args_dict))], **kwds)
|
|
220
|
+
|
|
221
|
+
def weighted(self, weight):
|
|
222
|
+
"""
|
|
223
|
+
Return a version of this species with the specified weight.
|
|
224
|
+
|
|
225
|
+
EXAMPLES::
|
|
226
|
+
|
|
227
|
+
sage: t = ZZ['t'].gen()
|
|
228
|
+
sage: C = species.CycleSpecies(); C
|
|
229
|
+
Cyclic permutation species
|
|
230
|
+
sage: C.weighted(t)
|
|
231
|
+
Cyclic permutation species with weight=t
|
|
232
|
+
"""
|
|
233
|
+
args_dict, kwds = self.__getstate__()
|
|
234
|
+
kwds.update({'weight': weight})
|
|
235
|
+
return self.__class__(*[args_dict[i] for i in range(len(args_dict))], **kwds)
|
|
236
|
+
|
|
237
|
+
def __repr__(self):
|
|
238
|
+
"""
|
|
239
|
+
Return a string representation of this species.
|
|
240
|
+
|
|
241
|
+
EXAMPLES::
|
|
242
|
+
|
|
243
|
+
sage: CombinatorialSpecies()
|
|
244
|
+
Combinatorial species
|
|
245
|
+
|
|
246
|
+
::
|
|
247
|
+
|
|
248
|
+
sage: species.SetSpecies()
|
|
249
|
+
Set species
|
|
250
|
+
sage: species.SetSpecies(min=1)
|
|
251
|
+
Set species with min=1
|
|
252
|
+
sage: species.SetSpecies(min=1, max=4)
|
|
253
|
+
Set species with min=1, max=4
|
|
254
|
+
sage: t = ZZ['t'].gen()
|
|
255
|
+
sage: species.SetSpecies(min=1, max=4, weight=t)
|
|
256
|
+
Set species with min=1, max=4, weight=t
|
|
257
|
+
"""
|
|
258
|
+
if hasattr(self, "_name"):
|
|
259
|
+
name = self._name if isinstance(self._name, str) else self._name()
|
|
260
|
+
else:
|
|
261
|
+
name = "Combinatorial species"
|
|
262
|
+
|
|
263
|
+
options = []
|
|
264
|
+
|
|
265
|
+
if self._min is not None:
|
|
266
|
+
options.append('min=%s' % self._min)
|
|
267
|
+
if self._max is not None:
|
|
268
|
+
options.append('max=%s' % self._max)
|
|
269
|
+
if self._weight != 1:
|
|
270
|
+
options.append('weight=%s' % self._weight)
|
|
271
|
+
|
|
272
|
+
if options:
|
|
273
|
+
name += " with " + ", ".join(options)
|
|
274
|
+
|
|
275
|
+
return name
|
|
276
|
+
|
|
277
|
+
def __add__(self, g):
|
|
278
|
+
"""
|
|
279
|
+
Return the sum of ``self`` and ``g``.
|
|
280
|
+
|
|
281
|
+
EXAMPLES::
|
|
282
|
+
|
|
283
|
+
sage: P = species.PermutationSpecies()
|
|
284
|
+
sage: F = P + P; F
|
|
285
|
+
Sum of (Permutation species) and (Permutation species)
|
|
286
|
+
sage: F.structures([1,2]).list()
|
|
287
|
+
[[1, 2], [2, 1], [1, 2], [2, 1]]
|
|
288
|
+
"""
|
|
289
|
+
from .sum_species import SumSpecies
|
|
290
|
+
if not isinstance(g, GenericCombinatorialSpecies):
|
|
291
|
+
raise TypeError("g must be a combinatorial species")
|
|
292
|
+
return SumSpecies(self, g)
|
|
293
|
+
|
|
294
|
+
sum = __add__
|
|
295
|
+
|
|
296
|
+
def __mul__(self, g):
|
|
297
|
+
"""
|
|
298
|
+
Return the product of ``self`` and ``g``.
|
|
299
|
+
|
|
300
|
+
EXAMPLES::
|
|
301
|
+
|
|
302
|
+
sage: P = species.PermutationSpecies()
|
|
303
|
+
sage: F = P * P; F
|
|
304
|
+
Product of (Permutation species) and (Permutation species)
|
|
305
|
+
"""
|
|
306
|
+
from .product_species import ProductSpecies
|
|
307
|
+
if not isinstance(g, GenericCombinatorialSpecies):
|
|
308
|
+
raise TypeError("g must be a combinatorial species")
|
|
309
|
+
return ProductSpecies(self, g)
|
|
310
|
+
|
|
311
|
+
product = __mul__
|
|
312
|
+
|
|
313
|
+
def __call__(self, g):
|
|
314
|
+
"""
|
|
315
|
+
EXAMPLES::
|
|
316
|
+
|
|
317
|
+
sage: S = species.SetSpecies()
|
|
318
|
+
sage: S(S)
|
|
319
|
+
Composition of (Set species) and (Set species)
|
|
320
|
+
"""
|
|
321
|
+
from .composition_species import CompositionSpecies
|
|
322
|
+
if not isinstance(g, GenericCombinatorialSpecies):
|
|
323
|
+
raise TypeError("g must be a combinatorial species")
|
|
324
|
+
return CompositionSpecies(self, g)
|
|
325
|
+
|
|
326
|
+
composition = __call__
|
|
327
|
+
|
|
328
|
+
def functorial_composition(self, g):
|
|
329
|
+
"""
|
|
330
|
+
Return the functorial composition of ``self`` with ``g``.
|
|
331
|
+
|
|
332
|
+
EXAMPLES::
|
|
333
|
+
|
|
334
|
+
sage: E = species.SetSpecies()
|
|
335
|
+
sage: E2 = E.restricted(min=2, max=3)
|
|
336
|
+
sage: WP = species.SubsetSpecies()
|
|
337
|
+
sage: P2 = E2*E
|
|
338
|
+
sage: G = WP.functorial_composition(P2)
|
|
339
|
+
sage: G.isotype_generating_series()[0:5] # needs sage.libs.pari sage.modules
|
|
340
|
+
[1, 1, 2, 4, 11]
|
|
341
|
+
"""
|
|
342
|
+
from .functorial_composition_species import FunctorialCompositionSpecies
|
|
343
|
+
if not isinstance(g, GenericCombinatorialSpecies):
|
|
344
|
+
raise TypeError("g must be a combinatorial species")
|
|
345
|
+
return FunctorialCompositionSpecies(self, g)
|
|
346
|
+
|
|
347
|
+
@accept_size
|
|
348
|
+
def restricted(self, min=None, max=None):
|
|
349
|
+
"""
|
|
350
|
+
Return the restriction of the species.
|
|
351
|
+
|
|
352
|
+
INPUT:
|
|
353
|
+
|
|
354
|
+
- ``min`` -- (optional) integer
|
|
355
|
+
|
|
356
|
+
- ``max`` -- (optional) integer
|
|
357
|
+
|
|
358
|
+
EXAMPLES::
|
|
359
|
+
|
|
360
|
+
sage: S = species.SetSpecies().restricted(min=3); S
|
|
361
|
+
Set species with min=3
|
|
362
|
+
sage: S.structures([1,2]).list()
|
|
363
|
+
[]
|
|
364
|
+
sage: S.generating_series()[0:5]
|
|
365
|
+
[0, 0, 0, 1/6, 1/24]
|
|
366
|
+
"""
|
|
367
|
+
kwargs = {'min': self._min if min is None else min,
|
|
368
|
+
'max': self._max if max is None else max,
|
|
369
|
+
'weight': self._weight}
|
|
370
|
+
return self.__class__(**kwargs)
|
|
371
|
+
|
|
372
|
+
def structures(self, labels, structure_class=None):
|
|
373
|
+
"""
|
|
374
|
+
EXAMPLES::
|
|
375
|
+
|
|
376
|
+
sage: F = CombinatorialSpecies()
|
|
377
|
+
sage: F.structures([1,2,3]).list()
|
|
378
|
+
Traceback (most recent call last):
|
|
379
|
+
...
|
|
380
|
+
ValueError: Stream is not yet defined
|
|
381
|
+
"""
|
|
382
|
+
return StructuresWrapper(self, labels, structure_class)
|
|
383
|
+
|
|
384
|
+
def isotypes(self, labels, structure_class=None):
|
|
385
|
+
"""
|
|
386
|
+
EXAMPLES::
|
|
387
|
+
|
|
388
|
+
sage: F = CombinatorialSpecies()
|
|
389
|
+
sage: F.isotypes([1,2,3]).list()
|
|
390
|
+
Traceback (most recent call last):
|
|
391
|
+
...
|
|
392
|
+
ValueError: Stream is not yet defined
|
|
393
|
+
"""
|
|
394
|
+
return IsotypesWrapper(self, labels, structure_class=structure_class)
|
|
395
|
+
|
|
396
|
+
def _check(self, n=5):
|
|
397
|
+
"""
|
|
398
|
+
Return ``True`` if the number of structures and isomorphism types
|
|
399
|
+
generated is the same as the number found from the generating
|
|
400
|
+
series.
|
|
401
|
+
|
|
402
|
+
EXAMPLES::
|
|
403
|
+
|
|
404
|
+
sage: P = species.PartitionSpecies()
|
|
405
|
+
sage: P._check() # needs sage.libs.flint
|
|
406
|
+
True
|
|
407
|
+
"""
|
|
408
|
+
st = self.structures(range(n))
|
|
409
|
+
it = self.isotypes(range(n))
|
|
410
|
+
|
|
411
|
+
try:
|
|
412
|
+
return (len(st.list()) == st.cardinality() and
|
|
413
|
+
len(it.list()) == it.cardinality())
|
|
414
|
+
except NotImplementedError:
|
|
415
|
+
return False
|
|
416
|
+
|
|
417
|
+
def __pow__(self, n):
|
|
418
|
+
r"""
|
|
419
|
+
Return this species to the power `n`.
|
|
420
|
+
|
|
421
|
+
This uses a binary exponentiation algorithm to perform the
|
|
422
|
+
powering.
|
|
423
|
+
|
|
424
|
+
EXAMPLES::
|
|
425
|
+
|
|
426
|
+
sage: One = species.EmptySetSpecies()
|
|
427
|
+
sage: X = species.SingletonSpecies()
|
|
428
|
+
sage: X^2
|
|
429
|
+
Product of (Singleton species) and (Singleton species)
|
|
430
|
+
sage: X^5
|
|
431
|
+
Product of (Singleton species) and (Product of (Product of
|
|
432
|
+
(Singleton species) and (Singleton species)) and (Product
|
|
433
|
+
of (Singleton species) and (Singleton species)))
|
|
434
|
+
|
|
435
|
+
sage: (X^2).generating_series()[0:4]
|
|
436
|
+
[0, 0, 1, 0]
|
|
437
|
+
sage: (X^3).generating_series()[0:4]
|
|
438
|
+
[0, 0, 0, 1]
|
|
439
|
+
sage: ((One+X)^3).generating_series()[0:4]
|
|
440
|
+
[1, 3, 3, 1]
|
|
441
|
+
sage: ((One+X)^7).generating_series()[0:8]
|
|
442
|
+
[1, 7, 21, 35, 35, 21, 7, 1]
|
|
443
|
+
|
|
444
|
+
sage: x = QQ[['x']].gen()
|
|
445
|
+
sage: coeffs = ((1+x+x+x**2)**25+O(x**10)).padded_list()
|
|
446
|
+
sage: T = ((One+X+X+X^2)^25)
|
|
447
|
+
sage: T.generating_series()[0:10] == coeffs
|
|
448
|
+
True
|
|
449
|
+
sage: X^1 is X
|
|
450
|
+
True
|
|
451
|
+
sage: A = X^32
|
|
452
|
+
sage: A.digraph() # needs sage.graphs
|
|
453
|
+
Multi-digraph on 6 vertices
|
|
454
|
+
|
|
455
|
+
TESTS::
|
|
456
|
+
|
|
457
|
+
sage: X**(-1)
|
|
458
|
+
Traceback (most recent call last):
|
|
459
|
+
...
|
|
460
|
+
ValueError: only positive exponents are currently supported
|
|
461
|
+
"""
|
|
462
|
+
from sage.rings.integer import Integer
|
|
463
|
+
import operator
|
|
464
|
+
n = Integer(n)
|
|
465
|
+
if n <= 0:
|
|
466
|
+
raise ValueError("only positive exponents are currently supported")
|
|
467
|
+
digits = n.digits(2)
|
|
468
|
+
squares = [self]
|
|
469
|
+
for i in range(len(digits) - 1):
|
|
470
|
+
squares.append(squares[-1] * squares[-1])
|
|
471
|
+
return reduce(operator.mul, (s for i, s in zip(digits, squares)
|
|
472
|
+
if i != 0))
|
|
473
|
+
|
|
474
|
+
def _get_series(self, series_ring_class, prefix, base_ring=None):
|
|
475
|
+
"""
|
|
476
|
+
Return the generating / isotype generating / cycle index series
|
|
477
|
+
ring. The purpose of this method is to restrict the result of
|
|
478
|
+
_series_helper to ``self._min`` and ``self._max``.
|
|
479
|
+
|
|
480
|
+
EXAMPLES::
|
|
481
|
+
|
|
482
|
+
sage: P = species.PermutationSpecies(min=2, max=4)
|
|
483
|
+
sage: P.generating_series()[0:8] #indirect doctest
|
|
484
|
+
[0, 0, 1, 1, 0, 0, 0, 0]
|
|
485
|
+
"""
|
|
486
|
+
series = self._series_helper(series_ring_class, prefix, base_ring=base_ring)
|
|
487
|
+
# We need to restrict the series based on the min
|
|
488
|
+
# and max of this species. Note that if min and max
|
|
489
|
+
# are both None (as in the default case), then the restrict
|
|
490
|
+
# method will just return series.
|
|
491
|
+
if self._min is None and self._max is None:
|
|
492
|
+
return series
|
|
493
|
+
return series.parent()(lambda n: series[n],
|
|
494
|
+
valuation=self._min, degree=self._max)
|
|
495
|
+
|
|
496
|
+
def _series_helper(self, series_ring_class, prefix, base_ring=None):
|
|
497
|
+
"""
|
|
498
|
+
This code handles much of the common work involved in getting the
|
|
499
|
+
generating series for this species (such as determining the
|
|
500
|
+
correct base ring to pass down to the subclass, determining which
|
|
501
|
+
method on the subclass to call to get the series object, etc.)
|
|
502
|
+
|
|
503
|
+
INPUT:
|
|
504
|
+
|
|
505
|
+
- ``series_ring_class`` -- a class for the series ring such as
|
|
506
|
+
``ExponentialGeneratingSeriesRing``, etc.
|
|
507
|
+
|
|
508
|
+
- ``prefix`` -- the string prefix associated with the generating series
|
|
509
|
+
such as "cis" for the cycle index series. This prefix appears in the
|
|
510
|
+
methods that are implemented in the subclass.
|
|
511
|
+
|
|
512
|
+
- ``base_ring`` -- the ring in which the coefficients of the generating
|
|
513
|
+
series live. If it is not specified, then it is determined by the
|
|
514
|
+
weight of the species.
|
|
515
|
+
|
|
516
|
+
EXAMPLES::
|
|
517
|
+
|
|
518
|
+
sage: from sage.combinat.species.generating_series import OrdinaryGeneratingSeriesRing
|
|
519
|
+
sage: S = species.SetSpecies()
|
|
520
|
+
sage: itgs = S._series_helper(OrdinaryGeneratingSeriesRing, "itgs")
|
|
521
|
+
sage: itgs[:3]
|
|
522
|
+
[1, 1, 1]
|
|
523
|
+
|
|
524
|
+
::
|
|
525
|
+
|
|
526
|
+
sage: itgs = S._series_helper(OrdinaryGeneratingSeriesRing, "itgs", base_ring=RDF)
|
|
527
|
+
sage: itgs[:3]
|
|
528
|
+
[1.0, 1.0, 1.0]
|
|
529
|
+
"""
|
|
530
|
+
prefix = "_" + prefix
|
|
531
|
+
|
|
532
|
+
# Get the base ring
|
|
533
|
+
if base_ring is None:
|
|
534
|
+
base_ring = self.weight_ring()
|
|
535
|
+
else:
|
|
536
|
+
# The specified base ring must have maps from both
|
|
537
|
+
# the rational numbers and the weight ring
|
|
538
|
+
if not base_ring.has_coerce_map_from(QQ):
|
|
539
|
+
raise ValueError("specified base ring does not contain the rationals")
|
|
540
|
+
if not base_ring.has_coerce_map_from(self.weight_ring()):
|
|
541
|
+
raise ValueError("specified base ring is incompatible with the weight ring of self")
|
|
542
|
+
|
|
543
|
+
series_ring = series_ring_class(base_ring)
|
|
544
|
+
|
|
545
|
+
# Try to return things like self._gs(base_ring)
|
|
546
|
+
# This is used when the subclass wants to just
|
|
547
|
+
# handle creating the generating series itself;
|
|
548
|
+
# for example, returning the exponential of a
|
|
549
|
+
# generating series.
|
|
550
|
+
try:
|
|
551
|
+
return getattr(self, prefix)(series_ring, base_ring)
|
|
552
|
+
except AttributeError:
|
|
553
|
+
pass
|
|
554
|
+
|
|
555
|
+
# Try to return things like self._gs_callable(base_ring).
|
|
556
|
+
# This is used when the subclass just provides a callable
|
|
557
|
+
# for the coefficients of the generating series. Optionally,
|
|
558
|
+
# the subclass can specify the order of the series.
|
|
559
|
+
try:
|
|
560
|
+
callable = getattr(self, prefix + "_callable")
|
|
561
|
+
try:
|
|
562
|
+
return series_ring(lambda n: callable(base_ring, n), valuation=self._order())
|
|
563
|
+
except AttributeError:
|
|
564
|
+
return series_ring(lambda n: callable(base_ring, n))
|
|
565
|
+
except AttributeError:
|
|
566
|
+
pass
|
|
567
|
+
|
|
568
|
+
# Try to use things like self._gs_term(base_ring).
|
|
569
|
+
# This is used when the generating series is just a single
|
|
570
|
+
# term.
|
|
571
|
+
try:
|
|
572
|
+
return series_ring(getattr(self, prefix + "_term")(base_ring),
|
|
573
|
+
self._order())
|
|
574
|
+
except AttributeError:
|
|
575
|
+
pass
|
|
576
|
+
|
|
577
|
+
# Try to use things like self._gs_list(base_ring).
|
|
578
|
+
# This is used when the coefficients of the generating series
|
|
579
|
+
# can be given by a finite list with the last coefficient repeating.
|
|
580
|
+
# The generating series with all ones coefficients is generated this
|
|
581
|
+
# way.
|
|
582
|
+
try:
|
|
583
|
+
return series_ring(lambda n: getattr(self, prefix + "_list")(base_ring, n))
|
|
584
|
+
except AttributeError:
|
|
585
|
+
pass
|
|
586
|
+
|
|
587
|
+
raise NotImplementedError
|
|
588
|
+
|
|
589
|
+
@cached_method
|
|
590
|
+
def generating_series(self, base_ring=None):
|
|
591
|
+
r"""
|
|
592
|
+
Return the generating series for this species.
|
|
593
|
+
|
|
594
|
+
This is an exponential generating series so the `n`-th
|
|
595
|
+
coefficient of the series corresponds to the number of labeled
|
|
596
|
+
structures with `n` labels divided by `n!`.
|
|
597
|
+
|
|
598
|
+
EXAMPLES::
|
|
599
|
+
|
|
600
|
+
sage: P = species.PermutationSpecies()
|
|
601
|
+
sage: g = P.generating_series()
|
|
602
|
+
sage: g[:4]
|
|
603
|
+
[1, 1, 1, 1]
|
|
604
|
+
sage: g.counts(4)
|
|
605
|
+
[1, 1, 2, 6]
|
|
606
|
+
sage: P.structures([1,2,3]).list()
|
|
607
|
+
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
|
|
608
|
+
sage: len(_)
|
|
609
|
+
6
|
|
610
|
+
"""
|
|
611
|
+
return self._get_series(ExponentialGeneratingSeriesRing, "gs", base_ring)
|
|
612
|
+
|
|
613
|
+
@cached_method
|
|
614
|
+
def isotype_generating_series(self, base_ring=None):
|
|
615
|
+
r"""
|
|
616
|
+
Return the isotype generating series for this species.
|
|
617
|
+
|
|
618
|
+
The `n`-th coefficient of this series corresponds to the number
|
|
619
|
+
of isomorphism types for the structures on `n` labels.
|
|
620
|
+
|
|
621
|
+
EXAMPLES::
|
|
622
|
+
|
|
623
|
+
sage: P = species.PermutationSpecies()
|
|
624
|
+
sage: g = P.isotype_generating_series()
|
|
625
|
+
sage: g[0:4] # needs sage.libs.flint
|
|
626
|
+
[1, 1, 2, 3]
|
|
627
|
+
sage: g.counts(4) # needs sage.libs.flint
|
|
628
|
+
[1, 1, 2, 3]
|
|
629
|
+
sage: P.isotypes([1,2,3]).list() # needs sage.libs.flint
|
|
630
|
+
[[2, 3, 1], [2, 1, 3], [1, 2, 3]]
|
|
631
|
+
sage: len(_) # needs sage.libs.flint
|
|
632
|
+
3
|
|
633
|
+
"""
|
|
634
|
+
return self._get_series(OrdinaryGeneratingSeriesRing, "itgs", base_ring)
|
|
635
|
+
|
|
636
|
+
@cached_method
|
|
637
|
+
def cycle_index_series(self, base_ring=None):
|
|
638
|
+
r"""
|
|
639
|
+
Return the cycle index series for this species.
|
|
640
|
+
|
|
641
|
+
The cycle index series is a sequence of symmetric functions.
|
|
642
|
+
|
|
643
|
+
EXAMPLES::
|
|
644
|
+
|
|
645
|
+
sage: P = species.PermutationSpecies()
|
|
646
|
+
sage: g = P.cycle_index_series() # needs sage.modules
|
|
647
|
+
sage: g[0:4] # needs sage.modules
|
|
648
|
+
[p[], p[1], p[1, 1] + p[2], p[1, 1, 1] + p[2, 1] + p[3]]
|
|
649
|
+
"""
|
|
650
|
+
return self._get_series(CycleIndexSeriesRing, "cis", base_ring)
|
|
651
|
+
|
|
652
|
+
def is_weighted(self):
|
|
653
|
+
"""
|
|
654
|
+
Return ``True`` if this species has a nontrivial weighting associated
|
|
655
|
+
with it.
|
|
656
|
+
|
|
657
|
+
EXAMPLES::
|
|
658
|
+
|
|
659
|
+
sage: C = species.CycleSpecies()
|
|
660
|
+
sage: C.is_weighted()
|
|
661
|
+
False
|
|
662
|
+
"""
|
|
663
|
+
return self._weight != 1
|
|
664
|
+
|
|
665
|
+
def weight_ring(self):
|
|
666
|
+
"""
|
|
667
|
+
Return the ring in which the weights of this species occur.
|
|
668
|
+
|
|
669
|
+
By default, this is just the field of rational numbers.
|
|
670
|
+
|
|
671
|
+
EXAMPLES::
|
|
672
|
+
|
|
673
|
+
sage: species.SetSpecies().weight_ring()
|
|
674
|
+
Rational Field
|
|
675
|
+
"""
|
|
676
|
+
if self.is_weighted():
|
|
677
|
+
return self._weight.parent()
|
|
678
|
+
else:
|
|
679
|
+
return QQ
|
|
680
|
+
|
|
681
|
+
def _common_parent(self, parents):
|
|
682
|
+
"""
|
|
683
|
+
Return a parent that contains all the parents
|
|
684
|
+
in the given list of parents.
|
|
685
|
+
|
|
686
|
+
EXAMPLES::
|
|
687
|
+
|
|
688
|
+
sage: C = species.CombinatorialSpecies()
|
|
689
|
+
sage: C._common_parent([QQ, ZZ['t']])
|
|
690
|
+
Univariate Polynomial Ring in t over Rational Field
|
|
691
|
+
"""
|
|
692
|
+
assert parents
|
|
693
|
+
from sage.structure.element import get_coercion_model
|
|
694
|
+
cm = get_coercion_model()
|
|
695
|
+
|
|
696
|
+
common = parents[0]
|
|
697
|
+
for p in parents[1:]:
|
|
698
|
+
common = cm.explain(common, p, verbosity=0)
|
|
699
|
+
if common is None:
|
|
700
|
+
raise ValueError("unable to find a common parent")
|
|
701
|
+
return common
|
|
702
|
+
|
|
703
|
+
def digraph(self):
|
|
704
|
+
"""
|
|
705
|
+
Return a directed graph where the vertices are the individual
|
|
706
|
+
species that make up this one.
|
|
707
|
+
|
|
708
|
+
EXAMPLES::
|
|
709
|
+
|
|
710
|
+
sage: X = species.SingletonSpecies()
|
|
711
|
+
sage: B = species.CombinatorialSpecies()
|
|
712
|
+
sage: B.define(X+B*B)
|
|
713
|
+
sage: g = B.digraph(); g # needs sage.graphs
|
|
714
|
+
Multi-digraph on 4 vertices
|
|
715
|
+
|
|
716
|
+
sage: sorted(g, key=str) # needs sage.graphs
|
|
717
|
+
[Combinatorial species,
|
|
718
|
+
Product of (Combinatorial species) and (Combinatorial species),
|
|
719
|
+
Singleton species,
|
|
720
|
+
Sum of (Singleton species) and
|
|
721
|
+
(Product of (Combinatorial species) and (Combinatorial species))]
|
|
722
|
+
|
|
723
|
+
sage: d = {sp: i for i, sp in enumerate(g)} # needs sage.graphs
|
|
724
|
+
sage: g.relabel(d) # needs sage.graphs
|
|
725
|
+
sage: g.canonical_label().edges(sort=True) # needs sage.graphs
|
|
726
|
+
[(0, 3, None), (2, 0, None), (2, 0, None), (3, 1, None), (3, 2, None)]
|
|
727
|
+
"""
|
|
728
|
+
from sage.graphs.digraph import DiGraph
|
|
729
|
+
d = DiGraph(multiedges=True)
|
|
730
|
+
self._add_to_digraph(d)
|
|
731
|
+
return d
|
|
732
|
+
|
|
733
|
+
def _add_to_digraph(self, d):
|
|
734
|
+
"""
|
|
735
|
+
Add this species as a vertex to the digraph ``d`` along with any
|
|
736
|
+
'children' of this species. For example, sum species would add
|
|
737
|
+
itself as a vertex and an edge between itself and each of its
|
|
738
|
+
summands.
|
|
739
|
+
|
|
740
|
+
EXAMPLES::
|
|
741
|
+
|
|
742
|
+
sage: # needs sage.graphs
|
|
743
|
+
sage: d = DiGraph(multiedges=True)
|
|
744
|
+
sage: X = species.SingletonSpecies()
|
|
745
|
+
sage: X._add_to_digraph(d); d
|
|
746
|
+
Multi-digraph on 1 vertex
|
|
747
|
+
sage: (X+X)._add_to_digraph(d); d
|
|
748
|
+
Multi-digraph on 2 vertices
|
|
749
|
+
sage: d.edges(sort=True)
|
|
750
|
+
[(Sum of (Singleton species) and (Singleton species), Singleton species, None),
|
|
751
|
+
(Sum of (Singleton species) and (Singleton species), Singleton species, None)]
|
|
752
|
+
"""
|
|
753
|
+
d.add_vertex(self)
|
|
754
|
+
|
|
755
|
+
if not hasattr(self, "_state_info"):
|
|
756
|
+
return
|
|
757
|
+
|
|
758
|
+
for child in self._state_info:
|
|
759
|
+
if not isinstance(child, GenericCombinatorialSpecies):
|
|
760
|
+
continue
|
|
761
|
+
d.add_edge(self, child)
|
|
762
|
+
child._add_to_digraph(d)
|
|
763
|
+
|
|
764
|
+
def algebraic_equation_system(self):
|
|
765
|
+
"""
|
|
766
|
+
Return a system of algebraic equations satisfied by this species.
|
|
767
|
+
|
|
768
|
+
The nodes are numbered in the order that they appear as vertices of
|
|
769
|
+
the associated digraph.
|
|
770
|
+
|
|
771
|
+
EXAMPLES::
|
|
772
|
+
|
|
773
|
+
sage: B = species.BinaryTreeSpecies()
|
|
774
|
+
sage: B.algebraic_equation_system() # needs sage.graphs
|
|
775
|
+
[-node3^2 + node1, -node1 + node3 + (-z)]
|
|
776
|
+
|
|
777
|
+
::
|
|
778
|
+
|
|
779
|
+
sage: sorted(B.digraph().vertex_iterator(), key=str) # needs sage.graphs
|
|
780
|
+
[Combinatorial species with min=1,
|
|
781
|
+
Product of (Combinatorial species with min=1)
|
|
782
|
+
and (Combinatorial species with min=1),
|
|
783
|
+
Singleton species,
|
|
784
|
+
Sum of (Singleton species)
|
|
785
|
+
and (Product of (Combinatorial species with min=1)
|
|
786
|
+
and (Combinatorial species with min=1))]
|
|
787
|
+
|
|
788
|
+
::
|
|
789
|
+
|
|
790
|
+
sage: B.algebraic_equation_system()[0].parent() # needs sage.graphs
|
|
791
|
+
Multivariate Polynomial Ring in node0, node1, node2, node3 over
|
|
792
|
+
Fraction Field of Univariate Polynomial Ring in z over Rational Field
|
|
793
|
+
"""
|
|
794
|
+
d = self.digraph()
|
|
795
|
+
|
|
796
|
+
Qz = QQ['z'].fraction_field()
|
|
797
|
+
|
|
798
|
+
# Generate the variable names and the corresponding polynomial rings
|
|
799
|
+
var_names = ["node%s" % i for i in range(d.num_verts())]
|
|
800
|
+
R = Qz[", ".join(var_names)]
|
|
801
|
+
R_gens_dict = R.gens_dict()
|
|
802
|
+
|
|
803
|
+
# A dictionary mapping the nodes to variables
|
|
804
|
+
vertices = sorted(d.vertex_iterator(), key=str)
|
|
805
|
+
var_mapping = {node: R_gens_dict[name]
|
|
806
|
+
for node, name in zip(vertices, var_names)}
|
|
807
|
+
var_mapping['z'] = Qz.gen()
|
|
808
|
+
|
|
809
|
+
eqns = []
|
|
810
|
+
subs = {}
|
|
811
|
+
for species in vertices:
|
|
812
|
+
try:
|
|
813
|
+
eqn = species._equation(var_mapping)
|
|
814
|
+
if eqn in Qz or eqn in R.gens():
|
|
815
|
+
subs[var_mapping[species]] = eqn
|
|
816
|
+
else:
|
|
817
|
+
eqns.append(var_mapping[species] - eqn)
|
|
818
|
+
except AttributeError:
|
|
819
|
+
raise NotImplementedError
|
|
820
|
+
return [eq.subs(subs) for eq in eqns]
|