passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +400 -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-0e7fc84e.so.10.5.0 +0 -0
- passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +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 +35 -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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +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.cpython-314-x86_64-linux-musl.so +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
|
@@ -0,0 +1,779 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.libs.pari sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Splitting Algebras
|
|
5
|
+
|
|
6
|
+
*Splitting algebras* have been considered by Dan Laksov, Anders Thorup,
|
|
7
|
+
Torsten Ekedahl and others (see references below) in order to study
|
|
8
|
+
intersection theory of Grassmann and other flag schemes. Similarly as
|
|
9
|
+
*splitting fields* they can be considered as extensions of rings containing
|
|
10
|
+
all the roots of a given monic polynomial over that ring under the
|
|
11
|
+
assumption that its Galois group is the symmetric group of order equal
|
|
12
|
+
to the polynomial's degree.
|
|
13
|
+
|
|
14
|
+
Thus they can be used as a tool to express elements of a ring generated by
|
|
15
|
+
`n` indeterminates in terms of symmetric functions in these indeterminates.
|
|
16
|
+
|
|
17
|
+
This realization of splitting algebras follows the approach of a recursive
|
|
18
|
+
quotient ring construction splitting off some linear factor of the
|
|
19
|
+
polynomial in each recursive step. Accordingly it is inherited from
|
|
20
|
+
:class:`PolynomialQuotientRing_domain`.
|
|
21
|
+
|
|
22
|
+
AUTHORS:
|
|
23
|
+
|
|
24
|
+
- Sebastian Oehms (April 2020): initial version
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
# ****************************************************************************
|
|
28
|
+
# Copyright (C) 2020 Sebastian Oehms <seb.oehms@gmail.com>
|
|
29
|
+
#
|
|
30
|
+
# This program is free software: you can redistribute it and/or modify
|
|
31
|
+
# it under the terms of the GNU General Public License as published by
|
|
32
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
33
|
+
# (at your option) any later version.
|
|
34
|
+
# https://www.gnu.org/licenses/
|
|
35
|
+
# ****************************************************************************
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
from warnings import warn
|
|
39
|
+
|
|
40
|
+
from sage.misc.verbose import verbose
|
|
41
|
+
from sage.misc.cachefunc import cached_method
|
|
42
|
+
from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_domain
|
|
43
|
+
from sage.rings.polynomial.polynomial_quotient_ring_element import PolynomialQuotientRingElement
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# ------------------------------------------------------------------------------------------------------------------
|
|
47
|
+
# Element class for the splitting algebra
|
|
48
|
+
# --------------------------------------------------------------------------------------------------------
|
|
49
|
+
class SplittingAlgebraElement(PolynomialQuotientRingElement):
|
|
50
|
+
r"""
|
|
51
|
+
Element class for :class:`SplittingAlgebra`.
|
|
52
|
+
|
|
53
|
+
EXAMPLES::
|
|
54
|
+
|
|
55
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
56
|
+
sage: cp6 = cyclotomic_polynomial(6)
|
|
57
|
+
sage: CR6.<e6> = SplittingAlgebra(cp6)
|
|
58
|
+
sage: type(e6)
|
|
59
|
+
<class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category.element_class'>
|
|
60
|
+
|
|
61
|
+
sage: type(CR6(5))
|
|
62
|
+
<class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category.element_class'>
|
|
63
|
+
"""
|
|
64
|
+
def __invert__(self):
|
|
65
|
+
r"""
|
|
66
|
+
Return the inverse of ``self``.
|
|
67
|
+
|
|
68
|
+
Support inversion of special elements attached to the construction
|
|
69
|
+
of the parent and which are recorded in the list
|
|
70
|
+
``self.parent()._invertible_elements``.
|
|
71
|
+
|
|
72
|
+
EXAMPLES::
|
|
73
|
+
|
|
74
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
75
|
+
sage: CR3.<e3> = SplittingAlgebra(cyclotomic_polynomial(3))
|
|
76
|
+
sage: ~e3
|
|
77
|
+
-e3 - 1
|
|
78
|
+
sage: ~(e3 + 5)
|
|
79
|
+
Traceback (most recent call last):
|
|
80
|
+
...
|
|
81
|
+
ArithmeticError: element is non-invertible
|
|
82
|
+
"""
|
|
83
|
+
inv_elements = self.parent()._invertible_elements
|
|
84
|
+
if self in inv_elements:
|
|
85
|
+
return inv_elements[self]
|
|
86
|
+
|
|
87
|
+
return super().__invert__()
|
|
88
|
+
|
|
89
|
+
def is_unit(self):
|
|
90
|
+
r"""
|
|
91
|
+
Return ``True`` if ``self`` is invertible.
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
96
|
+
sage: CR3.<e3> = SplittingAlgebra(cyclotomic_polynomial(3))
|
|
97
|
+
sage: e3.is_unit()
|
|
98
|
+
True
|
|
99
|
+
"""
|
|
100
|
+
inv_elements = self.parent()._invertible_elements
|
|
101
|
+
if self in inv_elements:
|
|
102
|
+
return True
|
|
103
|
+
|
|
104
|
+
return super().is_unit()
|
|
105
|
+
|
|
106
|
+
def monomial_coefficients(self, copy=True):
|
|
107
|
+
r"""
|
|
108
|
+
Return the dictionary of ``self`` according to its lift to the cover.
|
|
109
|
+
|
|
110
|
+
EXAMPLES::
|
|
111
|
+
|
|
112
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
113
|
+
sage: CR3.<e3> = SplittingAlgebra(cyclotomic_polynomial(3))
|
|
114
|
+
sage: f = e3 + 42
|
|
115
|
+
sage: f.monomial_coefficients()
|
|
116
|
+
{0: 42, 1: 1}
|
|
117
|
+
|
|
118
|
+
``dict`` is an alias::
|
|
119
|
+
|
|
120
|
+
sage: f.dict()
|
|
121
|
+
{0: 42, 1: 1}
|
|
122
|
+
"""
|
|
123
|
+
return self.lift().monomial_coefficients(copy=copy)
|
|
124
|
+
|
|
125
|
+
dict = monomial_coefficients
|
|
126
|
+
|
|
127
|
+
# ------------------------------------------------------------------------------------------------------------------
|
|
128
|
+
# Parent class of the splitting algebra
|
|
129
|
+
# --------------------------------------------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class SplittingAlgebra(PolynomialQuotientRing_domain):
|
|
133
|
+
r"""
|
|
134
|
+
For a given monic polynomial `p(t)` of degree `n` over a commutative
|
|
135
|
+
ring `R`, the splitting algebra is the universal `R`-algebra in which
|
|
136
|
+
`p(t)` has `n` roots, or, more precisely, over which `p(t)` factors,
|
|
137
|
+
|
|
138
|
+
.. MATH::
|
|
139
|
+
|
|
140
|
+
p(t) = (t - \xi_1) \cdots (t - \xi_n).
|
|
141
|
+
|
|
142
|
+
This class creates an algebra as extension over the base ring of a
|
|
143
|
+
given polynomial `p` such that `p` splits into linear factors over
|
|
144
|
+
that extension. It is assumed (and not checked in general) that the
|
|
145
|
+
Galois group of `p` is the symmetric Group `S(n)`. The construction
|
|
146
|
+
is recursive (following [LT2012]_, 1.3).
|
|
147
|
+
|
|
148
|
+
INPUT:
|
|
149
|
+
|
|
150
|
+
- ``monic_polynomial`` -- the monic polynomial which should be split
|
|
151
|
+
- ``names`` -- names for the indeterminates to be adjoined to the
|
|
152
|
+
base ring of ``monic_polynomial``
|
|
153
|
+
- ``warning`` -- boolean (default: ``True``); can be used (by setting to
|
|
154
|
+
``False``) to suppress a warning which will be thrown whenever it cannot
|
|
155
|
+
be checked that the Galois group of ``monic_polynomial`` is maximal
|
|
156
|
+
|
|
157
|
+
EXAMPLES::
|
|
158
|
+
|
|
159
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
160
|
+
sage: Lc.<w> = LaurentPolynomialRing(ZZ)
|
|
161
|
+
sage: PabLc.<u,v> = Lc[]; t = polygen(PabLc)
|
|
162
|
+
sage: S.<x, y> = SplittingAlgebra(t^3 - u*t^2 + v*t - w)
|
|
163
|
+
doctest:...: UserWarning: Assuming x^3 - u*x^2 + v*x - w to have maximal
|
|
164
|
+
Galois group!
|
|
165
|
+
|
|
166
|
+
sage: roots = S.splitting_roots(); roots
|
|
167
|
+
[x, y, -y - x + u]
|
|
168
|
+
sage: all(t^3 -u*t^2 +v*t -w == 0 for t in roots)
|
|
169
|
+
True
|
|
170
|
+
sage: xi = ~x; xi
|
|
171
|
+
(w^-1)*x^2 + ((-w^-1)*u)*x + (w^-1)*v
|
|
172
|
+
sage: ~xi == x
|
|
173
|
+
True
|
|
174
|
+
sage: ~y
|
|
175
|
+
((-w^-1)*x)*y + (-w^-1)*x^2 + ((w^-1)*u)*x
|
|
176
|
+
sage: zi = ((w^-1)*x)*y; ~zi
|
|
177
|
+
-y - x + u
|
|
178
|
+
|
|
179
|
+
sage: cp3 = cyclotomic_polynomial(3).change_ring(GF(5))
|
|
180
|
+
sage: CR3.<e3> = SplittingAlgebra(cp3)
|
|
181
|
+
sage: CR3.is_field()
|
|
182
|
+
True
|
|
183
|
+
sage: CR3.cardinality()
|
|
184
|
+
25
|
|
185
|
+
sage: F.<a> = cp3.splitting_field()
|
|
186
|
+
sage: F.cardinality()
|
|
187
|
+
25
|
|
188
|
+
sage: E3 = cp3.change_ring(F).roots()[0][0]; E3
|
|
189
|
+
3*a + 3
|
|
190
|
+
sage: f = CR3.hom([E3]); f
|
|
191
|
+
Ring morphism:
|
|
192
|
+
From: Splitting Algebra of x^2 + x + 1
|
|
193
|
+
with roots [e3, 4*e3 + 4]
|
|
194
|
+
over Finite Field of size 5
|
|
195
|
+
To: Finite Field in a of size 5^2
|
|
196
|
+
Defn: e3 |--> 3*a + 3
|
|
197
|
+
|
|
198
|
+
REFERENCES:
|
|
199
|
+
|
|
200
|
+
- [EL2002]_
|
|
201
|
+
- [Lak2010]_
|
|
202
|
+
- [Tho2011]_
|
|
203
|
+
- [LT2012]_
|
|
204
|
+
"""
|
|
205
|
+
Element = SplittingAlgebraElement
|
|
206
|
+
|
|
207
|
+
def __init__(self, monic_polynomial, names='X', iterate=True, warning=True):
|
|
208
|
+
r"""
|
|
209
|
+
Python constructor.
|
|
210
|
+
|
|
211
|
+
EXAMPLES::
|
|
212
|
+
|
|
213
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
214
|
+
sage: Lw.<w> = LaurentPolynomialRing(ZZ)
|
|
215
|
+
sage: PuvLw.<u,v> = Lw[]; t = polygen(PuvLw)
|
|
216
|
+
sage: S.<x, y> = SplittingAlgebra(t^3 - u*t^2 + v*t - w, warning=False)
|
|
217
|
+
sage: TestSuite(S).run()
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
# ---------------------------------------------------------------------------------
|
|
221
|
+
# checking input parameters
|
|
222
|
+
# ---------------------------------------------------------------------------------
|
|
223
|
+
|
|
224
|
+
base_ring = monic_polynomial.base_ring()
|
|
225
|
+
if not monic_polynomial.is_monic():
|
|
226
|
+
raise ValueError("given polynomial must be monic")
|
|
227
|
+
deg = monic_polynomial.degree()
|
|
228
|
+
|
|
229
|
+
from sage.structure.category_object import normalize_names
|
|
230
|
+
self._root_names = normalize_names(deg-1, names)
|
|
231
|
+
root_names = list(self._root_names)
|
|
232
|
+
verbose("Create splitting algebra to base ring %s and polynomial %s (%s %s)"
|
|
233
|
+
% (base_ring, monic_polynomial, iterate, warning))
|
|
234
|
+
|
|
235
|
+
self._defining_polynomial = monic_polynomial
|
|
236
|
+
self._iterate = iterate
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
if not base_ring.is_integral_domain():
|
|
240
|
+
raise TypeError("base_ring must be an integral domain")
|
|
241
|
+
except NotImplementedError:
|
|
242
|
+
from sage.categories.rings import Rings
|
|
243
|
+
if base_ring not in Rings():
|
|
244
|
+
raise TypeError("base_ring must be a ring")
|
|
245
|
+
if warning:
|
|
246
|
+
warn('Assuming %s to be an integral domain!' % base_ring)
|
|
247
|
+
|
|
248
|
+
if deg < 1:
|
|
249
|
+
raise ValueError("the degree of the polynomial must positive")
|
|
250
|
+
|
|
251
|
+
self._splitting_roots = []
|
|
252
|
+
self._coefficients_list = []
|
|
253
|
+
self._invertible_elements = {}
|
|
254
|
+
|
|
255
|
+
if isinstance(base_ring, SplittingAlgebra):
|
|
256
|
+
self._invertible_elements = base_ring._invertible_elements
|
|
257
|
+
|
|
258
|
+
# ------------------------------------------------------------------------------------
|
|
259
|
+
# taking next root_name
|
|
260
|
+
# ------------------------------------------------------------------------------------
|
|
261
|
+
root_name = root_names[0]
|
|
262
|
+
p = monic_polynomial.change_variable_name(root_name)
|
|
263
|
+
P = p.parent()
|
|
264
|
+
|
|
265
|
+
self._set_modulus_irreducible_ = False
|
|
266
|
+
try:
|
|
267
|
+
if not p.is_irreducible():
|
|
268
|
+
raise ValueError("monic_polynomial must be irreducible")
|
|
269
|
+
except (NotImplementedError, AttributeError):
|
|
270
|
+
# assuming this has been checked mathematically before
|
|
271
|
+
self._set_modulus_irreducible_ = True
|
|
272
|
+
if warning:
|
|
273
|
+
warn('Assuming %s to have maximal Galois group!' % (monic_polynomial))
|
|
274
|
+
warning = False # one warning must be enough
|
|
275
|
+
|
|
276
|
+
verbose("P %s defined:" % (P))
|
|
277
|
+
|
|
278
|
+
if deg > 2 and iterate:
|
|
279
|
+
# ------------------------------------------------------------------------------------
|
|
280
|
+
# successive solution via recursion (on base_ring_step)
|
|
281
|
+
# ------------------------------------------------------------------------------------
|
|
282
|
+
base_ring_step = SplittingAlgebra(monic_polynomial, tuple(root_names), iterate=False, warning=False)
|
|
283
|
+
first_root = base_ring_step.gen()
|
|
284
|
+
|
|
285
|
+
verbose("base_ring_step %s defined:" % (base_ring_step))
|
|
286
|
+
|
|
287
|
+
# -------------------------------------------------------------
|
|
288
|
+
# splitting first root off
|
|
289
|
+
# -------------------------------------------------------------
|
|
290
|
+
from copy import copy
|
|
291
|
+
root_names_reduces = copy(root_names)
|
|
292
|
+
root_names_reduces.remove(root_name)
|
|
293
|
+
|
|
294
|
+
P = base_ring_step[root_names_reduces[0]]
|
|
295
|
+
p = P(monic_polynomial.monomial_coefficients())
|
|
296
|
+
q, _ = p.quo_rem(P.gen() - first_root)
|
|
297
|
+
|
|
298
|
+
verbose("Invoking recursion with: %s" % (q,))
|
|
299
|
+
|
|
300
|
+
SplittingAlgebra.__init__(self, q, root_names_reduces, warning=False)
|
|
301
|
+
|
|
302
|
+
splitting_roots = base_ring_step._splitting_roots + self._splitting_roots
|
|
303
|
+
coefficients_list = base_ring_step._coefficients_list + self._coefficients_list
|
|
304
|
+
|
|
305
|
+
verbose("Adding roots: %s" % (splitting_roots))
|
|
306
|
+
|
|
307
|
+
self._splitting_roots = splitting_roots
|
|
308
|
+
self._coefficients_list = coefficients_list
|
|
309
|
+
else:
|
|
310
|
+
PolynomialQuotientRing_domain.__init__(self, P, p, root_name)
|
|
311
|
+
|
|
312
|
+
first_root = self.gen()
|
|
313
|
+
self._splitting_roots.append(first_root)
|
|
314
|
+
self._coefficients_list = [monic_polynomial.coefficients(sparse=False)]
|
|
315
|
+
|
|
316
|
+
if not iterate:
|
|
317
|
+
verbose("pre ring defined splitting_roots: %s" % (self._splitting_roots))
|
|
318
|
+
return
|
|
319
|
+
|
|
320
|
+
verbose("final ring defined splitting_roots: %s" % (self._splitting_roots))
|
|
321
|
+
|
|
322
|
+
if deg == 2:
|
|
323
|
+
coefficients = monic_polynomial.coefficients(sparse=False)
|
|
324
|
+
lin_coeff = coefficients[1]
|
|
325
|
+
self._splitting_roots.append(-lin_coeff - first_root)
|
|
326
|
+
|
|
327
|
+
self._root_names = names
|
|
328
|
+
self._splitting_roots = [self(root) for root in self._splitting_roots]
|
|
329
|
+
verbose("splitting_roots: %s embedded" % (self._splitting_roots))
|
|
330
|
+
|
|
331
|
+
# --------------------------------------------------------------------
|
|
332
|
+
# try to calculate inverses of the roots. This is possible if the original polynomial
|
|
333
|
+
# has an invertible constant term. For example let cf = [-w, v,-u, 1] that is
|
|
334
|
+
# p = h^3 -u*h^2 + v*h -w, than u = x + y + z, v = x*y + x*z + y*z, w = x*y*z. If
|
|
335
|
+
# w is invertible then 1/x = (v -(u-x)*x)/w, 1/y = (v -(u-y)*y)/w, 1/z = (v -(u-z)*z)/w
|
|
336
|
+
# -----------------------------------------------------------------
|
|
337
|
+
# first find the polynomial with invertible constant coefficient
|
|
338
|
+
# -----------------------------------------------------------------
|
|
339
|
+
cf0_inv = None
|
|
340
|
+
for cf in self._coefficients_list:
|
|
341
|
+
cf0 = cf[0]
|
|
342
|
+
try:
|
|
343
|
+
cf0_inv = ~(cf[0])
|
|
344
|
+
cf0_inv = self(cf0_inv)
|
|
345
|
+
verbose("invertible coefficient: %s found" % (cf0_inv))
|
|
346
|
+
break
|
|
347
|
+
except NotImplementedError:
|
|
348
|
+
verbose("constant coefficient: %s not invertibe" % (cf0))
|
|
349
|
+
|
|
350
|
+
# ------------------------------------------------------------------
|
|
351
|
+
# assuming that cf splits into linear factors over self
|
|
352
|
+
# and the _splitting_roots are its roots we can calculate inverses
|
|
353
|
+
# ------------------------------------------------------------------
|
|
354
|
+
if cf0_inv is not None:
|
|
355
|
+
deg_cf = len(cf)-1
|
|
356
|
+
pf = P(cf)
|
|
357
|
+
for root in self._splitting_roots:
|
|
358
|
+
check = self(pf)
|
|
359
|
+
if not check.is_zero():
|
|
360
|
+
continue
|
|
361
|
+
root_inv = self.one()
|
|
362
|
+
for pos in range(deg_cf-1):
|
|
363
|
+
root_inv = (-1)**(pos+1) * cf[deg_cf-pos-1] - root_inv * root
|
|
364
|
+
verbose("inverse %s of root %s" % (root_inv, root))
|
|
365
|
+
root_inv = (-1)**(deg_cf) * cf0_inv * root_inv
|
|
366
|
+
self._invertible_elements.update({root:root_inv})
|
|
367
|
+
verbose("adding inverse %s of root %s" % (root_inv, root))
|
|
368
|
+
invert_items = list(self._invertible_elements.items())
|
|
369
|
+
for k, v in invert_items:
|
|
370
|
+
self._invertible_elements.update({v: k})
|
|
371
|
+
return
|
|
372
|
+
|
|
373
|
+
########################################################################
|
|
374
|
+
# ----------------------------------------------------------------------
|
|
375
|
+
# overloaded inherited methods
|
|
376
|
+
# ----------------------------------------------------------------------
|
|
377
|
+
########################################################################
|
|
378
|
+
def __reduce__(self):
|
|
379
|
+
r"""
|
|
380
|
+
Used in pickling.
|
|
381
|
+
|
|
382
|
+
EXAMPLES::
|
|
383
|
+
|
|
384
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
385
|
+
sage: L.<t, u, v, w > = LaurentPolynomialRing(ZZ); x = polygen(L)
|
|
386
|
+
sage: S = SplittingAlgebra(x^4 -t*x^3 - u*x^2 - v*x + w, ('X', 'Y', 'Z'), warning=False)
|
|
387
|
+
sage: S.__reduce__()
|
|
388
|
+
(<class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category'>,
|
|
389
|
+
(x^4 - t*x^3 - u*x^2 - v*x + w, ('X', 'Y', 'Z'), True, False))
|
|
390
|
+
sage: S.base_ring().__reduce__()
|
|
391
|
+
(<class 'sage.algebras.splitting_algebra.SplittingAlgebra_with_category'>,
|
|
392
|
+
(Y^3 + (X - t)*Y^2 + (X^2 - t*X - u)*Y + X^3 - t*X^2 - u*X - v,
|
|
393
|
+
('Y', 'Z'),
|
|
394
|
+
False,
|
|
395
|
+
False))
|
|
396
|
+
|
|
397
|
+
sage: TestSuite(S).run()
|
|
398
|
+
"""
|
|
399
|
+
defining_polynomial = self.defining_polynomial()
|
|
400
|
+
definig_coefficients = self._coefficients_list[0]
|
|
401
|
+
if defining_polynomial.coefficients(sparse=False) != definig_coefficients:
|
|
402
|
+
# case of factorization algebra (intermediate construction step)
|
|
403
|
+
par_pol = self.cover_ring()
|
|
404
|
+
defining_polynomial = par_pol(definig_coefficients)
|
|
405
|
+
return self.__class__, (defining_polynomial, self._root_names, self._iterate, False)
|
|
406
|
+
|
|
407
|
+
def _repr_(self):
|
|
408
|
+
r"""
|
|
409
|
+
Return a string representation of ``self``.
|
|
410
|
+
|
|
411
|
+
EXAMPLES::
|
|
412
|
+
|
|
413
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
414
|
+
sage: L.<u, v> = PolynomialRing(ZZ)
|
|
415
|
+
sage: t = polygen(L)
|
|
416
|
+
sage: Spl.<S, T> = SplittingAlgebra(t^3 - (u^2-v)*t^2 + (v+u)*t - 1)
|
|
417
|
+
sage: Spl._repr_()
|
|
418
|
+
'Splitting Algebra of x^3 + (-u^2 + v)*x^2 + (u + v)*x - 1
|
|
419
|
+
with roots [S, T, -T - S + u^2 - v]
|
|
420
|
+
over Multivariate Polynomial Ring in u, v over Integer Ring'
|
|
421
|
+
sage: Spl.base_ring() # indirect doctest
|
|
422
|
+
Factorization Algebra of x^3 + (-u^2 + v)*x^2 + (u + v)*x - 1
|
|
423
|
+
with roots [S] over Multivariate Polynomial Ring in u, v over Integer Ring
|
|
424
|
+
"""
|
|
425
|
+
if self.is_completely_split():
|
|
426
|
+
return ('Splitting Algebra of %s with roots %s over %s'
|
|
427
|
+
% (self.defining_polynomial(), self.splitting_roots(), self.scalar_base_ring()))
|
|
428
|
+
else:
|
|
429
|
+
return ('Factorization Algebra of %s with roots %s over %s'
|
|
430
|
+
% (self.defining_polynomial(), self.splitting_roots(), self.scalar_base_ring()))
|
|
431
|
+
|
|
432
|
+
def _first_ngens(self, n):
|
|
433
|
+
r"""
|
|
434
|
+
Used by the preparser for ``R.<x> = ...``.
|
|
435
|
+
|
|
436
|
+
EXAMPLES::
|
|
437
|
+
|
|
438
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
439
|
+
sage: L.<u, v> = PolynomialRing(ZZ)
|
|
440
|
+
sage: t = polygen(L)
|
|
441
|
+
sage: S.<X, Y> = SplittingAlgebra(t^3 - (u^2-v)*t^2 + (v+u)*t - 1) # indirect doctest
|
|
442
|
+
sage: X.parent()
|
|
443
|
+
Splitting Algebra of x^3 + (-u^2 + v)*x^2 + (u + v)*x - 1
|
|
444
|
+
with roots [X, Y, -Y - X + u^2 - v]
|
|
445
|
+
over Multivariate Polynomial Ring in u, v over Integer Ring
|
|
446
|
+
sage: S._first_ngens(4)
|
|
447
|
+
(X, Y, u, v)
|
|
448
|
+
"""
|
|
449
|
+
srts = self.splitting_roots()
|
|
450
|
+
k = len(srts)-1
|
|
451
|
+
gens = srts[:k] + list(self.scalar_base_ring().gens())
|
|
452
|
+
return tuple(gens[:n])
|
|
453
|
+
|
|
454
|
+
def _element_constructor_(self, x):
|
|
455
|
+
r"""
|
|
456
|
+
Make sure ``x`` is a valid member of ``self``, and return the constructed element.
|
|
457
|
+
|
|
458
|
+
TESTS::
|
|
459
|
+
|
|
460
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
461
|
+
sage: L.<u, v, w> = LaurentPolynomialRing(ZZ); x = polygen(L)
|
|
462
|
+
sage: S.<X, Y> = SplittingAlgebra(x^3 - u*x^2 + v*x - w)
|
|
463
|
+
sage: S(u + v)
|
|
464
|
+
u + v
|
|
465
|
+
sage: S(X*Y + X)
|
|
466
|
+
X*Y + X
|
|
467
|
+
sage: TestSuite(S).run() # indirect doctest
|
|
468
|
+
"""
|
|
469
|
+
if isinstance(x, SplittingAlgebraElement):
|
|
470
|
+
# coercion from covering fixes pickling problems
|
|
471
|
+
return self(x.lift())
|
|
472
|
+
return super()._element_constructor_(x)
|
|
473
|
+
|
|
474
|
+
def hom(self, im_gens, codomain=None, check=True, base_map=None):
|
|
475
|
+
r"""
|
|
476
|
+
This version keeps track with the special recursive structure
|
|
477
|
+
of :class:`SplittingAlgebra`
|
|
478
|
+
|
|
479
|
+
Type ``Ring.hom?`` to see the general documentation of this method.
|
|
480
|
+
Here you see just special examples for the current class.
|
|
481
|
+
|
|
482
|
+
EXAMPLES::
|
|
483
|
+
|
|
484
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
485
|
+
sage: L.<u, v, w> = LaurentPolynomialRing(ZZ); x = polygen(L)
|
|
486
|
+
sage: S = SplittingAlgebra(x^3 - u*x^2 + v*x - w, ('X', 'Y'))
|
|
487
|
+
sage: P.<x, y, z> = PolynomialRing(ZZ)
|
|
488
|
+
sage: F = FractionField(P)
|
|
489
|
+
sage: im_gens = [F(g) for g in [y, x, x + y + z, x*y+x*z+y*z, x*y*z]]
|
|
490
|
+
sage: f = S.hom(im_gens)
|
|
491
|
+
sage: f(u), f(v), f(w)
|
|
492
|
+
(x + y + z, x*y + x*z + y*z, x*y*z)
|
|
493
|
+
sage: roots = S.splitting_roots(); roots
|
|
494
|
+
[X, Y, -Y - X + u]
|
|
495
|
+
sage: [f(r) for r in roots]
|
|
496
|
+
[x, y, z]
|
|
497
|
+
"""
|
|
498
|
+
base_ring = self.base_ring()
|
|
499
|
+
|
|
500
|
+
if not isinstance(im_gens, (list, tuple)):
|
|
501
|
+
im_gens = [im_gens]
|
|
502
|
+
|
|
503
|
+
all_gens = self.gens_dict_recursive()
|
|
504
|
+
if len(im_gens) != len(all_gens):
|
|
505
|
+
return super().hom(im_gens, codomain=codomain, check=check, base_map=base_map)
|
|
506
|
+
|
|
507
|
+
num_gens = len(self.gens())
|
|
508
|
+
im_gens_start = [img for img in im_gens if im_gens.index(img) < num_gens]
|
|
509
|
+
im_gens_end = [img for img in im_gens if im_gens.index(img) >= num_gens]
|
|
510
|
+
|
|
511
|
+
if not im_gens_end:
|
|
512
|
+
return super().hom(im_gens, codomain=codomain, check=check, base_map=base_map)
|
|
513
|
+
|
|
514
|
+
verbose('base %s im_gens_end %s codomain %s check %s base_map %s' % (base_ring, im_gens_end, codomain, check, base_map))
|
|
515
|
+
hom_on_base_recurs = base_ring.hom(im_gens_end, codomain=codomain, check=check, base_map=base_map)
|
|
516
|
+
verbose('hom_on_base_recurs %s' % (hom_on_base_recurs))
|
|
517
|
+
|
|
518
|
+
cover_ring = self.cover_ring()
|
|
519
|
+
hom_from_cover = cover_ring.hom(im_gens_start, codomain=codomain, check=check, base_map=hom_on_base_recurs)
|
|
520
|
+
lift = self.lifting_map()
|
|
521
|
+
return hom_from_cover*lift
|
|
522
|
+
|
|
523
|
+
###################################################################
|
|
524
|
+
# -----------------------------------------------------------------
|
|
525
|
+
# local methods
|
|
526
|
+
# -----------------------------------------------------------------
|
|
527
|
+
###################################################################
|
|
528
|
+
|
|
529
|
+
###################################################################
|
|
530
|
+
# -----------------------------------------------------------------
|
|
531
|
+
# global methods
|
|
532
|
+
# -----------------------------------------------------------------
|
|
533
|
+
###################################################################
|
|
534
|
+
|
|
535
|
+
def is_completely_split(self):
|
|
536
|
+
r"""
|
|
537
|
+
Return ``True`` if the defining polynomial of ``self`` splits into
|
|
538
|
+
linear factors over ``self``.
|
|
539
|
+
|
|
540
|
+
EXAMPLES::
|
|
541
|
+
|
|
542
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
543
|
+
sage: L.<u, v, w > = LaurentPolynomialRing(ZZ); x = polygen(L)
|
|
544
|
+
sage: S.<a,b> = SplittingAlgebra(x^3 - u*x^2 + v*x - w)
|
|
545
|
+
sage: S.is_completely_split()
|
|
546
|
+
True
|
|
547
|
+
sage: S.base_ring().is_completely_split()
|
|
548
|
+
False
|
|
549
|
+
"""
|
|
550
|
+
return len(self.splitting_roots()) >= self.defining_polynomial().degree()
|
|
551
|
+
|
|
552
|
+
@cached_method
|
|
553
|
+
def lifting_map(self):
|
|
554
|
+
r"""
|
|
555
|
+
Return a section map from ``self`` to the cover ring. It is implemented according
|
|
556
|
+
to the same named method of :class:`~sage.rings.quotient_ring.QuotientRing_nc`.
|
|
557
|
+
|
|
558
|
+
EXAMPLES::
|
|
559
|
+
|
|
560
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
561
|
+
sage: x = polygen(ZZ)
|
|
562
|
+
sage: S = SplittingAlgebra(x^2+1, ('I',))
|
|
563
|
+
sage: lift = S.lifting_map()
|
|
564
|
+
sage: lift(5)
|
|
565
|
+
5
|
|
566
|
+
sage: r1, r2 =S.splitting_roots()
|
|
567
|
+
sage: lift(r1)
|
|
568
|
+
I
|
|
569
|
+
"""
|
|
570
|
+
from sage.rings.morphism import RingMap_lift
|
|
571
|
+
return RingMap_lift(self, self.cover_ring())
|
|
572
|
+
|
|
573
|
+
def splitting_roots(self):
|
|
574
|
+
r"""
|
|
575
|
+
Return the roots of the split equation.
|
|
576
|
+
|
|
577
|
+
EXAMPLES::
|
|
578
|
+
|
|
579
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
580
|
+
sage: x = polygen(ZZ)
|
|
581
|
+
sage: S = SplittingAlgebra(x^2+1, ('I',))
|
|
582
|
+
sage: S.splitting_roots()
|
|
583
|
+
[I, -I]
|
|
584
|
+
"""
|
|
585
|
+
return self._splitting_roots
|
|
586
|
+
|
|
587
|
+
@cached_method
|
|
588
|
+
def scalar_base_ring(self):
|
|
589
|
+
r"""
|
|
590
|
+
Return the ring of scalars of ``self`` (considered as an algebra).
|
|
591
|
+
|
|
592
|
+
EXAMPLES::
|
|
593
|
+
|
|
594
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
595
|
+
sage: L.<u, v, w > = LaurentPolynomialRing(ZZ)
|
|
596
|
+
sage: x = polygen(L)
|
|
597
|
+
sage: S = SplittingAlgebra(x^3 - u*x^2 + v*x - w, ('X', 'Y'))
|
|
598
|
+
sage: S.base_ring()
|
|
599
|
+
Factorization Algebra of x^3 - u*x^2 + v*x - w with roots [X]
|
|
600
|
+
over Multivariate Laurent Polynomial Ring in u, v, w over Integer Ring
|
|
601
|
+
sage: S.scalar_base_ring()
|
|
602
|
+
Multivariate Laurent Polynomial Ring in u, v, w over Integer Ring
|
|
603
|
+
"""
|
|
604
|
+
base_ring = self.base_ring()
|
|
605
|
+
if isinstance(base_ring, SplittingAlgebra):
|
|
606
|
+
if base_ring.is_completely_split():
|
|
607
|
+
# another splitting algebra independent of self
|
|
608
|
+
return base_ring
|
|
609
|
+
else:
|
|
610
|
+
return base_ring.scalar_base_ring()
|
|
611
|
+
return base_ring
|
|
612
|
+
|
|
613
|
+
@cached_method
|
|
614
|
+
def defining_polynomial(self):
|
|
615
|
+
r"""
|
|
616
|
+
Return the defining polynomial of ``self``.
|
|
617
|
+
|
|
618
|
+
EXAMPLES::
|
|
619
|
+
|
|
620
|
+
sage: from sage.algebras.splitting_algebra import SplittingAlgebra
|
|
621
|
+
sage: L.<u, v, w > = LaurentPolynomialRing(ZZ)
|
|
622
|
+
sage: x = polygen(L)
|
|
623
|
+
sage: S = SplittingAlgebra(x^3 - u*x^2 + v*x - w, ('X', 'Y'))
|
|
624
|
+
sage: S.defining_polynomial()
|
|
625
|
+
x^3 - u*x^2 + v*x - w
|
|
626
|
+
"""
|
|
627
|
+
base_ring = self.base_ring()
|
|
628
|
+
if isinstance(base_ring, SplittingAlgebra):
|
|
629
|
+
if base_ring.is_completely_split():
|
|
630
|
+
# another splitting algebra independent of self
|
|
631
|
+
return self._defining_polynomial
|
|
632
|
+
else:
|
|
633
|
+
return base_ring.defining_polynomial()
|
|
634
|
+
return self._defining_polynomial
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
# --------------------------------------------------------------------------------------------
|
|
638
|
+
# ============================================================================================
|
|
639
|
+
# Utility function to create the roots of a polynomial in an appropriate extension ring
|
|
640
|
+
# ============================================================================================
|
|
641
|
+
# --------------------------------------------------------------------------------------------
|
|
642
|
+
|
|
643
|
+
def solve_with_extension(monic_polynomial, root_names=None, var='x', flatten=False, warning=True):
|
|
644
|
+
r"""
|
|
645
|
+
Return all roots of a monic polynomial in its base ring or in an appropriate
|
|
646
|
+
extension ring, as far as possible.
|
|
647
|
+
|
|
648
|
+
INPUT:
|
|
649
|
+
|
|
650
|
+
- ``monic_polynomial`` -- the monic polynomial whose roots should be created
|
|
651
|
+
- ``root_names`` -- names for the indeterminates needed to define the
|
|
652
|
+
splitting algebra of the ``monic_polynomial`` (if necessary and possible)
|
|
653
|
+
- ``var`` -- (default: ``'x'``) for the indeterminate needed to define the
|
|
654
|
+
splitting field of the ``monic_polynomial`` (if necessary and possible)
|
|
655
|
+
- ``flatten`` -- boolean (default: ``True``); if ``True`` the roots will
|
|
656
|
+
not be given as a list of pairs ``(root, multiplicity)`` but as a list of
|
|
657
|
+
roots repeated according to their multiplicity
|
|
658
|
+
- ``warning`` -- boolean (default: ``True``); can be used (by setting to
|
|
659
|
+
``False``) to suppress a warning which will be thrown whenever it cannot
|
|
660
|
+
be checked that the Galois group of ``monic_polynomial`` is maximal
|
|
661
|
+
|
|
662
|
+
OUTPUT:
|
|
663
|
+
|
|
664
|
+
List of tuples ``(root, multiplicity)`` respectively list of roots repeated
|
|
665
|
+
according to their multiplicity if option ``flatten`` is ``True``.
|
|
666
|
+
|
|
667
|
+
EXAMPLES::
|
|
668
|
+
|
|
669
|
+
sage: from sage.algebras.splitting_algebra import solve_with_extension
|
|
670
|
+
sage: t = polygen(ZZ)
|
|
671
|
+
sage: p = t^2 -2*t +1
|
|
672
|
+
sage: solve_with_extension(p, flatten=True )
|
|
673
|
+
[1, 1]
|
|
674
|
+
sage: solve_with_extension(p)
|
|
675
|
+
[(1, 2)]
|
|
676
|
+
|
|
677
|
+
sage: cp5 = cyclotomic_polynomial(5, var='T').change_ring(UniversalCyclotomicField())
|
|
678
|
+
sage: solve_with_extension(cp5)
|
|
679
|
+
[(E(5), 1), (E(5)^4, 1), (E(5)^2, 1), (E(5)^3, 1)]
|
|
680
|
+
sage: _[0][0].parent()
|
|
681
|
+
Universal Cyclotomic Field
|
|
682
|
+
"""
|
|
683
|
+
def create_roots(monic_polynomial, warning=True):
|
|
684
|
+
r"""
|
|
685
|
+
This internal function creates all roots of a polynomial in an
|
|
686
|
+
appropriate extension ring assuming that none of the roots is
|
|
687
|
+
contained its base ring.
|
|
688
|
+
|
|
689
|
+
It first tries to create the splitting field of the given polynomial.
|
|
690
|
+
If this is not faithful the splitting algebra will be created.
|
|
691
|
+
|
|
692
|
+
INPUT:
|
|
693
|
+
|
|
694
|
+
- ``monic_polynomial`` -- the monic polynomial whose roots should
|
|
695
|
+
be created
|
|
696
|
+
- ``warning`` -- boolean (default: ``True``); can be used (by setting
|
|
697
|
+
to ``False``) to suppress a warning which will be thrown whenever it
|
|
698
|
+
cannot be checked that the Galois group of ``monic_polynomial`` is
|
|
699
|
+
maximal
|
|
700
|
+
"""
|
|
701
|
+
parent = monic_polynomial.parent()
|
|
702
|
+
base_ring = parent.base_ring()
|
|
703
|
+
|
|
704
|
+
try:
|
|
705
|
+
ext_field, embed = monic_polynomial.splitting_field(var, map=True)
|
|
706
|
+
|
|
707
|
+
if embed.domain() != base_ring:
|
|
708
|
+
# in this case the SplittingAlgebra is preferred
|
|
709
|
+
raise NotImplementedError
|
|
710
|
+
|
|
711
|
+
# -------------------------------------------------------------------------------------
|
|
712
|
+
# in some cases the embedding of the base_ring in ext_field can not be obtained
|
|
713
|
+
# as coercion
|
|
714
|
+
# -------------------------------------------------------------------------------------
|
|
715
|
+
reset_coercion = False
|
|
716
|
+
from sage.rings.number_field.number_field import NumberField_generic
|
|
717
|
+
if isinstance(base_ring, NumberField_generic):
|
|
718
|
+
reset_coercion = True
|
|
719
|
+
elif base_ring.is_finite() and not base_ring.is_prime_field():
|
|
720
|
+
reset_coercion = True
|
|
721
|
+
if reset_coercion:
|
|
722
|
+
ext_field._unset_coercions_used()
|
|
723
|
+
ext_field.register_coercion(embed)
|
|
724
|
+
ext_field.register_conversion(embed)
|
|
725
|
+
|
|
726
|
+
verbose("splitting field %s defined" % (ext_field))
|
|
727
|
+
pol_emb = monic_polynomial.change_ring(ext_field)
|
|
728
|
+
roots = pol_emb.roots()
|
|
729
|
+
except NotImplementedError:
|
|
730
|
+
ext_ring = SplittingAlgebra(monic_polynomial, name_list, warning=warning)
|
|
731
|
+
verbose("splitting algebra %s defined" % (ext_ring))
|
|
732
|
+
roots = [(r, 1) for r in ext_ring.splitting_roots()]
|
|
733
|
+
return roots
|
|
734
|
+
|
|
735
|
+
deg_pol = monic_polynomial.degree()
|
|
736
|
+
if not root_names:
|
|
737
|
+
from sage.structure.category_object import normalize_names
|
|
738
|
+
root_names = normalize_names(deg_pol-1, 'r')
|
|
739
|
+
name_list = list(root_names)
|
|
740
|
+
root_list = []
|
|
741
|
+
try:
|
|
742
|
+
root_list = monic_polynomial.roots()
|
|
743
|
+
except (TypeError, ValueError, NotImplementedError):
|
|
744
|
+
pass
|
|
745
|
+
|
|
746
|
+
if not root_list:
|
|
747
|
+
# --------------------------------------------------------------
|
|
748
|
+
# no roots found: find roots in an appropriate extension ring
|
|
749
|
+
# --------------------------------------------------------------
|
|
750
|
+
verbose("no roots in base_ring")
|
|
751
|
+
if len(name_list) > deg_pol - 1:
|
|
752
|
+
name_list = [name_list[i] for i in range(deg_pol - 1)]
|
|
753
|
+
roots = create_roots(monic_polynomial, warning=warning)
|
|
754
|
+
|
|
755
|
+
else:
|
|
756
|
+
# ------------------------------------------------------------------
|
|
757
|
+
# root calculation was possible but maybe some more roots in
|
|
758
|
+
# an appropriate extension ring can be constructed.
|
|
759
|
+
# ------------------------------------------------------------------
|
|
760
|
+
num_roots = sum(m for r, m in root_list)
|
|
761
|
+
if num_roots < deg_pol:
|
|
762
|
+
h = monic_polynomial.variables()[0]
|
|
763
|
+
divisor = monic_polynomial.base_ring().one()
|
|
764
|
+
for r, m in root_list:
|
|
765
|
+
divisor *= (h - r)**m
|
|
766
|
+
q, r = monic_polynomial.quo_rem(divisor)
|
|
767
|
+
if len(name_list) > deg_pol - num_roots - 1:
|
|
768
|
+
name_list = [name_list[i] for i in range(deg_pol - num_roots - 1)]
|
|
769
|
+
verbose("%d root found in base ring, now solving %s" % (num_roots,q))
|
|
770
|
+
missing_roots = create_roots(q, warning=True)
|
|
771
|
+
roots = root_list + missing_roots
|
|
772
|
+
else:
|
|
773
|
+
roots = root_list
|
|
774
|
+
verbose("all roots in base ring")
|
|
775
|
+
|
|
776
|
+
if flatten:
|
|
777
|
+
from sage.misc.flatten import flatten
|
|
778
|
+
return flatten([[rt]*m for rt, m in roots])
|
|
779
|
+
return roots
|