passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.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_categories-10.6.32.dist-info/METADATA +156 -0
- passagemath_categories-10.6.32.dist-info/RECORD +719 -0
- passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
- passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_categories.py +28 -0
- sage/arith/all.py +38 -0
- sage/arith/constants.pxd +27 -0
- sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/functions.pxd +4 -0
- sage/arith/functions.pyx +221 -0
- sage/arith/misc.py +6552 -0
- sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/multi_modular.pxd +39 -0
- sage/arith/multi_modular.pyx +994 -0
- sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/rational_reconstruction.pxd +4 -0
- sage/arith/rational_reconstruction.pyx +115 -0
- sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/srange.pyx +571 -0
- sage/calculus/all__sagemath_categories.py +2 -0
- sage/calculus/functional.py +481 -0
- sage/calculus/functions.py +151 -0
- sage/categories/additive_groups.py +73 -0
- sage/categories/additive_magmas.py +1044 -0
- sage/categories/additive_monoids.py +114 -0
- sage/categories/additive_semigroups.py +184 -0
- sage/categories/affine_weyl_groups.py +238 -0
- sage/categories/algebra_ideals.py +95 -0
- sage/categories/algebra_modules.py +96 -0
- sage/categories/algebras.py +349 -0
- sage/categories/algebras_with_basis.py +377 -0
- sage/categories/all.py +160 -0
- sage/categories/aperiodic_semigroups.py +29 -0
- sage/categories/associative_algebras.py +47 -0
- sage/categories/bialgebras.py +101 -0
- sage/categories/bialgebras_with_basis.py +414 -0
- sage/categories/bimodules.py +206 -0
- sage/categories/chain_complexes.py +268 -0
- sage/categories/classical_crystals.py +480 -0
- sage/categories/coalgebras.py +405 -0
- sage/categories/coalgebras_with_basis.py +232 -0
- sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/coercion_methods.pyx +52 -0
- sage/categories/commutative_additive_groups.py +104 -0
- sage/categories/commutative_additive_monoids.py +45 -0
- sage/categories/commutative_additive_semigroups.py +48 -0
- sage/categories/commutative_algebra_ideals.py +87 -0
- sage/categories/commutative_algebras.py +94 -0
- sage/categories/commutative_ring_ideals.py +58 -0
- sage/categories/commutative_rings.py +736 -0
- sage/categories/complete_discrete_valuation.py +293 -0
- sage/categories/complex_reflection_groups.py +145 -0
- sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
- sage/categories/coxeter_group_algebras.py +186 -0
- sage/categories/coxeter_groups.py +3402 -0
- sage/categories/crystals.py +2628 -0
- sage/categories/cw_complexes.py +216 -0
- sage/categories/dedekind_domains.py +137 -0
- sage/categories/discrete_valuation.py +325 -0
- sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
- sage/categories/division_rings.py +114 -0
- sage/categories/domains.py +95 -0
- sage/categories/drinfeld_modules.py +789 -0
- sage/categories/dual.py +42 -0
- sage/categories/enumerated_sets.py +1146 -0
- sage/categories/euclidean_domains.py +271 -0
- sage/categories/examples/algebras_with_basis.py +102 -0
- sage/categories/examples/all.py +1 -0
- sage/categories/examples/commutative_additive_monoids.py +130 -0
- sage/categories/examples/commutative_additive_semigroups.py +199 -0
- sage/categories/examples/coxeter_groups.py +8 -0
- sage/categories/examples/crystals.py +236 -0
- sage/categories/examples/cw_complexes.py +163 -0
- sage/categories/examples/facade_sets.py +187 -0
- sage/categories/examples/filtered_algebras_with_basis.py +204 -0
- sage/categories/examples/filtered_modules_with_basis.py +154 -0
- sage/categories/examples/finite_coxeter_groups.py +252 -0
- sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
- sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
- sage/categories/examples/finite_enumerated_sets.py +208 -0
- sage/categories/examples/finite_monoids.py +150 -0
- sage/categories/examples/finite_semigroups.py +190 -0
- sage/categories/examples/finite_weyl_groups.py +191 -0
- sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
- sage/categories/examples/graded_modules_with_basis.py +168 -0
- sage/categories/examples/graphs.py +122 -0
- sage/categories/examples/hopf_algebras_with_basis.py +145 -0
- sage/categories/examples/infinite_enumerated_sets.py +190 -0
- sage/categories/examples/lie_algebras.py +352 -0
- sage/categories/examples/lie_algebras_with_basis.py +196 -0
- sage/categories/examples/magmas.py +162 -0
- sage/categories/examples/manifolds.py +94 -0
- sage/categories/examples/monoids.py +144 -0
- sage/categories/examples/posets.py +178 -0
- sage/categories/examples/semigroups.py +580 -0
- sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/examples/semigroups_cython.pyx +221 -0
- sage/categories/examples/semirings.py +249 -0
- sage/categories/examples/sets_cat.py +706 -0
- sage/categories/examples/sets_with_grading.py +101 -0
- sage/categories/examples/with_realizations.py +542 -0
- sage/categories/fields.py +991 -0
- sage/categories/filtered_algebras.py +63 -0
- sage/categories/filtered_algebras_with_basis.py +548 -0
- sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
- sage/categories/filtered_modules.py +210 -0
- sage/categories/filtered_modules_with_basis.py +1209 -0
- sage/categories/finite_complex_reflection_groups.py +1506 -0
- sage/categories/finite_coxeter_groups.py +1138 -0
- sage/categories/finite_crystals.py +103 -0
- sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
- sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
- sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
- sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
- sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
- sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
- sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
- sage/categories/finite_enumerated_sets.py +769 -0
- sage/categories/finite_fields.py +252 -0
- sage/categories/finite_groups.py +256 -0
- sage/categories/finite_lattice_posets.py +242 -0
- sage/categories/finite_monoids.py +316 -0
- sage/categories/finite_permutation_groups.py +339 -0
- sage/categories/finite_posets.py +1994 -0
- sage/categories/finite_semigroups.py +136 -0
- sage/categories/finite_sets.py +93 -0
- sage/categories/finite_weyl_groups.py +39 -0
- sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
- sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
- sage/categories/finitely_generated_magmas.py +57 -0
- sage/categories/finitely_generated_semigroups.py +214 -0
- sage/categories/function_fields.py +76 -0
- sage/categories/g_sets.py +77 -0
- sage/categories/gcd_domains.py +65 -0
- sage/categories/generalized_coxeter_groups.py +94 -0
- sage/categories/graded_algebras.py +85 -0
- sage/categories/graded_algebras_with_basis.py +258 -0
- sage/categories/graded_bialgebras.py +32 -0
- sage/categories/graded_bialgebras_with_basis.py +32 -0
- sage/categories/graded_coalgebras.py +65 -0
- sage/categories/graded_coalgebras_with_basis.py +51 -0
- sage/categories/graded_hopf_algebras.py +41 -0
- sage/categories/graded_hopf_algebras_with_basis.py +169 -0
- sage/categories/graded_lie_algebras.py +91 -0
- sage/categories/graded_lie_algebras_with_basis.py +44 -0
- sage/categories/graded_lie_conformal_algebras.py +74 -0
- sage/categories/graded_modules.py +133 -0
- sage/categories/graded_modules_with_basis.py +329 -0
- sage/categories/graphs.py +138 -0
- sage/categories/group_algebras.py +430 -0
- sage/categories/groupoid.py +94 -0
- sage/categories/groups.py +667 -0
- sage/categories/h_trivial_semigroups.py +64 -0
- sage/categories/hecke_modules.py +185 -0
- sage/categories/highest_weight_crystals.py +980 -0
- sage/categories/hopf_algebras.py +219 -0
- sage/categories/hopf_algebras_with_basis.py +309 -0
- sage/categories/infinite_enumerated_sets.py +115 -0
- sage/categories/integral_domains.py +203 -0
- sage/categories/j_trivial_semigroups.py +29 -0
- sage/categories/kac_moody_algebras.py +82 -0
- sage/categories/kahler_algebras.py +203 -0
- sage/categories/l_trivial_semigroups.py +63 -0
- sage/categories/lambda_bracket_algebras.py +280 -0
- sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
- sage/categories/lattice_posets.py +89 -0
- sage/categories/left_modules.py +49 -0
- sage/categories/lie_algebras.py +1070 -0
- sage/categories/lie_algebras_with_basis.py +261 -0
- sage/categories/lie_conformal_algebras.py +350 -0
- sage/categories/lie_conformal_algebras_with_basis.py +147 -0
- sage/categories/lie_groups.py +73 -0
- sage/categories/loop_crystals.py +1290 -0
- sage/categories/magmas.py +1189 -0
- sage/categories/magmas_and_additive_magmas.py +149 -0
- sage/categories/magmatic_algebras.py +365 -0
- sage/categories/manifolds.py +352 -0
- sage/categories/matrix_algebras.py +40 -0
- sage/categories/metric_spaces.py +387 -0
- sage/categories/modular_abelian_varieties.py +78 -0
- sage/categories/modules.py +989 -0
- sage/categories/modules_with_basis.py +2794 -0
- sage/categories/monoid_algebras.py +38 -0
- sage/categories/monoids.py +739 -0
- sage/categories/noetherian_rings.py +87 -0
- sage/categories/number_fields.py +242 -0
- sage/categories/ore_modules.py +189 -0
- sage/categories/partially_ordered_monoids.py +49 -0
- sage/categories/permutation_groups.py +63 -0
- sage/categories/pointed_sets.py +42 -0
- sage/categories/polyhedra.py +74 -0
- sage/categories/poor_man_map.py +270 -0
- sage/categories/posets.py +722 -0
- sage/categories/principal_ideal_domains.py +270 -0
- sage/categories/quantum_group_representations.py +543 -0
- sage/categories/quotient_fields.py +728 -0
- sage/categories/r_trivial_semigroups.py +45 -0
- sage/categories/regular_crystals.py +898 -0
- sage/categories/regular_supercrystals.py +170 -0
- sage/categories/right_modules.py +49 -0
- sage/categories/ring_ideals.py +74 -0
- sage/categories/rings.py +1904 -0
- sage/categories/rngs.py +175 -0
- sage/categories/schemes.py +393 -0
- sage/categories/semigroups.py +1060 -0
- sage/categories/semirings.py +71 -0
- sage/categories/semisimple_algebras.py +114 -0
- sage/categories/sets_with_grading.py +235 -0
- sage/categories/shephard_groups.py +43 -0
- sage/categories/signed_tensor.py +120 -0
- sage/categories/simplicial_complexes.py +134 -0
- sage/categories/simplicial_sets.py +1206 -0
- sage/categories/super_algebras.py +149 -0
- sage/categories/super_algebras_with_basis.py +144 -0
- sage/categories/super_hopf_algebras_with_basis.py +126 -0
- sage/categories/super_lie_conformal_algebras.py +193 -0
- sage/categories/super_modules.py +229 -0
- sage/categories/super_modules_with_basis.py +193 -0
- sage/categories/supercommutative_algebras.py +99 -0
- sage/categories/supercrystals.py +406 -0
- sage/categories/tensor.py +110 -0
- sage/categories/topological_spaces.py +170 -0
- sage/categories/triangular_kac_moody_algebras.py +439 -0
- sage/categories/tutorial.py +58 -0
- sage/categories/unique_factorization_domains.py +318 -0
- sage/categories/unital_algebras.py +426 -0
- sage/categories/vector_bundles.py +159 -0
- sage/categories/vector_spaces.py +357 -0
- sage/categories/weyl_groups.py +853 -0
- sage/combinat/all__sagemath_categories.py +34 -0
- sage/combinat/backtrack.py +180 -0
- sage/combinat/combinat.py +2269 -0
- sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/combinat_cython.pxd +6 -0
- sage/combinat/combinat_cython.pyx +390 -0
- sage/combinat/combination.py +796 -0
- sage/combinat/combinatorial_map.py +416 -0
- sage/combinat/composition.py +2192 -0
- sage/combinat/dlx.py +510 -0
- sage/combinat/integer_lists/__init__.py +7 -0
- sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/base.pxd +16 -0
- sage/combinat/integer_lists/base.pyx +713 -0
- sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/invlex.pxd +4 -0
- sage/combinat/integer_lists/invlex.pyx +1650 -0
- sage/combinat/integer_lists/lists.py +328 -0
- sage/combinat/integer_lists/nn.py +48 -0
- sage/combinat/integer_vector.py +1818 -0
- sage/combinat/integer_vector_weighted.py +413 -0
- sage/combinat/matrices/all__sagemath_categories.py +5 -0
- sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/matrices/dancing_links.pyx +1159 -0
- sage/combinat/matrices/dancing_links_c.h +380 -0
- sage/combinat/matrices/dlxcpp.py +136 -0
- sage/combinat/partition.py +10070 -0
- sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/partitions.pyx +743 -0
- sage/combinat/permutation.py +10168 -0
- sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/permutation_cython.pxd +11 -0
- sage/combinat/permutation_cython.pyx +407 -0
- sage/combinat/q_analogues.py +1090 -0
- sage/combinat/ranker.py +268 -0
- sage/combinat/subset.py +1561 -0
- sage/combinat/subsets_hereditary.py +202 -0
- sage/combinat/subsets_pairwise.py +184 -0
- sage/combinat/tools.py +63 -0
- sage/combinat/tuple.py +348 -0
- sage/data_structures/all.py +2 -0
- sage/data_structures/all__sagemath_categories.py +2 -0
- sage/data_structures/binary_matrix.pxd +138 -0
- sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/binary_search.pxd +3 -0
- sage/data_structures/binary_search.pyx +66 -0
- sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset.pxd +40 -0
- sage/data_structures/bitset.pyx +2385 -0
- sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset_base.pxd +926 -0
- sage/data_structures/bitset_base.pyx +117 -0
- sage/data_structures/bitset_intrinsics.h +487 -0
- sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/blas_dict.pxd +12 -0
- sage/data_structures/blas_dict.pyx +469 -0
- sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/list_of_pairs.pxd +16 -0
- sage/data_structures/list_of_pairs.pyx +122 -0
- sage/data_structures/mutable_poset.py +3312 -0
- sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/pairing_heap.h +346 -0
- sage/data_structures/pairing_heap.pxd +88 -0
- sage/data_structures/pairing_heap.pyx +1464 -0
- sage/data_structures/sparse_bitset.pxd +62 -0
- sage/data_structures/stream.py +5070 -0
- sage/databases/all__sagemath_categories.py +7 -0
- sage/databases/sql_db.py +2236 -0
- sage/ext/all__sagemath_categories.py +3 -0
- sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_callable.pxd +4 -0
- sage/ext/fast_callable.pyx +2746 -0
- sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_eval.pxd +1 -0
- sage/ext/fast_eval.pyx +102 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_categories.py +2 -0
- sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_el.pxd +18 -0
- sage/ext/interpreters/wrapper_el.pyx +148 -0
- sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_py.pxd +17 -0
- sage/ext/interpreters/wrapper_py.pyx +133 -0
- sage/functions/airy.py +937 -0
- sage/functions/all.py +97 -0
- sage/functions/bessel.py +2102 -0
- sage/functions/error.py +784 -0
- sage/functions/exp_integral.py +1529 -0
- sage/functions/gamma.py +1087 -0
- sage/functions/generalized.py +672 -0
- sage/functions/hyperbolic.py +747 -0
- sage/functions/hypergeometric.py +1156 -0
- sage/functions/jacobi.py +1705 -0
- sage/functions/log.py +1402 -0
- sage/functions/min_max.py +338 -0
- sage/functions/orthogonal_polys.py +3106 -0
- sage/functions/other.py +2303 -0
- sage/functions/piecewise.py +1505 -0
- sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/functions/prime_pi.pyx +262 -0
- sage/functions/special.py +1212 -0
- sage/functions/spike_function.py +278 -0
- sage/functions/transcendental.py +690 -0
- sage/functions/trig.py +1062 -0
- sage/functions/wigner.py +726 -0
- sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/geometry/abc.pyx +82 -0
- sage/geometry/all__sagemath_categories.py +1 -0
- sage/groups/all__sagemath_categories.py +11 -0
- sage/groups/generic.py +1733 -0
- sage/groups/groups_catalog.py +113 -0
- sage/groups/perm_gps/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/all.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
- sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
- sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
- sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
- sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
- sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
- sage/interfaces/abc.py +140 -0
- sage/interfaces/all.py +58 -0
- sage/interfaces/all__sagemath_categories.py +1 -0
- sage/interfaces/expect.py +1643 -0
- sage/interfaces/interface.py +1682 -0
- sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/process.pxd +5 -0
- sage/interfaces/process.pyx +288 -0
- sage/interfaces/quit.py +167 -0
- sage/interfaces/sage0.py +604 -0
- sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/sagespawn.pyx +308 -0
- sage/interfaces/tab_completion.py +101 -0
- sage/misc/all__sagemath_categories.py +78 -0
- sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/allocator.pxd +6 -0
- sage/misc/allocator.pyx +47 -0
- sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/binary_tree.pxd +29 -0
- sage/misc/binary_tree.pyx +537 -0
- sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/callable_dict.pyx +89 -0
- sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/citation.pyx +159 -0
- sage/misc/converting_dict.py +293 -0
- sage/misc/defaults.py +129 -0
- sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/derivative.pyx +223 -0
- sage/misc/functional.py +2005 -0
- sage/misc/html.py +589 -0
- sage/misc/latex.py +2673 -0
- sage/misc/latex_macros.py +236 -0
- sage/misc/latex_standalone.py +1833 -0
- sage/misc/map_threaded.py +38 -0
- sage/misc/mathml.py +76 -0
- sage/misc/method_decorator.py +88 -0
- sage/misc/mrange.py +755 -0
- sage/misc/multireplace.py +41 -0
- sage/misc/object_multiplexer.py +92 -0
- sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/parser.pyx +1107 -0
- sage/misc/random_testing.py +264 -0
- sage/misc/rest_index_of_methods.py +377 -0
- sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/search.pxd +2 -0
- sage/misc/search.pyx +68 -0
- sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/stopgap.pyx +95 -0
- sage/misc/table.py +853 -0
- sage/monoids/all__sagemath_categories.py +1 -0
- sage/monoids/indexed_free_monoid.py +1071 -0
- sage/monoids/monoid.py +82 -0
- sage/numerical/all__sagemath_categories.py +1 -0
- sage/numerical/backends/all__sagemath_categories.py +1 -0
- sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_backend.pxd +61 -0
- sage/numerical/backends/generic_backend.pyx +1893 -0
- sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_sdp_backend.pxd +38 -0
- sage/numerical/backends/generic_sdp_backend.pyx +755 -0
- sage/parallel/all.py +6 -0
- sage/parallel/decorate.py +575 -0
- sage/parallel/map_reduce.py +1997 -0
- sage/parallel/multiprocessing_sage.py +76 -0
- sage/parallel/ncpus.py +35 -0
- sage/parallel/parallelism.py +364 -0
- sage/parallel/reference.py +47 -0
- sage/parallel/use_fork.py +333 -0
- sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/abc.pxd +31 -0
- sage/rings/abc.pyx +526 -0
- sage/rings/algebraic_closure_finite_field.py +1154 -0
- sage/rings/all__sagemath_categories.py +91 -0
- sage/rings/big_oh.py +227 -0
- sage/rings/continued_fraction.py +2754 -0
- sage/rings/continued_fraction_gosper.py +220 -0
- sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/factorint.pyx +295 -0
- sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fast_arith.pxd +21 -0
- sage/rings/fast_arith.pyx +535 -0
- sage/rings/finite_rings/all__sagemath_categories.py +9 -0
- sage/rings/finite_rings/conway_polynomials.py +542 -0
- sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_base.pxd +12 -0
- sage/rings/finite_rings/element_base.pyx +1176 -0
- sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/finite_field_base.pxd +7 -0
- sage/rings/finite_rings/finite_field_base.pyx +2171 -0
- sage/rings/finite_rings/finite_field_constructor.py +827 -0
- sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
- sage/rings/finite_rings/galois_group.py +154 -0
- sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field.pxd +23 -0
- sage/rings/finite_rings/hom_finite_field.pyx +856 -0
- sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
- sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
- sage/rings/finite_rings/homset.py +357 -0
- sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/integer_mod.pxd +56 -0
- sage/rings/finite_rings/integer_mod.pyx +4586 -0
- sage/rings/finite_rings/integer_mod_limits.h +11 -0
- sage/rings/finite_rings/integer_mod_ring.py +2044 -0
- sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field.pxd +30 -0
- sage/rings/finite_rings/residue_field.pyx +1811 -0
- sage/rings/finite_rings/stdint.pxd +19 -0
- sage/rings/fraction_field.py +1452 -0
- sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fraction_field_element.pyx +1357 -0
- sage/rings/function_field/all.py +7 -0
- sage/rings/function_field/all__sagemath_categories.py +2 -0
- sage/rings/function_field/constructor.py +218 -0
- sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element.pxd +11 -0
- sage/rings/function_field/element.pyx +1008 -0
- sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element_rational.pyx +513 -0
- sage/rings/function_field/extensions.py +230 -0
- sage/rings/function_field/function_field.py +1468 -0
- sage/rings/function_field/function_field_rational.py +1005 -0
- sage/rings/function_field/ideal.py +1155 -0
- sage/rings/function_field/ideal_rational.py +629 -0
- sage/rings/function_field/jacobian_base.py +826 -0
- sage/rings/function_field/jacobian_hess.py +1053 -0
- sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
- sage/rings/function_field/maps.py +1039 -0
- sage/rings/function_field/order.py +281 -0
- sage/rings/function_field/order_basis.py +586 -0
- sage/rings/function_field/order_rational.py +576 -0
- sage/rings/function_field/place.py +426 -0
- sage/rings/function_field/place_rational.py +181 -0
- sage/rings/generic.py +320 -0
- sage/rings/homset.py +332 -0
- sage/rings/ideal.py +1885 -0
- sage/rings/ideal_monoid.py +215 -0
- sage/rings/infinity.py +1890 -0
- sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer.pxd +45 -0
- sage/rings/integer.pyx +7874 -0
- sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer_ring.pxd +8 -0
- sage/rings/integer_ring.pyx +1693 -0
- sage/rings/laurent_series_ring.py +931 -0
- sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/laurent_series_ring_element.pxd +11 -0
- sage/rings/laurent_series_ring_element.pyx +1927 -0
- sage/rings/lazy_series.py +7815 -0
- sage/rings/lazy_series_ring.py +4356 -0
- sage/rings/localization.py +1043 -0
- sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/morphism.pxd +39 -0
- sage/rings/morphism.pyx +3299 -0
- sage/rings/multi_power_series_ring.py +1145 -0
- sage/rings/multi_power_series_ring_element.py +2184 -0
- sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/noncommutative_ideals.pyx +423 -0
- sage/rings/number_field/all__sagemath_categories.py +1 -0
- sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_base.pxd +8 -0
- sage/rings/number_field/number_field_base.pyx +507 -0
- sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_element_base.pxd +6 -0
- sage/rings/number_field/number_field_element_base.pyx +36 -0
- sage/rings/number_field/number_field_ideal.py +3550 -0
- sage/rings/padics/all__sagemath_categories.py +4 -0
- sage/rings/padics/local_generic.py +1670 -0
- sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/local_generic_element.pxd +5 -0
- sage/rings/padics/local_generic_element.pyx +1017 -0
- sage/rings/padics/misc.py +256 -0
- sage/rings/padics/padic_generic.py +1911 -0
- sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer.pxd +38 -0
- sage/rings/padics/pow_computer.pyx +671 -0
- sage/rings/padics/precision_error.py +24 -0
- sage/rings/polynomial/all__sagemath_categories.py +25 -0
- sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/commutative_polynomial.pxd +6 -0
- sage/rings/polynomial/commutative_polynomial.pyx +24 -0
- sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/cyclotomic.pyx +404 -0
- sage/rings/polynomial/flatten.py +711 -0
- sage/rings/polynomial/ideal.py +102 -0
- sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
- sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
- sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial.pxd +18 -0
- sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
- sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
- sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
- sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
- sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial.pxd +12 -0
- sage/rings/polynomial/multi_polynomial.pyx +3082 -0
- sage/rings/polynomial/multi_polynomial_element.py +2570 -0
- sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
- sage/rings/polynomial/multi_polynomial_ring.py +947 -0
- sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
- sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
- sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polydict.pxd +45 -0
- sage/rings/polynomial/polydict.pyx +2701 -0
- sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_compiled.pxd +59 -0
- sage/rings/polynomial/polynomial_compiled.pyx +509 -0
- sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_element.pxd +64 -0
- sage/rings/polynomial/polynomial_element.pyx +13255 -0
- sage/rings/polynomial/polynomial_element_generic.py +1637 -0
- sage/rings/polynomial/polynomial_fateman.py +97 -0
- sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
- sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
- sage/rings/polynomial/polynomial_ring.py +3784 -0
- sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
- sage/rings/polynomial/polynomial_singular_interface.py +549 -0
- sage/rings/polynomial/symmetric_ideal.py +989 -0
- sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/symmetric_reduction.pxd +8 -0
- sage/rings/polynomial/symmetric_reduction.pyx +669 -0
- sage/rings/polynomial/term_order.py +2279 -0
- sage/rings/polynomial/toy_buchberger.py +449 -0
- sage/rings/polynomial/toy_d_basis.py +387 -0
- sage/rings/polynomial/toy_variety.py +362 -0
- sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_mpoly.pxd +9 -0
- sage/rings/power_series_mpoly.pyx +161 -0
- sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_poly.pxd +10 -0
- sage/rings/power_series_poly.pyx +1317 -0
- sage/rings/power_series_ring.py +1441 -0
- sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_ring_element.pxd +12 -0
- sage/rings/power_series_ring_element.pyx +3028 -0
- sage/rings/puiseux_series_ring.py +487 -0
- sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/puiseux_series_ring_element.pxd +7 -0
- sage/rings/puiseux_series_ring_element.pyx +1055 -0
- sage/rings/qqbar_decorators.py +167 -0
- sage/rings/quotient_ring.py +1598 -0
- sage/rings/quotient_ring_element.py +979 -0
- sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/rational.pxd +20 -0
- sage/rings/rational.pyx +4284 -0
- sage/rings/rational_field.py +1730 -0
- sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_double.pxd +16 -0
- sage/rings/real_double.pyx +2218 -0
- sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_lazy.pxd +30 -0
- sage/rings/real_lazy.pyx +1773 -0
- sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/ring.pxd +30 -0
- sage/rings/ring.pyx +850 -0
- sage/rings/semirings/all.py +3 -0
- sage/rings/semirings/non_negative_integer_semiring.py +107 -0
- sage/rings/semirings/tropical_mpolynomial.py +972 -0
- sage/rings/semirings/tropical_polynomial.py +997 -0
- sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/semirings/tropical_semiring.pyx +676 -0
- sage/rings/semirings/tropical_variety.py +1701 -0
- sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/sum_of_squares.pxd +3 -0
- sage/rings/sum_of_squares.pyx +336 -0
- sage/rings/tests.py +504 -0
- sage/schemes/affine/affine_homset.py +508 -0
- sage/schemes/affine/affine_morphism.py +1574 -0
- sage/schemes/affine/affine_point.py +460 -0
- sage/schemes/affine/affine_rational_point.py +308 -0
- sage/schemes/affine/affine_space.py +1264 -0
- sage/schemes/affine/affine_subscheme.py +592 -0
- sage/schemes/affine/all.py +25 -0
- sage/schemes/all__sagemath_categories.py +5 -0
- sage/schemes/generic/algebraic_scheme.py +2092 -0
- sage/schemes/generic/all.py +5 -0
- sage/schemes/generic/ambient_space.py +400 -0
- sage/schemes/generic/divisor.py +465 -0
- sage/schemes/generic/divisor_group.py +313 -0
- sage/schemes/generic/glue.py +84 -0
- sage/schemes/generic/homset.py +820 -0
- sage/schemes/generic/hypersurface.py +234 -0
- sage/schemes/generic/morphism.py +2107 -0
- sage/schemes/generic/point.py +237 -0
- sage/schemes/generic/scheme.py +1190 -0
- sage/schemes/generic/spec.py +199 -0
- sage/schemes/product_projective/all.py +6 -0
- sage/schemes/product_projective/homset.py +236 -0
- sage/schemes/product_projective/morphism.py +517 -0
- sage/schemes/product_projective/point.py +568 -0
- sage/schemes/product_projective/rational_point.py +550 -0
- sage/schemes/product_projective/space.py +1301 -0
- sage/schemes/product_projective/subscheme.py +466 -0
- sage/schemes/projective/all.py +24 -0
- sage/schemes/projective/proj_bdd_height.py +453 -0
- sage/schemes/projective/projective_homset.py +718 -0
- sage/schemes/projective/projective_morphism.py +2792 -0
- sage/schemes/projective/projective_point.py +1484 -0
- sage/schemes/projective/projective_rational_point.py +569 -0
- sage/schemes/projective/projective_space.py +2571 -0
- sage/schemes/projective/projective_subscheme.py +1574 -0
- sage/sets/all.py +17 -0
- sage/sets/cartesian_product.py +376 -0
- sage/sets/condition_set.py +525 -0
- sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/disjoint_set.pxd +36 -0
- sage/sets/disjoint_set.pyx +998 -0
- sage/sets/disjoint_union_enumerated_sets.py +625 -0
- sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/family.pxd +12 -0
- sage/sets/family.pyx +1556 -0
- sage/sets/finite_enumerated_set.py +406 -0
- sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/finite_set_map_cy.pxd +34 -0
- sage/sets/finite_set_map_cy.pyx +708 -0
- sage/sets/finite_set_maps.py +591 -0
- sage/sets/image_set.py +448 -0
- sage/sets/integer_range.py +829 -0
- sage/sets/non_negative_integers.py +241 -0
- sage/sets/positive_integers.py +93 -0
- sage/sets/primes.py +188 -0
- sage/sets/real_set.py +2760 -0
- sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/recursively_enumerated_set.pxd +31 -0
- sage/sets/recursively_enumerated_set.pyx +2082 -0
- sage/sets/set.py +2083 -0
- sage/sets/set_from_iterator.py +1021 -0
- sage/sets/totally_ordered_finite_set.py +329 -0
- sage/symbolic/all__sagemath_categories.py +1 -0
- sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/function.pxd +29 -0
- sage/symbolic/function.pyx +1488 -0
- sage/symbolic/symbols.py +56 -0
- sage/tests/all__sagemath_categories.py +1 -0
- sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/cython.pyx +37 -0
- sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/stl_vector.pyx +171 -0
- sage/typeset/all.py +6 -0
- sage/typeset/ascii_art.py +295 -0
- sage/typeset/character_art.py +789 -0
- sage/typeset/character_art_factory.py +572 -0
- sage/typeset/symbols.py +334 -0
- sage/typeset/unicode_art.py +183 -0
- sage/typeset/unicode_characters.py +101 -0
|
@@ -0,0 +1,1637 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
"""
|
|
3
|
+
Univariate Polynomials over domains and fields
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- William Stein: first version
|
|
8
|
+
- Martin Albrecht: Added singular coercion.
|
|
9
|
+
- David Harvey: split off polynomial_integer_dense_ntl.pyx (2007-09)
|
|
10
|
+
- Robert Bradshaw: split off polynomial_modn_dense_ntl.pyx (2007-09)
|
|
11
|
+
|
|
12
|
+
TESTS:
|
|
13
|
+
|
|
14
|
+
We test coercion in a particularly complicated situation::
|
|
15
|
+
|
|
16
|
+
sage: W.<w> = QQ['w']
|
|
17
|
+
sage: WZ.<z> = W['z']
|
|
18
|
+
sage: m = matrix(WZ, 2, 2, [1, z, z, z^2]) # needs sage.modules
|
|
19
|
+
sage: a = m.charpoly() # needs sage.modules
|
|
20
|
+
sage: R.<x> = WZ[]
|
|
21
|
+
sage: R(a) # needs sage.modules
|
|
22
|
+
x^2 + (-z^2 - 1)*x
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# ****************************************************************************
|
|
26
|
+
# Copyright (C) 2007 William Stein <wstein@gmail.com>
|
|
27
|
+
#
|
|
28
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
29
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
30
|
+
# the License, or (at your option) any later version.
|
|
31
|
+
# https://www.gnu.org/licenses/
|
|
32
|
+
# ****************************************************************************
|
|
33
|
+
from sage.rings.polynomial.polynomial_element import Polynomial, Polynomial_generic_dense, Polynomial_generic_dense_inexact
|
|
34
|
+
from sage.structure.element import IntegralDomainElement, EuclideanDomainElement
|
|
35
|
+
|
|
36
|
+
from sage.rings.polynomial.polynomial_singular_interface import Polynomial_singular_repr
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
from cypari2.gen import Gen as pari_gen
|
|
40
|
+
except ImportError:
|
|
41
|
+
pari_gen = ()
|
|
42
|
+
|
|
43
|
+
from sage.structure.element import coerce_binop, parent
|
|
44
|
+
from sage.structure.factorization import Factorization
|
|
45
|
+
from sage.structure.richcmp import richcmp, richcmp_item, rich_to_bool, rich_to_bool_sgn
|
|
46
|
+
|
|
47
|
+
from sage.rings.infinity import infinity, Infinity
|
|
48
|
+
from sage.rings.integer_ring import ZZ
|
|
49
|
+
from sage.rings.integer import Integer
|
|
50
|
+
from sage.rings.padics.precision_error import PrecisionError
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class Polynomial_generic_sparse(Polynomial):
|
|
54
|
+
"""
|
|
55
|
+
A generic sparse polynomial.
|
|
56
|
+
|
|
57
|
+
The ``Polynomial_generic_sparse`` class defines functionality for sparse
|
|
58
|
+
polynomials over any base ring. A sparse polynomial is represented using a
|
|
59
|
+
dictionary which maps each exponent to the corresponding coefficient. The
|
|
60
|
+
coefficients must never be zero.
|
|
61
|
+
|
|
62
|
+
EXAMPLES::
|
|
63
|
+
|
|
64
|
+
sage: R.<x> = PolynomialRing(PolynomialRing(QQ, 'y'), sparse=True)
|
|
65
|
+
sage: f = x^3 - x + 17
|
|
66
|
+
sage: type(f)
|
|
67
|
+
<class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain_with_category.element_class'>
|
|
68
|
+
sage: loads(f.dumps()) == f
|
|
69
|
+
True
|
|
70
|
+
|
|
71
|
+
A more extensive example::
|
|
72
|
+
|
|
73
|
+
sage: # needs sage.libs.pari
|
|
74
|
+
sage: A.<T> = PolynomialRing(Integers(5), sparse=True)
|
|
75
|
+
sage: f = T^2 + 1; B = A.quo(f)
|
|
76
|
+
sage: C.<s> = PolynomialRing(B)
|
|
77
|
+
sage: C
|
|
78
|
+
Univariate Polynomial Ring in s over Univariate Quotient Polynomial Ring in Tbar
|
|
79
|
+
over Ring of integers modulo 5 with modulus T^2 + 1
|
|
80
|
+
sage: s + T
|
|
81
|
+
s + Tbar
|
|
82
|
+
sage: (s + T)**2
|
|
83
|
+
s^2 + 2*Tbar*s + 4
|
|
84
|
+
"""
|
|
85
|
+
def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
|
|
86
|
+
"""
|
|
87
|
+
TESTS::
|
|
88
|
+
|
|
89
|
+
sage: PolynomialRing(RIF, 'z', sparse=True)([RIF(-1, 1), RIF(-1,1)]) # needs sage.rings.real_interval_field
|
|
90
|
+
0.?*z + 0.?
|
|
91
|
+
sage: PolynomialRing(RIF, 'z', sparse=True)((RIF(-1, 1), RIF(-1,1))) # needs sage.rings.real_interval_field
|
|
92
|
+
0.?*z + 0.?
|
|
93
|
+
sage: PolynomialRing(CIF, 'z', sparse=True)([CIF(RIF(-1,1), RIF(-1,1)), RIF(-1,1)]) # needs sage.rings.complex_interval_field
|
|
94
|
+
0.?*z + 0.? + 0.?*I
|
|
95
|
+
"""
|
|
96
|
+
Polynomial.__init__(self, parent, is_gen=is_gen)
|
|
97
|
+
if x is None:
|
|
98
|
+
self.__coeffs = {}
|
|
99
|
+
return
|
|
100
|
+
R = parent.base_ring()
|
|
101
|
+
if isinstance(x, Polynomial):
|
|
102
|
+
if x.parent() == self.parent():
|
|
103
|
+
x = x.monomial_coefficients()
|
|
104
|
+
elif x.parent() == R:
|
|
105
|
+
x = {0: x}
|
|
106
|
+
else:
|
|
107
|
+
w = {}
|
|
108
|
+
for n, c in x.monomial_coefficients().items():
|
|
109
|
+
w[n] = R(c)
|
|
110
|
+
# The following line has been added in github issue #9944.
|
|
111
|
+
# Apparently, the "else" case has never occurred before.
|
|
112
|
+
x = w
|
|
113
|
+
elif isinstance(x, (list, tuple)):
|
|
114
|
+
x = {i: c for i, c in enumerate(x) if c}
|
|
115
|
+
elif isinstance(x, pari_gen):
|
|
116
|
+
y = {}
|
|
117
|
+
for i in range(len(x)):
|
|
118
|
+
y[i] = R(x[i])
|
|
119
|
+
x = y
|
|
120
|
+
check = True
|
|
121
|
+
elif not isinstance(x, dict):
|
|
122
|
+
x = {0: x} # constant polynomials
|
|
123
|
+
if check:
|
|
124
|
+
self.__coeffs = {}
|
|
125
|
+
for i, z in x.items():
|
|
126
|
+
self.__coeffs[i] = R(z)
|
|
127
|
+
else:
|
|
128
|
+
self.__coeffs = x
|
|
129
|
+
if check:
|
|
130
|
+
self.__normalize()
|
|
131
|
+
|
|
132
|
+
def monomial_coefficients(self, copy=None):
|
|
133
|
+
"""
|
|
134
|
+
Return a new copy of the dict of the underlying
|
|
135
|
+
elements of ``self``.
|
|
136
|
+
|
|
137
|
+
EXAMPLES::
|
|
138
|
+
|
|
139
|
+
sage: R.<w> = PolynomialRing(Integers(8), sparse=True)
|
|
140
|
+
sage: f = 5 + w^1997 - w^10000; f
|
|
141
|
+
7*w^10000 + w^1997 + 5
|
|
142
|
+
sage: d = f.monomial_coefficients(); d
|
|
143
|
+
{0: 5, 1997: 1, 10000: 7}
|
|
144
|
+
sage: d[0] = 10
|
|
145
|
+
sage: f.monomial_coefficients()
|
|
146
|
+
{0: 5, 1997: 1, 10000: 7}
|
|
147
|
+
|
|
148
|
+
``dict`` is an alias::
|
|
149
|
+
|
|
150
|
+
sage: f.dict()
|
|
151
|
+
{0: 5, 1997: 1, 10000: 7}
|
|
152
|
+
"""
|
|
153
|
+
return dict(self.__coeffs)
|
|
154
|
+
|
|
155
|
+
dict = monomial_coefficients
|
|
156
|
+
|
|
157
|
+
def coefficients(self, sparse=True):
|
|
158
|
+
"""
|
|
159
|
+
Return the coefficients of the monomials appearing in ``self``.
|
|
160
|
+
|
|
161
|
+
EXAMPLES::
|
|
162
|
+
|
|
163
|
+
sage: R.<w> = PolynomialRing(Integers(8), sparse=True)
|
|
164
|
+
sage: f = 5 + w^1997 - w^10000; f
|
|
165
|
+
7*w^10000 + w^1997 + 5
|
|
166
|
+
sage: f.coefficients()
|
|
167
|
+
[5, 1, 7]
|
|
168
|
+
|
|
169
|
+
TESTS:
|
|
170
|
+
|
|
171
|
+
Check that all coefficients are in the base ring::
|
|
172
|
+
|
|
173
|
+
sage: S.<x> = PolynomialRing(QQ, sparse=True)
|
|
174
|
+
sage: f = x^4
|
|
175
|
+
sage: all(c.parent() is QQ for c in f.coefficients(False))
|
|
176
|
+
True
|
|
177
|
+
"""
|
|
178
|
+
if sparse:
|
|
179
|
+
return [self.__coeffs[e] for e in self.exponents()]
|
|
180
|
+
else:
|
|
181
|
+
zero = self.parent().base_ring().zero()
|
|
182
|
+
return [self.__coeffs[i] if i in self.__coeffs else zero
|
|
183
|
+
for i in range(self.degree() + 1)]
|
|
184
|
+
|
|
185
|
+
def exponents(self):
|
|
186
|
+
"""
|
|
187
|
+
Return the exponents of the monomials appearing in ``self``.
|
|
188
|
+
|
|
189
|
+
EXAMPLES::
|
|
190
|
+
|
|
191
|
+
sage: R.<w> = PolynomialRing(Integers(8), sparse=True)
|
|
192
|
+
sage: f = 5 + w^1997 - w^10000; f
|
|
193
|
+
7*w^10000 + w^1997 + 5
|
|
194
|
+
sage: f.exponents()
|
|
195
|
+
[0, 1997, 10000]
|
|
196
|
+
"""
|
|
197
|
+
return sorted(self.__coeffs)
|
|
198
|
+
|
|
199
|
+
def valuation(self, p=None):
|
|
200
|
+
"""
|
|
201
|
+
Return the valuation of ``self``.
|
|
202
|
+
|
|
203
|
+
EXAMPLES::
|
|
204
|
+
|
|
205
|
+
sage: # needs sage.rings.finite_rings
|
|
206
|
+
sage: R.<w> = PolynomialRing(GF(9, 'a'), sparse=True)
|
|
207
|
+
sage: f = w^1997 - w^10000
|
|
208
|
+
sage: f.valuation()
|
|
209
|
+
1997
|
|
210
|
+
sage: R(19).valuation()
|
|
211
|
+
0
|
|
212
|
+
sage: R(0).valuation()
|
|
213
|
+
+Infinity
|
|
214
|
+
"""
|
|
215
|
+
if not self.__coeffs:
|
|
216
|
+
return infinity
|
|
217
|
+
|
|
218
|
+
if p is infinity:
|
|
219
|
+
return -self.degree()
|
|
220
|
+
|
|
221
|
+
if p is not None:
|
|
222
|
+
raise NotImplementedError("input p is not support for sparse polynomials")
|
|
223
|
+
|
|
224
|
+
return ZZ(min(self.__coeffs))
|
|
225
|
+
|
|
226
|
+
def _derivative(self, var=None):
|
|
227
|
+
"""
|
|
228
|
+
Return the formal derivative of this polynomial with respect to
|
|
229
|
+
the given variable.
|
|
230
|
+
|
|
231
|
+
If ``var`` is ``None`` or is the generator of this ring, the
|
|
232
|
+
derivative is with respect to the generator. Otherwise,
|
|
233
|
+
_derivative(var) is called recursively for each coefficient of
|
|
234
|
+
this polynomial.
|
|
235
|
+
|
|
236
|
+
.. SEEALSO:: :meth:`.derivative`
|
|
237
|
+
|
|
238
|
+
EXAMPLES::
|
|
239
|
+
|
|
240
|
+
sage: R.<w> = PolynomialRing(ZZ, sparse=True)
|
|
241
|
+
sage: f = R(range(9)); f
|
|
242
|
+
8*w^8 + 7*w^7 + 6*w^6 + 5*w^5 + 4*w^4 + 3*w^3 + 2*w^2 + w
|
|
243
|
+
sage: f._derivative()
|
|
244
|
+
64*w^7 + 49*w^6 + 36*w^5 + 25*w^4 + 16*w^3 + 9*w^2 + 4*w + 1
|
|
245
|
+
sage: f._derivative(w)
|
|
246
|
+
64*w^7 + 49*w^6 + 36*w^5 + 25*w^4 + 16*w^3 + 9*w^2 + 4*w + 1
|
|
247
|
+
|
|
248
|
+
sage: R.<x> = PolynomialRing(ZZ)
|
|
249
|
+
sage: S.<y> = PolynomialRing(R, sparse=True)
|
|
250
|
+
sage: f = x^3*y^4
|
|
251
|
+
sage: f._derivative()
|
|
252
|
+
4*x^3*y^3
|
|
253
|
+
sage: f._derivative(y)
|
|
254
|
+
4*x^3*y^3
|
|
255
|
+
sage: f._derivative(x)
|
|
256
|
+
3*x^2*y^4
|
|
257
|
+
|
|
258
|
+
Check that :issue:`28187` is fixed::
|
|
259
|
+
|
|
260
|
+
sage: R = PolynomialRing(ZZ, 't', sparse=True)
|
|
261
|
+
sage: t, u = var('t, u') # needs sage.symbolic
|
|
262
|
+
sage: R.gen()._derivative(t) # needs sage.symbolic
|
|
263
|
+
1
|
|
264
|
+
sage: R.gen()._derivative(u) # needs sage.symbolic
|
|
265
|
+
Traceback (most recent call last):
|
|
266
|
+
...
|
|
267
|
+
ValueError: cannot differentiate with respect to u
|
|
268
|
+
"""
|
|
269
|
+
P = self.parent()
|
|
270
|
+
if var is not None and var != P.gen():
|
|
271
|
+
try:
|
|
272
|
+
# call _derivative() recursively on coefficients
|
|
273
|
+
return P({n:self.__coeffs[n]._derivative(var)
|
|
274
|
+
for n in self.__coeffs})
|
|
275
|
+
except AttributeError:
|
|
276
|
+
raise ValueError('cannot differentiate with respect to {}'.format(var))
|
|
277
|
+
|
|
278
|
+
# compute formal derivative with respect to generator
|
|
279
|
+
d = {}
|
|
280
|
+
for n, c in self.__coeffs.items():
|
|
281
|
+
d[n-1] = n*c
|
|
282
|
+
if -1 in d:
|
|
283
|
+
del d[-1]
|
|
284
|
+
return P(d)
|
|
285
|
+
|
|
286
|
+
def integral(self, var=None):
|
|
287
|
+
"""
|
|
288
|
+
Return the integral of this polynomial.
|
|
289
|
+
|
|
290
|
+
By default, the integration variable is the variable of the
|
|
291
|
+
polynomial.
|
|
292
|
+
|
|
293
|
+
Otherwise, the integration variable is the optional parameter ``var``
|
|
294
|
+
|
|
295
|
+
.. NOTE::
|
|
296
|
+
|
|
297
|
+
The integral is always chosen so that the constant term is 0.
|
|
298
|
+
|
|
299
|
+
EXAMPLES::
|
|
300
|
+
|
|
301
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
302
|
+
sage: (1 + 3*x^10 - 2*x^100).integral()
|
|
303
|
+
-2/101*x^101 + 3/11*x^11 + x
|
|
304
|
+
|
|
305
|
+
TESTS:
|
|
306
|
+
|
|
307
|
+
Check that :issue:`18600` is fixed::
|
|
308
|
+
|
|
309
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
310
|
+
sage: (x^2^100).integral()
|
|
311
|
+
1/1267650600228229401496703205377*x^1267650600228229401496703205377
|
|
312
|
+
|
|
313
|
+
Check the correctness when the base ring is a polynomial ring::
|
|
314
|
+
|
|
315
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
316
|
+
sage: S.<t> = PolynomialRing(R, sparse=True)
|
|
317
|
+
sage: (x*t+1).integral()
|
|
318
|
+
1/2*x*t^2 + t
|
|
319
|
+
sage: (x*t+1).integral(x)
|
|
320
|
+
1/2*x^2*t + x
|
|
321
|
+
|
|
322
|
+
Check the correctness when the base ring is not an integral domain::
|
|
323
|
+
|
|
324
|
+
sage: R.<x> = PolynomialRing(Zmod(4), sparse=True)
|
|
325
|
+
sage: (x^4 + 2*x^2 + 3).integral()
|
|
326
|
+
x^5 + 2*x^3 + 3*x
|
|
327
|
+
sage: x.integral()
|
|
328
|
+
Traceback (most recent call last):
|
|
329
|
+
...
|
|
330
|
+
ZeroDivisionError: inverse of Mod(2, 4) does not exist
|
|
331
|
+
"""
|
|
332
|
+
R = self.parent()
|
|
333
|
+
# TODO:
|
|
334
|
+
# calling the coercion model bin_op is much more accurate than using the
|
|
335
|
+
# true division (which is bypassed by polynomials). But it does not work
|
|
336
|
+
# in all cases!!
|
|
337
|
+
from sage.structure.element import coercion_model as cm
|
|
338
|
+
import operator
|
|
339
|
+
try:
|
|
340
|
+
Q = cm.bin_op(R.one(), ZZ.one(), operator.truediv).parent()
|
|
341
|
+
except TypeError:
|
|
342
|
+
F = (R.base_ring().one()/ZZ.one()).parent()
|
|
343
|
+
Q = R.change_ring(F)
|
|
344
|
+
|
|
345
|
+
if var is not None and var != R.gen():
|
|
346
|
+
return Q({k:v.integral(var) for k,v in self.__coeffs.items()}, check=False)
|
|
347
|
+
|
|
348
|
+
return Q({ k+1:v/(k+1) for k,v in self.__coeffs.items()}, check=False)
|
|
349
|
+
|
|
350
|
+
def _dict_unsafe(self):
|
|
351
|
+
"""
|
|
352
|
+
Return unsafe access to the underlying dictionary of coefficients.
|
|
353
|
+
|
|
354
|
+
** DO NOT use this, unless you really really know what you are doing. **
|
|
355
|
+
|
|
356
|
+
EXAMPLES::
|
|
357
|
+
|
|
358
|
+
sage: R.<w> = PolynomialRing(ZZ, sparse=True)
|
|
359
|
+
sage: f = w^15 - w*3; f
|
|
360
|
+
w^15 - 3*w
|
|
361
|
+
sage: d = f._dict_unsafe(); d
|
|
362
|
+
{1: -3, 15: 1}
|
|
363
|
+
sage: d[1] = 10; f
|
|
364
|
+
w^15 + 10*w
|
|
365
|
+
"""
|
|
366
|
+
return self.__coeffs
|
|
367
|
+
|
|
368
|
+
def _repr(self, name=None):
|
|
369
|
+
r"""
|
|
370
|
+
EXAMPLES::
|
|
371
|
+
|
|
372
|
+
sage: # needs sage.rings.complex_double sage.symbolic
|
|
373
|
+
sage: R.<w> = PolynomialRing(CDF, sparse=True)
|
|
374
|
+
sage: f = CDF(1,2) + w^5 - CDF(pi)*w + CDF(e)
|
|
375
|
+
sage: f._repr() # abs tol 1e-15
|
|
376
|
+
'1.0*w^5 - 3.141592653589793*w + 3.718281828459045 + 2.0*I'
|
|
377
|
+
sage: f._repr(name='z') # abs tol 1e-15
|
|
378
|
+
'1.0*z^5 - 3.141592653589793*z + 3.718281828459045 + 2.0*I'
|
|
379
|
+
|
|
380
|
+
TESTS::
|
|
381
|
+
|
|
382
|
+
sage: pol = RIF['x']([0, 0, (-1,1)]) # needs sage.rings.real_interval_field
|
|
383
|
+
sage: PolynomialRing(RIF, 'x', sparse=True)(pol) # needs sage.rings.real_interval_field
|
|
384
|
+
0.?*x^2
|
|
385
|
+
|
|
386
|
+
AUTHOR:
|
|
387
|
+
|
|
388
|
+
- David Harvey (2006-08-05), based on Polynomial._repr()
|
|
389
|
+
- Francis Clarke (2008-09-08) improved for 'negative' coefficients
|
|
390
|
+
"""
|
|
391
|
+
s = " "
|
|
392
|
+
m = self.degree() + 1
|
|
393
|
+
if name is None:
|
|
394
|
+
name = self.parent().variable_name()
|
|
395
|
+
atomic_repr = self.parent().base_ring()._repr_option('element_is_atomic')
|
|
396
|
+
coeffs = sorted(self.__coeffs.items())
|
|
397
|
+
for (n, x) in reversed(coeffs):
|
|
398
|
+
if x:
|
|
399
|
+
if n != m-1:
|
|
400
|
+
s += " + "
|
|
401
|
+
x = y = repr(x)
|
|
402
|
+
if y.find("-") == 0:
|
|
403
|
+
y = y[1:]
|
|
404
|
+
if not atomic_repr and n > 0 and (y.find("+") != -1 or y.find("-") != -1):
|
|
405
|
+
x = "(%s)" % x
|
|
406
|
+
if n > 1:
|
|
407
|
+
var = "*%s^%s" % (name,n)
|
|
408
|
+
elif n == 1:
|
|
409
|
+
var = "*%s" % name
|
|
410
|
+
else:
|
|
411
|
+
var = ""
|
|
412
|
+
s += "%s%s" % (x,var)
|
|
413
|
+
s = s.replace(" + -", " - ")
|
|
414
|
+
s = s.replace(" 1*"," ")
|
|
415
|
+
s = s.replace(" -1*", " -")
|
|
416
|
+
if s == " ":
|
|
417
|
+
return "0"
|
|
418
|
+
return s[1:]
|
|
419
|
+
|
|
420
|
+
def __normalize(self):
|
|
421
|
+
x = self.__coeffs
|
|
422
|
+
D = [n for n, z in x.items() if not z]
|
|
423
|
+
for n in D:
|
|
424
|
+
del x[n]
|
|
425
|
+
|
|
426
|
+
def __getitem__(self, n):
|
|
427
|
+
"""
|
|
428
|
+
Return the `n`-th coefficient of this polynomial.
|
|
429
|
+
|
|
430
|
+
Negative indexes are allowed and always return 0 (so you can
|
|
431
|
+
view the polynomial as embedding Laurent series).
|
|
432
|
+
|
|
433
|
+
EXAMPLES::
|
|
434
|
+
|
|
435
|
+
sage: # needs sage.symbolic
|
|
436
|
+
sage: R.<w> = PolynomialRing(RDF, sparse=True)
|
|
437
|
+
sage: e = RDF(e)
|
|
438
|
+
sage: f = sum(e^n*w^n for n in range(4)); f # abs tol 1.1e-14
|
|
439
|
+
20.085536923187664*w^3 + 7.3890560989306495*w^2 + 2.718281828459045*w + 1.0
|
|
440
|
+
sage: f[1] # abs tol 5e-16
|
|
441
|
+
2.718281828459045
|
|
442
|
+
sage: f[5]
|
|
443
|
+
0.0
|
|
444
|
+
sage: f[-1]
|
|
445
|
+
0.0
|
|
446
|
+
|
|
447
|
+
sage: R.<x> = PolynomialRing(RealField(19), sparse=True) # needs sage.rings.real_mpfr
|
|
448
|
+
sage: f = (2-3.5*x)^3; f # needs sage.rings.real_mpfr
|
|
449
|
+
-42.875*x^3 + 73.500*x^2 - 42.000*x + 8.0000
|
|
450
|
+
|
|
451
|
+
Using slices, we can truncate polynomials::
|
|
452
|
+
|
|
453
|
+
sage: f[:2] # needs sage.rings.real_mpfr
|
|
454
|
+
-42.000*x + 8.0000
|
|
455
|
+
|
|
456
|
+
Any other kind of slicing is an error, see :issue:`18940`::
|
|
457
|
+
|
|
458
|
+
sage: f[1:3] # needs sage.rings.real_mpfr
|
|
459
|
+
Traceback (most recent call last):
|
|
460
|
+
...
|
|
461
|
+
IndexError: polynomial slicing with a start is not defined
|
|
462
|
+
|
|
463
|
+
sage: f[1:3:2] # needs sage.rings.real_mpfr
|
|
464
|
+
Traceback (most recent call last):
|
|
465
|
+
...
|
|
466
|
+
IndexError: polynomial slicing with a step is not defined
|
|
467
|
+
|
|
468
|
+
TESTS::
|
|
469
|
+
|
|
470
|
+
sage: f["hello"] # needs sage.rings.real_mpfr
|
|
471
|
+
Traceback (most recent call last):
|
|
472
|
+
...
|
|
473
|
+
TypeError: list indices must be integers, not str
|
|
474
|
+
"""
|
|
475
|
+
if isinstance(n, slice):
|
|
476
|
+
start, stop, step = n.start, n.stop, n.step
|
|
477
|
+
if step is not None:
|
|
478
|
+
raise IndexError("polynomial slicing with a step is not defined")
|
|
479
|
+
if start is not None:
|
|
480
|
+
raise IndexError("polynomial slicing with a start is not defined")
|
|
481
|
+
d = self.degree() + 1
|
|
482
|
+
if stop is None or stop > d:
|
|
483
|
+
stop = d
|
|
484
|
+
v = {key: val for key, val in self.__coeffs.items()
|
|
485
|
+
if key < stop}
|
|
486
|
+
return self.parent()(v)
|
|
487
|
+
|
|
488
|
+
try:
|
|
489
|
+
n = n.__index__()
|
|
490
|
+
except AttributeError:
|
|
491
|
+
raise TypeError("list indices must be integers, not {0}".format(type(n).__name__))
|
|
492
|
+
try:
|
|
493
|
+
return self.__coeffs[n]
|
|
494
|
+
except KeyError:
|
|
495
|
+
return self.base_ring().zero()
|
|
496
|
+
|
|
497
|
+
def _unsafe_mutate(self, n, value):
|
|
498
|
+
r"""
|
|
499
|
+
Change the coefficient of `x^n` to value.
|
|
500
|
+
|
|
501
|
+
** NEVER USE THIS ** -- unless you really know what you are doing.
|
|
502
|
+
|
|
503
|
+
EXAMPLES::
|
|
504
|
+
|
|
505
|
+
sage: # needs sage.rings.real_mpfr
|
|
506
|
+
sage: R.<z> = PolynomialRing(CC, sparse=True)
|
|
507
|
+
sage: f = z^2 + CC.0; f
|
|
508
|
+
1.00000000000000*z^2 + 1.00000000000000*I
|
|
509
|
+
sage: f._unsafe_mutate(0, 10)
|
|
510
|
+
sage: f
|
|
511
|
+
1.00000000000000*z^2 + 10.0000000000000
|
|
512
|
+
|
|
513
|
+
Much more nasty::
|
|
514
|
+
|
|
515
|
+
sage: z._unsafe_mutate(1, 0) # needs sage.rings.real_mpfr
|
|
516
|
+
sage: z # needs sage.rings.real_mpfr
|
|
517
|
+
0
|
|
518
|
+
"""
|
|
519
|
+
n = int(n)
|
|
520
|
+
value = self.base_ring()(value)
|
|
521
|
+
x = self.__coeffs
|
|
522
|
+
if n < 0:
|
|
523
|
+
raise IndexError("polynomial coefficient index must be nonnegative")
|
|
524
|
+
if value == 0:
|
|
525
|
+
if n in x:
|
|
526
|
+
del x[n]
|
|
527
|
+
else:
|
|
528
|
+
x[n] = value
|
|
529
|
+
|
|
530
|
+
def list(self, copy=True):
|
|
531
|
+
"""
|
|
532
|
+
Return a new copy of the list of the underlying
|
|
533
|
+
elements of ``self``.
|
|
534
|
+
|
|
535
|
+
EXAMPLES::
|
|
536
|
+
|
|
537
|
+
sage: R.<z> = PolynomialRing(Integers(100), sparse=True)
|
|
538
|
+
sage: f = 13*z^5 + 15*z^2 + 17*z
|
|
539
|
+
sage: f.list()
|
|
540
|
+
[0, 17, 15, 0, 0, 13]
|
|
541
|
+
"""
|
|
542
|
+
zero = self.base_ring().zero()
|
|
543
|
+
v = [zero] * (self.degree()+1)
|
|
544
|
+
for n, x in self.__coeffs.items():
|
|
545
|
+
v[n] = x
|
|
546
|
+
return v
|
|
547
|
+
|
|
548
|
+
def degree(self, gen=None):
|
|
549
|
+
"""
|
|
550
|
+
Return the degree of this sparse polynomial.
|
|
551
|
+
|
|
552
|
+
EXAMPLES::
|
|
553
|
+
|
|
554
|
+
sage: R.<z> = PolynomialRing(ZZ, sparse=True)
|
|
555
|
+
sage: f = 13*z^50000 + 15*z^2 + 17*z
|
|
556
|
+
sage: f.degree()
|
|
557
|
+
50000
|
|
558
|
+
"""
|
|
559
|
+
if not self.__coeffs:
|
|
560
|
+
return -1
|
|
561
|
+
return max(self.__coeffs)
|
|
562
|
+
|
|
563
|
+
def __floordiv__(self, right):
|
|
564
|
+
"""
|
|
565
|
+
Return the quotient upon division (no remainder).
|
|
566
|
+
|
|
567
|
+
EXAMPLES::
|
|
568
|
+
|
|
569
|
+
sage: # needs sage.rings.number_field
|
|
570
|
+
sage: R.<x> = PolynomialRing(QQbar, sparse=True)
|
|
571
|
+
sage: f = (1+2*x)^3 + 3*x; f
|
|
572
|
+
8*x^3 + 12*x^2 + 9*x + 1
|
|
573
|
+
sage: g = f // (1+2*x); g
|
|
574
|
+
4*x^2 + 4*x + 5/2
|
|
575
|
+
sage: f - g * (1+2*x)
|
|
576
|
+
-3/2
|
|
577
|
+
sage: f.quo_rem(1+2*x)
|
|
578
|
+
(4*x^2 + 4*x + 5/2, -3/2)
|
|
579
|
+
"""
|
|
580
|
+
P = self.parent()
|
|
581
|
+
if P is parent(right):
|
|
582
|
+
return self._floordiv_(right)
|
|
583
|
+
d = P.base_ring()(right)
|
|
584
|
+
return self.map_coefficients(lambda c: c // d)
|
|
585
|
+
|
|
586
|
+
def _add_(self, right):
|
|
587
|
+
r"""
|
|
588
|
+
EXAMPLES::
|
|
589
|
+
|
|
590
|
+
sage: R.<x> = PolynomialRing(Integers(), sparse=True)
|
|
591
|
+
sage: (x^100000 + 2*x^50000) + (4*x^75000 - 2*x^50000 + 3*x)
|
|
592
|
+
x^100000 + 4*x^75000 + 3*x
|
|
593
|
+
|
|
594
|
+
AUTHOR:
|
|
595
|
+
|
|
596
|
+
- David Harvey (2006-08-05)
|
|
597
|
+
"""
|
|
598
|
+
output = dict(self.__coeffs)
|
|
599
|
+
|
|
600
|
+
for (index, coeff) in right.__coeffs.items():
|
|
601
|
+
if index in output:
|
|
602
|
+
output[index] += coeff
|
|
603
|
+
else:
|
|
604
|
+
output[index] = coeff
|
|
605
|
+
|
|
606
|
+
output = self.parent()(output, check=False)
|
|
607
|
+
output.__normalize()
|
|
608
|
+
return output
|
|
609
|
+
|
|
610
|
+
def _neg_(self):
|
|
611
|
+
r"""
|
|
612
|
+
EXAMPLES::
|
|
613
|
+
|
|
614
|
+
sage: R.<x> = PolynomialRing(Integers(), sparse=True)
|
|
615
|
+
sage: a = x^10000000; a
|
|
616
|
+
x^10000000
|
|
617
|
+
sage: -a
|
|
618
|
+
-x^10000000
|
|
619
|
+
"""
|
|
620
|
+
output = { }
|
|
621
|
+
for (index, coeff) in self.__coeffs.items():
|
|
622
|
+
output[index] = -coeff
|
|
623
|
+
output = self.parent()(output, check=False)
|
|
624
|
+
return output
|
|
625
|
+
|
|
626
|
+
def _mul_(self, right):
|
|
627
|
+
r"""
|
|
628
|
+
EXAMPLES::
|
|
629
|
+
|
|
630
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
631
|
+
sage: (x^100000 - x^50000) * (x^100000 + x^50000)
|
|
632
|
+
x^200000 - x^100000
|
|
633
|
+
sage: (x^100000 - x^50000) * R(0)
|
|
634
|
+
0
|
|
635
|
+
|
|
636
|
+
AUTHOR:
|
|
637
|
+
- David Harvey (2006-08-05)
|
|
638
|
+
"""
|
|
639
|
+
output = {}
|
|
640
|
+
|
|
641
|
+
for (index1, coeff1) in self.__coeffs.items():
|
|
642
|
+
for (index2, coeff2) in right.__coeffs.items():
|
|
643
|
+
product = coeff1 * coeff2
|
|
644
|
+
index = index1 + index2
|
|
645
|
+
if index in output:
|
|
646
|
+
output[index] += product
|
|
647
|
+
else:
|
|
648
|
+
output[index] = product
|
|
649
|
+
|
|
650
|
+
output = self.parent()(output, check=False)
|
|
651
|
+
output.__normalize()
|
|
652
|
+
return output
|
|
653
|
+
|
|
654
|
+
def _rmul_(self, left):
|
|
655
|
+
r"""
|
|
656
|
+
EXAMPLES::
|
|
657
|
+
|
|
658
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
659
|
+
sage: (x^100000 - x^50000) * (x^100000 + x^50000)
|
|
660
|
+
x^200000 - x^100000
|
|
661
|
+
sage: 7 * (x^100000 - x^50000) # indirect doctest
|
|
662
|
+
7*x^100000 - 7*x^50000
|
|
663
|
+
|
|
664
|
+
AUTHOR:
|
|
665
|
+
|
|
666
|
+
- Simon King (2011-03-31)
|
|
667
|
+
"""
|
|
668
|
+
output = {}
|
|
669
|
+
|
|
670
|
+
for (index, coeff) in self.__coeffs.items():
|
|
671
|
+
output[index] = left * coeff
|
|
672
|
+
|
|
673
|
+
output = self.parent()(output, check=False)
|
|
674
|
+
output.__normalize()
|
|
675
|
+
return output
|
|
676
|
+
|
|
677
|
+
def _lmul_(self, right):
|
|
678
|
+
r"""
|
|
679
|
+
EXAMPLES::
|
|
680
|
+
|
|
681
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
682
|
+
sage: (x^100000 - x^50000) * (x^100000 + x^50000)
|
|
683
|
+
x^200000 - x^100000
|
|
684
|
+
sage: (x^100000 - x^50000) * 7 # indirect doctest
|
|
685
|
+
7*x^100000 - 7*x^50000
|
|
686
|
+
|
|
687
|
+
AUTHOR:
|
|
688
|
+
|
|
689
|
+
- Simon King (2011-03-31)
|
|
690
|
+
"""
|
|
691
|
+
output = {}
|
|
692
|
+
|
|
693
|
+
for (index, coeff) in self.__coeffs.items():
|
|
694
|
+
output[index] = coeff * right
|
|
695
|
+
|
|
696
|
+
output = self.parent()(output, check=False)
|
|
697
|
+
output.__normalize()
|
|
698
|
+
return output
|
|
699
|
+
|
|
700
|
+
def _richcmp_(self, other, op):
|
|
701
|
+
"""
|
|
702
|
+
Compare this polynomial with other.
|
|
703
|
+
|
|
704
|
+
Polynomials are first compared by degree, then in dictionary order
|
|
705
|
+
starting with the coefficient of largest degree.
|
|
706
|
+
|
|
707
|
+
EXAMPLES::
|
|
708
|
+
|
|
709
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
710
|
+
sage: 3*x^100 - 12 > 12*x + 5
|
|
711
|
+
True
|
|
712
|
+
sage: 3*x^100 - 12 > 3*x^100 - x^50 + 5
|
|
713
|
+
True
|
|
714
|
+
sage: 3*x^100 - 12 < 3*x^100 - x^50 + 5
|
|
715
|
+
False
|
|
716
|
+
sage: x^100 + x^10 - 1 < x^100 + x^10
|
|
717
|
+
True
|
|
718
|
+
sage: x^100 < x^100 - x^10
|
|
719
|
+
False
|
|
720
|
+
|
|
721
|
+
TESTS::
|
|
722
|
+
|
|
723
|
+
sage: R.<x> = PolynomialRing(QQ, sparse=True)
|
|
724
|
+
sage: 2*x^2^500 > x^2^500
|
|
725
|
+
True
|
|
726
|
+
|
|
727
|
+
sage: Rd = PolynomialRing(ZZ, 'x', sparse=False)
|
|
728
|
+
sage: Rs = PolynomialRing(ZZ, 'x', sparse=True)
|
|
729
|
+
sage: for _ in range(100):
|
|
730
|
+
....: pd = Rd.random_element()
|
|
731
|
+
....: qd = Rd.random_element()
|
|
732
|
+
....: assert bool(pd < qd) == bool(Rs(pd) < Rs(qd))
|
|
733
|
+
"""
|
|
734
|
+
d1 = self.degree()
|
|
735
|
+
d2 = other.degree()
|
|
736
|
+
|
|
737
|
+
# Special case constant polynomials
|
|
738
|
+
if d1 <= 0 and d2 <= 0:
|
|
739
|
+
return richcmp(self[0], other[0], op)
|
|
740
|
+
|
|
741
|
+
# For different degrees, compare the degree
|
|
742
|
+
if d1 != d2:
|
|
743
|
+
return rich_to_bool_sgn(op, d1 - d2)
|
|
744
|
+
|
|
745
|
+
degs = set(self.__coeffs) | set(other.__coeffs)
|
|
746
|
+
for i in sorted(degs, reverse=True):
|
|
747
|
+
x = self[i]
|
|
748
|
+
y = other[i]
|
|
749
|
+
res = richcmp_item(x, y, op)
|
|
750
|
+
if res is not NotImplemented:
|
|
751
|
+
return res
|
|
752
|
+
return rich_to_bool(op, 0)
|
|
753
|
+
|
|
754
|
+
def shift(self, n):
|
|
755
|
+
r"""
|
|
756
|
+
Return this polynomial multiplied by the power `x^n`.
|
|
757
|
+
|
|
758
|
+
If `n` is negative, terms below `x^n` will be discarded. Does
|
|
759
|
+
not change this polynomial.
|
|
760
|
+
|
|
761
|
+
EXAMPLES::
|
|
762
|
+
|
|
763
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
764
|
+
sage: p = x^100000 + 2*x + 4
|
|
765
|
+
sage: type(p)
|
|
766
|
+
<class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain_with_category.element_class'>
|
|
767
|
+
sage: p.shift(0)
|
|
768
|
+
x^100000 + 2*x + 4
|
|
769
|
+
sage: p.shift(-1)
|
|
770
|
+
x^99999 + 2
|
|
771
|
+
sage: p.shift(-100002)
|
|
772
|
+
0
|
|
773
|
+
sage: p.shift(2)
|
|
774
|
+
x^100002 + 2*x^3 + 4*x^2
|
|
775
|
+
|
|
776
|
+
TESTS:
|
|
777
|
+
|
|
778
|
+
Check that :issue:`18600` is fixed::
|
|
779
|
+
|
|
780
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
781
|
+
sage: p = x^2^100 - 5
|
|
782
|
+
sage: p.shift(10)
|
|
783
|
+
x^1267650600228229401496703205386 - 5*x^10
|
|
784
|
+
sage: p.shift(-10)
|
|
785
|
+
x^1267650600228229401496703205366
|
|
786
|
+
sage: p.shift(1.5) # needs sage.rings.real_mpfr
|
|
787
|
+
Traceback (most recent call last):
|
|
788
|
+
...
|
|
789
|
+
TypeError: Attempt to coerce non-integral RealNumber to Integer
|
|
790
|
+
|
|
791
|
+
AUTHOR:
|
|
792
|
+
- David Harvey (2006-08-06)
|
|
793
|
+
"""
|
|
794
|
+
n = ZZ(n)
|
|
795
|
+
if n == 0:
|
|
796
|
+
return self
|
|
797
|
+
if n > 0:
|
|
798
|
+
output = {index+n: coeff for index, coeff in self.__coeffs.items()}
|
|
799
|
+
return self.parent()(output, check=False)
|
|
800
|
+
if n < 0:
|
|
801
|
+
output = {index+n:coeff for index, coeff in self.__coeffs.items() if index + n >= 0}
|
|
802
|
+
return self.parent()(output, check=False)
|
|
803
|
+
|
|
804
|
+
@coerce_binop
|
|
805
|
+
def quo_rem(self, other):
|
|
806
|
+
"""
|
|
807
|
+
Return the quotient and remainder of the Euclidean division of
|
|
808
|
+
``self`` and ``other``.
|
|
809
|
+
|
|
810
|
+
Raises :exc:`ZeroDivisionError` if ``other`` is zero.
|
|
811
|
+
|
|
812
|
+
Raises :exc:`ArithmeticError` if ``other`` has a nonunit leading
|
|
813
|
+
coefficient and this causes the Euclidean division to fail.
|
|
814
|
+
|
|
815
|
+
EXAMPLES::
|
|
816
|
+
|
|
817
|
+
sage: P.<x> = PolynomialRing(ZZ, sparse=True)
|
|
818
|
+
sage: R.<y> = PolynomialRing(P, sparse=True)
|
|
819
|
+
sage: f = R.random_element(10)
|
|
820
|
+
sage: while x.divides(f.leading_coefficient()):
|
|
821
|
+
....: f = R.random_element(10)
|
|
822
|
+
sage: g = y^5 + R.random_element(4)
|
|
823
|
+
sage: q, r = f.quo_rem(g)
|
|
824
|
+
sage: f == q*g + r and r.degree() < g.degree()
|
|
825
|
+
True
|
|
826
|
+
sage: g = x*y^5
|
|
827
|
+
sage: f.quo_rem(g)
|
|
828
|
+
Traceback (most recent call last):
|
|
829
|
+
...
|
|
830
|
+
ArithmeticError: Division non exact
|
|
831
|
+
(consider coercing to polynomials over the fraction field)
|
|
832
|
+
sage: g = 0
|
|
833
|
+
sage: f.quo_rem(g)
|
|
834
|
+
Traceback (most recent call last):
|
|
835
|
+
...
|
|
836
|
+
ZeroDivisionError: Division by zero polynomial
|
|
837
|
+
|
|
838
|
+
If the leading coefficient of ``other`` is not a unit, Euclidean division may still work::
|
|
839
|
+
|
|
840
|
+
sage: f = -x*y^10 + 2*x*y^7 + y^3 - 2*x^2*y^2 - y
|
|
841
|
+
sage: g = x*y^5
|
|
842
|
+
sage: f.quo_rem(g)
|
|
843
|
+
(-y^5 + 2*y^2, y^3 - 2*x^2*y^2 - y)
|
|
844
|
+
|
|
845
|
+
Polynomials over noncommutative rings are also allowed::
|
|
846
|
+
|
|
847
|
+
sage: # needs sage.combinat sage.libs.singular sage.modules
|
|
848
|
+
sage: HH = QuaternionAlgebra(QQ, -1, -1)
|
|
849
|
+
sage: P.<x> = PolynomialRing(HH, sparse=True)
|
|
850
|
+
sage: f = P.random_element(5)
|
|
851
|
+
sage: g = P.random_element((0, 5))
|
|
852
|
+
sage: q, r = f.quo_rem(g)
|
|
853
|
+
sage: f == q*g + r
|
|
854
|
+
True
|
|
855
|
+
|
|
856
|
+
TESTS::
|
|
857
|
+
|
|
858
|
+
sage: P.<x> = PolynomialRing(ZZ, sparse=True)
|
|
859
|
+
sage: f = x^10 - 4*x^6 - 5
|
|
860
|
+
sage: g = 17*x^22 + x^15 - 3*x^5 + 1
|
|
861
|
+
sage: q, r = g.quo_rem(f)
|
|
862
|
+
sage: g == f*q + r and r.degree() < f.degree()
|
|
863
|
+
True
|
|
864
|
+
sage: zero = P(0)
|
|
865
|
+
sage: zero.quo_rem(f)
|
|
866
|
+
(0, 0)
|
|
867
|
+
sage: Q.<y> = IntegerModRing(14)[]
|
|
868
|
+
sage: f = y^10 - 4*y^6 - 5
|
|
869
|
+
sage: g = 17*y^22 + y^15 - 3*y^5 + 1
|
|
870
|
+
sage: q, r = g.quo_rem(f)
|
|
871
|
+
sage: g == f*q + r and r.degree() < f.degree()
|
|
872
|
+
True
|
|
873
|
+
sage: f += 2*y^10 # 3 is invertible mod 14
|
|
874
|
+
sage: q, r = g.quo_rem(f)
|
|
875
|
+
sage: g == f*q + r and r.degree() < f.degree()
|
|
876
|
+
True
|
|
877
|
+
|
|
878
|
+
The following shows that :issue:`16649` is indeed fixed. ::
|
|
879
|
+
|
|
880
|
+
sage: P.<x> = PolynomialRing(ZZ, sparse=True)
|
|
881
|
+
sage: (4*x).quo_rem(2*x)
|
|
882
|
+
(2, 0)
|
|
883
|
+
|
|
884
|
+
AUTHORS:
|
|
885
|
+
|
|
886
|
+
- Bruno Grenet (2014-07-09)
|
|
887
|
+
"""
|
|
888
|
+
if other.is_zero():
|
|
889
|
+
raise ZeroDivisionError("Division by zero polynomial")
|
|
890
|
+
if self.is_zero():
|
|
891
|
+
return self, self
|
|
892
|
+
|
|
893
|
+
R = self.parent()
|
|
894
|
+
|
|
895
|
+
d = other.degree()
|
|
896
|
+
if self.degree() < d:
|
|
897
|
+
return R.zero(), self
|
|
898
|
+
|
|
899
|
+
quo = R.zero()
|
|
900
|
+
rem = self
|
|
901
|
+
|
|
902
|
+
while rem.degree() >= d:
|
|
903
|
+
try:
|
|
904
|
+
c = R(rem.leading_coefficient() * ~other.leading_coefficient())
|
|
905
|
+
except TypeError:
|
|
906
|
+
raise ArithmeticError("Division non exact (consider coercing to polynomials over the fraction field)")
|
|
907
|
+
e = rem.degree() - d
|
|
908
|
+
quo += c*R.one().shift(e)
|
|
909
|
+
# we know that the leading coefficient of rem vanishes
|
|
910
|
+
# thus we avoid doing a useless computation
|
|
911
|
+
rem = rem[:rem.degree()] - c*other[:d].shift(e)
|
|
912
|
+
return (quo,rem)
|
|
913
|
+
|
|
914
|
+
@coerce_binop
|
|
915
|
+
def gcd(self, other, algorithm=None):
|
|
916
|
+
r"""
|
|
917
|
+
Return the gcd of this polynomial and ``other``.
|
|
918
|
+
|
|
919
|
+
INPUT:
|
|
920
|
+
|
|
921
|
+
- ``other`` -- a polynomial defined over the same ring as this
|
|
922
|
+
polynomial
|
|
923
|
+
|
|
924
|
+
ALGORITHM:
|
|
925
|
+
|
|
926
|
+
Two algorithms are provided:
|
|
927
|
+
|
|
928
|
+
- ``'generic'`` -- uses the generic implementation, which depends on the
|
|
929
|
+
base ring being a UFD or a field
|
|
930
|
+
- ``'dense'`` -- the polynomials are converted to the dense
|
|
931
|
+
representation, their gcd is computed and is converted back to the
|
|
932
|
+
sparse representation
|
|
933
|
+
|
|
934
|
+
Default is ``'dense'`` for polynomials over `\ZZ` and ``'generic'`` in the
|
|
935
|
+
other cases.
|
|
936
|
+
|
|
937
|
+
EXAMPLES::
|
|
938
|
+
|
|
939
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
940
|
+
sage: p = x^6 + 7*x^5 + 8*x^4 + 6*x^3 + 2*x^2 + x + 2
|
|
941
|
+
sage: q = 2*x^4 - x^3 - 2*x^2 - 4*x - 1
|
|
942
|
+
sage: gcd(p, q)
|
|
943
|
+
x^2 + x + 1
|
|
944
|
+
sage: gcd(p, q, algorithm='dense')
|
|
945
|
+
x^2 + x + 1
|
|
946
|
+
sage: gcd(p, q, algorithm='generic')
|
|
947
|
+
x^2 + x + 1
|
|
948
|
+
sage: gcd(p, q, algorithm='foobar')
|
|
949
|
+
Traceback (most recent call last):
|
|
950
|
+
...
|
|
951
|
+
ValueError: Unknown algorithm 'foobar'
|
|
952
|
+
|
|
953
|
+
TESTS:
|
|
954
|
+
|
|
955
|
+
Check that :issue:`19676` is fixed::
|
|
956
|
+
|
|
957
|
+
sage: S.<y> = R[]
|
|
958
|
+
sage: x.gcd(y) # needs sage.libs.singular
|
|
959
|
+
1
|
|
960
|
+
sage: (6*x).gcd(9) # needs sage.libs.singular
|
|
961
|
+
3
|
|
962
|
+
|
|
963
|
+
Check that :issue:`36427` is fixed::
|
|
964
|
+
|
|
965
|
+
sage: P = PolynomialRing(ZZ, "q", sparse=True)
|
|
966
|
+
sage: q = P.gen()
|
|
967
|
+
sage: 2*q^-100
|
|
968
|
+
2/q^100
|
|
969
|
+
sage: gcd(1, q^100)
|
|
970
|
+
1
|
|
971
|
+
sage: gcd(q^0, q^100)
|
|
972
|
+
1
|
|
973
|
+
"""
|
|
974
|
+
|
|
975
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
976
|
+
|
|
977
|
+
if algorithm is None:
|
|
978
|
+
if self.base_ring() == ZZ:
|
|
979
|
+
algorithm = "dense"
|
|
980
|
+
else:
|
|
981
|
+
algorithm = "generic"
|
|
982
|
+
if algorithm == "dense":
|
|
983
|
+
S = self.parent()
|
|
984
|
+
# FLINT is faster but a bug makes the conversion extremely slow,
|
|
985
|
+
# so NTL is used in those cases where the conversion is too slow. Cf
|
|
986
|
+
# <https://groups.google.com/d/msg/sage-devel/6qhW90dgd1k/Hoq3N7fWe4QJ>
|
|
987
|
+
sd = self.degree()
|
|
988
|
+
od = other.degree()
|
|
989
|
+
if ((sd < 100 or len(self.__coeffs)/sd > .06)
|
|
990
|
+
and (od < 100 or len(other.__coeffs)/od > .06)):
|
|
991
|
+
implementation = "FLINT"
|
|
992
|
+
else:
|
|
993
|
+
implementation = "NTL"
|
|
994
|
+
try:
|
|
995
|
+
D = PolynomialRing(S.base_ring(),'x',implementation=implementation)
|
|
996
|
+
except ImportError:
|
|
997
|
+
D = PolynomialRing(S.base_ring(),'x')
|
|
998
|
+
g = D(self).gcd(D(other))
|
|
999
|
+
return S(g)
|
|
1000
|
+
elif algorithm == "generic":
|
|
1001
|
+
return Polynomial.gcd(self,other)
|
|
1002
|
+
else:
|
|
1003
|
+
raise ValueError("Unknown algorithm '%s'" % algorithm)
|
|
1004
|
+
|
|
1005
|
+
def reverse(self, degree=None):
|
|
1006
|
+
"""
|
|
1007
|
+
Return this polynomial but with the coefficients reversed.
|
|
1008
|
+
|
|
1009
|
+
If an optional degree argument is given, the coefficient list will be
|
|
1010
|
+
truncated or zero padded as necessary and the reverse polynomial will
|
|
1011
|
+
have the specified degree.
|
|
1012
|
+
|
|
1013
|
+
EXAMPLES::
|
|
1014
|
+
|
|
1015
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
1016
|
+
sage: p = x^4 + 2*x^2^100
|
|
1017
|
+
sage: p.reverse()
|
|
1018
|
+
x^1267650600228229401496703205372 + 2
|
|
1019
|
+
sage: p.reverse(10)
|
|
1020
|
+
x^6
|
|
1021
|
+
"""
|
|
1022
|
+
if degree is None:
|
|
1023
|
+
degree = self.degree()
|
|
1024
|
+
if not isinstance(degree, (int,Integer)):
|
|
1025
|
+
raise ValueError("degree argument must be a nonnegative integer, got %s" % degree)
|
|
1026
|
+
d = {degree-k: v for k,v in self.__coeffs.items() if degree >= k}
|
|
1027
|
+
return self.parent()(d, check=False)
|
|
1028
|
+
|
|
1029
|
+
def truncate(self, n):
|
|
1030
|
+
"""
|
|
1031
|
+
Return the polynomial of degree `< n` equal to ``self`` modulo `x^n`.
|
|
1032
|
+
|
|
1033
|
+
EXAMPLES::
|
|
1034
|
+
|
|
1035
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
1036
|
+
sage: (x^11 + x^10 + 1).truncate(11)
|
|
1037
|
+
x^10 + 1
|
|
1038
|
+
sage: (x^2^500 + x^2^100 + 1).truncate(2^101)
|
|
1039
|
+
x^1267650600228229401496703205376 + 1
|
|
1040
|
+
"""
|
|
1041
|
+
return self[:n]
|
|
1042
|
+
|
|
1043
|
+
def number_of_terms(self):
|
|
1044
|
+
"""
|
|
1045
|
+
Return the number of nonzero terms.
|
|
1046
|
+
|
|
1047
|
+
EXAMPLES::
|
|
1048
|
+
|
|
1049
|
+
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
|
|
1050
|
+
sage: p = x^100 - 3*x^10 + 12
|
|
1051
|
+
sage: p.number_of_terms()
|
|
1052
|
+
3
|
|
1053
|
+
"""
|
|
1054
|
+
return len(self.__coeffs)
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
class Polynomial_generic_domain(Polynomial, IntegralDomainElement):
|
|
1058
|
+
def __init__(self, parent, is_gen=False, construct=False):
|
|
1059
|
+
Polynomial.__init__(self, parent, is_gen=is_gen)
|
|
1060
|
+
|
|
1061
|
+
def is_unit(self):
|
|
1062
|
+
r"""
|
|
1063
|
+
Return ``True`` if this polynomial is a unit.
|
|
1064
|
+
|
|
1065
|
+
*EXERCISE* (Atiyah-McDonald, Ch 1): Let `A[x]` be a polynomial
|
|
1066
|
+
ring in one variable. Then `f=\sum a_i x^i \in A[x]` is a
|
|
1067
|
+
unit if and only if `a_0` is a unit and `a_1,\ldots, a_n` are
|
|
1068
|
+
nilpotent.
|
|
1069
|
+
|
|
1070
|
+
EXAMPLES::
|
|
1071
|
+
|
|
1072
|
+
sage: R.<z> = PolynomialRing(ZZ, sparse=True)
|
|
1073
|
+
sage: (2 + z^3).is_unit()
|
|
1074
|
+
False
|
|
1075
|
+
sage: f = -1 + 3*z^3; f
|
|
1076
|
+
3*z^3 - 1
|
|
1077
|
+
sage: f.is_unit()
|
|
1078
|
+
False
|
|
1079
|
+
sage: R(-3).is_unit()
|
|
1080
|
+
False
|
|
1081
|
+
sage: R(-1).is_unit()
|
|
1082
|
+
True
|
|
1083
|
+
sage: R(0).is_unit()
|
|
1084
|
+
False
|
|
1085
|
+
"""
|
|
1086
|
+
if self.degree() > 0:
|
|
1087
|
+
return False
|
|
1088
|
+
return self[0].is_unit()
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
class Polynomial_generic_field(Polynomial_singular_repr,
|
|
1092
|
+
Polynomial_generic_domain,
|
|
1093
|
+
EuclideanDomainElement):
|
|
1094
|
+
|
|
1095
|
+
@coerce_binop
|
|
1096
|
+
def quo_rem(self, other):
|
|
1097
|
+
"""
|
|
1098
|
+
Return a tuple ``(quotient, remainder)`` where
|
|
1099
|
+
``self = quotient * other + remainder``.
|
|
1100
|
+
|
|
1101
|
+
EXAMPLES::
|
|
1102
|
+
|
|
1103
|
+
sage: # needs sage.rings.number_field
|
|
1104
|
+
sage: R.<y> = PolynomialRing(QQ)
|
|
1105
|
+
sage: K.<t> = NumberField(y^2 - 2)
|
|
1106
|
+
sage: P.<x> = PolynomialRing(K)
|
|
1107
|
+
sage: x.quo_rem(K(1))
|
|
1108
|
+
(x, 0)
|
|
1109
|
+
sage: x.xgcd(K(1))
|
|
1110
|
+
(1, 0, 1)
|
|
1111
|
+
"""
|
|
1112
|
+
P = self.parent()
|
|
1113
|
+
if other.is_zero():
|
|
1114
|
+
raise ZeroDivisionError("other must be nonzero")
|
|
1115
|
+
|
|
1116
|
+
# This is algorithm 3.1.1 in Cohen GTM 138
|
|
1117
|
+
A = self
|
|
1118
|
+
B = other
|
|
1119
|
+
R = A
|
|
1120
|
+
Q = P.zero()
|
|
1121
|
+
while R.degree() >= B.degree():
|
|
1122
|
+
aaa = R.leading_coefficient()/B.leading_coefficient()
|
|
1123
|
+
diff_deg = R.degree()-B.degree()
|
|
1124
|
+
Q += P(aaa).shift(diff_deg)
|
|
1125
|
+
# We know that S*B exactly cancels the leading coefficient of R.
|
|
1126
|
+
# Thus, we skip the computation of this leading coefficient.
|
|
1127
|
+
# For most exact fields, this doesn't matter much; but for
|
|
1128
|
+
# inexact fields, the leading coefficient might not end up
|
|
1129
|
+
# exactly equal to zero; and for AA/QQbar, verifying that
|
|
1130
|
+
# the coefficient is exactly zero triggers exact computation.
|
|
1131
|
+
R = R[:R.degree()] - (aaa*B[:B.degree()]).shift(diff_deg)
|
|
1132
|
+
return (Q, R)
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
class Polynomial_generic_sparse_field(Polynomial_generic_sparse, Polynomial_generic_field):
|
|
1136
|
+
"""
|
|
1137
|
+
EXAMPLES::
|
|
1138
|
+
|
|
1139
|
+
sage: R.<x> = PolynomialRing(Frac(RR['t']), sparse=True)
|
|
1140
|
+
sage: f = x^3 - x + 17
|
|
1141
|
+
sage: type(f)
|
|
1142
|
+
<class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'>
|
|
1143
|
+
sage: loads(f.dumps()) == f
|
|
1144
|
+
True
|
|
1145
|
+
"""
|
|
1146
|
+
def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
|
|
1147
|
+
Polynomial_generic_sparse.__init__(self, parent, x, check, is_gen)
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
class Polynomial_generic_dense_field(Polynomial_generic_dense, Polynomial_generic_field):
|
|
1151
|
+
def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
|
|
1152
|
+
Polynomial_generic_dense.__init__(self, parent, x, check, is_gen)
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
##########################################
|
|
1156
|
+
# Over discrete valuation rings and fields
|
|
1157
|
+
##########################################
|
|
1158
|
+
|
|
1159
|
+
class Polynomial_generic_cdv(Polynomial_generic_domain):
|
|
1160
|
+
"""
|
|
1161
|
+
A generic class for polynomials over complete discrete
|
|
1162
|
+
valuation domains and fields.
|
|
1163
|
+
|
|
1164
|
+
AUTHOR:
|
|
1165
|
+
|
|
1166
|
+
- Xavier Caruso (2013-03)
|
|
1167
|
+
"""
|
|
1168
|
+
def newton_slopes(self, repetition=True):
|
|
1169
|
+
"""
|
|
1170
|
+
Return a list of the Newton slopes of this polynomial.
|
|
1171
|
+
|
|
1172
|
+
These are the valuations of the roots of this polynomial.
|
|
1173
|
+
|
|
1174
|
+
If ``repetition`` is ``True``, each slope is repeated a number of
|
|
1175
|
+
times equal to its multiplicity. Otherwise it appears only
|
|
1176
|
+
one time.
|
|
1177
|
+
|
|
1178
|
+
EXAMPLES::
|
|
1179
|
+
|
|
1180
|
+
sage: # needs sage.geometry.polyhedron sage.rings.padics
|
|
1181
|
+
sage: K = Qp(5)
|
|
1182
|
+
sage: R.<t> = K[]
|
|
1183
|
+
sage: f = 5 + 3*t + t^4 + 25*t^10
|
|
1184
|
+
sage: f.newton_polygon()
|
|
1185
|
+
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)
|
|
1186
|
+
sage: f.newton_slopes()
|
|
1187
|
+
[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
|
|
1188
|
+
sage: f.newton_slopes(repetition=False)
|
|
1189
|
+
[1, 0, -1/3]
|
|
1190
|
+
|
|
1191
|
+
AUTHOR:
|
|
1192
|
+
|
|
1193
|
+
- Xavier Caruso (2013-03-20)
|
|
1194
|
+
"""
|
|
1195
|
+
polygon = self.newton_polygon()
|
|
1196
|
+
return [-s for s in polygon.slopes(repetition=repetition)]
|
|
1197
|
+
|
|
1198
|
+
def newton_polygon(self):
|
|
1199
|
+
r"""
|
|
1200
|
+
Return a list of vertices of the Newton polygon of this polynomial.
|
|
1201
|
+
|
|
1202
|
+
.. NOTE::
|
|
1203
|
+
|
|
1204
|
+
If some coefficients have not enough precision an error is raised.
|
|
1205
|
+
|
|
1206
|
+
EXAMPLES::
|
|
1207
|
+
|
|
1208
|
+
sage: # needs sage.geometry.polyhedron sage.rings.padics
|
|
1209
|
+
sage: K = Qp(5)
|
|
1210
|
+
sage: R.<t> = K[]
|
|
1211
|
+
sage: f = 5 + 3*t + t^4 + 25*t^10
|
|
1212
|
+
sage: f.newton_polygon()
|
|
1213
|
+
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)
|
|
1214
|
+
sage: g = f + K(0,0)*t^4; g
|
|
1215
|
+
(5^2 + O(5^22))*t^10 + O(5^0)*t^4 + (3 + O(5^20))*t + 5 + O(5^21)
|
|
1216
|
+
sage: g.newton_polygon()
|
|
1217
|
+
Traceback (most recent call last):
|
|
1218
|
+
...
|
|
1219
|
+
PrecisionError: The coefficient of t^4 has not enough precision
|
|
1220
|
+
|
|
1221
|
+
TESTS:
|
|
1222
|
+
|
|
1223
|
+
Check that :issue:`22936` is fixed::
|
|
1224
|
+
|
|
1225
|
+
sage: S.<x> = PowerSeriesRing(GF(5))
|
|
1226
|
+
sage: R.<y> = S[]
|
|
1227
|
+
sage: p = x^2 + y + x*y^2
|
|
1228
|
+
sage: p.newton_polygon() # needs sage.geometry.polyhedron
|
|
1229
|
+
Finite Newton polygon with 3 vertices: (0, 2), (1, 0), (2, 1)
|
|
1230
|
+
|
|
1231
|
+
AUTHOR:
|
|
1232
|
+
|
|
1233
|
+
- Xavier Caruso (2013-03-20)
|
|
1234
|
+
"""
|
|
1235
|
+
d = self.degree()
|
|
1236
|
+
from sage.geometry.newton_polygon import NewtonPolygon
|
|
1237
|
+
polygon = NewtonPolygon([(x, self[x].valuation()) for x in range(d+1)])
|
|
1238
|
+
polygon_prec = NewtonPolygon([ (x, self[x].precision_absolute()) for x in range(d+1) ])
|
|
1239
|
+
vertices = polygon.vertices(copy=False)
|
|
1240
|
+
vertices_prec = polygon_prec.vertices(copy=False)
|
|
1241
|
+
if len(vertices_prec) > 0:
|
|
1242
|
+
if vertices[0][0] > vertices_prec[0][0]:
|
|
1243
|
+
raise PrecisionError("first term with non-infinite valuation must have determined valuation")
|
|
1244
|
+
elif vertices[-1][0] < vertices_prec[-1][0]:
|
|
1245
|
+
raise PrecisionError("last term with non-infinite valuation must have determined valuation")
|
|
1246
|
+
else:
|
|
1247
|
+
for (x, y) in vertices:
|
|
1248
|
+
if polygon_prec(x) <= y:
|
|
1249
|
+
raise PrecisionError("The coefficient of %s^%s has not enough precision" % (self.parent().variable_name(), x))
|
|
1250
|
+
return polygon
|
|
1251
|
+
|
|
1252
|
+
def hensel_lift(self, a):
|
|
1253
|
+
"""
|
|
1254
|
+
Lift `a` to a root of this polynomial (using
|
|
1255
|
+
Newton iteration).
|
|
1256
|
+
|
|
1257
|
+
If `a` is not close enough to a root (so that
|
|
1258
|
+
Newton iteration does not converge), an error
|
|
1259
|
+
is raised.
|
|
1260
|
+
|
|
1261
|
+
EXAMPLES::
|
|
1262
|
+
|
|
1263
|
+
sage: # needs sage.rings.padics
|
|
1264
|
+
sage: K = Qp(5, 10)
|
|
1265
|
+
sage: P.<x> = PolynomialRing(K)
|
|
1266
|
+
sage: f = x^2 + 1
|
|
1267
|
+
sage: root = f.hensel_lift(2); root
|
|
1268
|
+
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)
|
|
1269
|
+
sage: f(root)
|
|
1270
|
+
O(5^10)
|
|
1271
|
+
|
|
1272
|
+
sage: g = (x^2 + 1) * (x - 7) # needs sage.rings.padics
|
|
1273
|
+
sage: g.hensel_lift(2) # here, 2 is a multiple root modulo p # needs sage.rings.padics
|
|
1274
|
+
Traceback (most recent call last):
|
|
1275
|
+
...
|
|
1276
|
+
ValueError: a is not close enough to a root of this polynomial
|
|
1277
|
+
|
|
1278
|
+
AUTHOR:
|
|
1279
|
+
|
|
1280
|
+
- Xavier Caruso (2013-03-23)
|
|
1281
|
+
"""
|
|
1282
|
+
selfa = self(a)
|
|
1283
|
+
der = self.derivative()
|
|
1284
|
+
dera = der(a)
|
|
1285
|
+
if selfa.valuation() <= 2 * dera.valuation():
|
|
1286
|
+
raise ValueError("a is not close enough to a root of this polynomial")
|
|
1287
|
+
# Newton iteration
|
|
1288
|
+
# Todo: compute everything up to the adequate precision at each step
|
|
1289
|
+
b = ~dera
|
|
1290
|
+
while True:
|
|
1291
|
+
na = a - selfa * b
|
|
1292
|
+
if na == a:
|
|
1293
|
+
return a
|
|
1294
|
+
a = na
|
|
1295
|
+
selfa = self(a)
|
|
1296
|
+
dera = der(a)
|
|
1297
|
+
b *= 2 - dera * b
|
|
1298
|
+
|
|
1299
|
+
def _factor_of_degree(self, deg):
|
|
1300
|
+
"""
|
|
1301
|
+
Return a factor of ``self`` of degree ``deg``.
|
|
1302
|
+
|
|
1303
|
+
Algorithm is Newton iteration.
|
|
1304
|
+
|
|
1305
|
+
This fails if ``deg`` is not a breakpoint in the Newton
|
|
1306
|
+
polygon of ``self``.
|
|
1307
|
+
|
|
1308
|
+
Only for internal use!
|
|
1309
|
+
|
|
1310
|
+
EXAMPLES::
|
|
1311
|
+
|
|
1312
|
+
sage: # needs sage.rings.padics
|
|
1313
|
+
sage: K = Qp(5)
|
|
1314
|
+
sage: R.<x> = K[]
|
|
1315
|
+
sage: K = Qp(5)
|
|
1316
|
+
sage: R.<t> = K[]
|
|
1317
|
+
sage: f = 5 + 3*t + t^4 + 25*t^10
|
|
1318
|
+
|
|
1319
|
+
sage: g = f._factor_of_degree(4) # needs sage.rings.padics
|
|
1320
|
+
sage: (f % g).is_zero() # needs sage.rings.padics
|
|
1321
|
+
True
|
|
1322
|
+
|
|
1323
|
+
sage: g = f._factor_of_degree(3) # not tested # needs sage.rings.padics
|
|
1324
|
+
Traceback (most recent call last)
|
|
1325
|
+
...
|
|
1326
|
+
KeyboardInterrupt:
|
|
1327
|
+
|
|
1328
|
+
TESTS::
|
|
1329
|
+
|
|
1330
|
+
sage: S.<x> = PowerSeriesRing(GF(5))
|
|
1331
|
+
sage: R.<y> = S[]
|
|
1332
|
+
sage: p = x^2 + y + x*y^2
|
|
1333
|
+
sage: p._factor_of_degree(1)
|
|
1334
|
+
(1 + O(x^20))*y + x^2 + x^5 + 2*x^8 + 4*x^14 + 2*x^17 + 2*x^20 + O(x^22)
|
|
1335
|
+
|
|
1336
|
+
AUTHOR:
|
|
1337
|
+
|
|
1338
|
+
- Xavier Caruso (2013-03-20)
|
|
1339
|
+
|
|
1340
|
+
.. TODO::
|
|
1341
|
+
|
|
1342
|
+
Precision is not optimal, and can be improved.
|
|
1343
|
+
"""
|
|
1344
|
+
coeffs = self.list()
|
|
1345
|
+
a = coeffs[:deg+1]
|
|
1346
|
+
# The leading coefficient need to be known at finite precision
|
|
1347
|
+
# in order to ensure that the while loop below terminates
|
|
1348
|
+
if a[deg].precision_absolute() is Infinity:
|
|
1349
|
+
a[deg] = a[deg].add_bigoh(self.base_ring().default_prec())
|
|
1350
|
+
|
|
1351
|
+
parent = self.parent()
|
|
1352
|
+
a = parent(a)
|
|
1353
|
+
v = parent.one()
|
|
1354
|
+
x = self % a
|
|
1355
|
+
while not x.is_zero():
|
|
1356
|
+
a += (v * x) % a
|
|
1357
|
+
b, x = self.quo_rem(a)
|
|
1358
|
+
b %= a
|
|
1359
|
+
v = (v * (2 - b * v)) % a
|
|
1360
|
+
return a
|
|
1361
|
+
|
|
1362
|
+
def factor_of_slope(self, slope=None):
|
|
1363
|
+
"""
|
|
1364
|
+
INPUT:
|
|
1365
|
+
|
|
1366
|
+
- ``slope`` -- a rational number (default: the first slope
|
|
1367
|
+
in the Newton polygon of ``self``)
|
|
1368
|
+
|
|
1369
|
+
OUTPUT:
|
|
1370
|
+
|
|
1371
|
+
The factor of ``self`` corresponding to the slope ``slope`` (i.e.
|
|
1372
|
+
the unique monic divisor of ``self`` whose slope is ``slope`` and
|
|
1373
|
+
degree is the length of ``slope`` in the Newton polygon).
|
|
1374
|
+
|
|
1375
|
+
EXAMPLES::
|
|
1376
|
+
|
|
1377
|
+
sage: # needs sage.geometry.polyhedron sage.rings.padics
|
|
1378
|
+
sage: K = Qp(5)
|
|
1379
|
+
sage: R.<x> = K[]
|
|
1380
|
+
sage: K = Qp(5)
|
|
1381
|
+
sage: R.<t> = K[]
|
|
1382
|
+
sage: f = 5 + 3*t + t^4 + 25*t^10
|
|
1383
|
+
sage: f.newton_slopes()
|
|
1384
|
+
[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
|
|
1385
|
+
sage: g = f.factor_of_slope(0)
|
|
1386
|
+
sage: g.newton_slopes()
|
|
1387
|
+
[0, 0, 0]
|
|
1388
|
+
sage: (f % g).is_zero()
|
|
1389
|
+
True
|
|
1390
|
+
sage: h = f.factor_of_slope()
|
|
1391
|
+
sage: h.newton_slopes()
|
|
1392
|
+
[1]
|
|
1393
|
+
sage: (f % h).is_zero()
|
|
1394
|
+
True
|
|
1395
|
+
|
|
1396
|
+
If ``slope`` is not a slope of ``self``, the corresponding factor
|
|
1397
|
+
is `1`::
|
|
1398
|
+
|
|
1399
|
+
sage: f.factor_of_slope(-1) # needs sage.geometry.polyhedron sage.rings.padics
|
|
1400
|
+
1 + O(5^20)
|
|
1401
|
+
|
|
1402
|
+
AUTHOR:
|
|
1403
|
+
|
|
1404
|
+
- Xavier Caruso (2013-03-20)
|
|
1405
|
+
"""
|
|
1406
|
+
one = self.parent()(1)
|
|
1407
|
+
vertices = self.newton_polygon().vertices(copy=False)
|
|
1408
|
+
if len(vertices) < 2:
|
|
1409
|
+
if slope is Infinity:
|
|
1410
|
+
return self.parent().gen() ** self.degree()
|
|
1411
|
+
else:
|
|
1412
|
+
return one
|
|
1413
|
+
if slope is None:
|
|
1414
|
+
deg_first = vertices[0][0]
|
|
1415
|
+
deg_last = vertices[1][0]
|
|
1416
|
+
else:
|
|
1417
|
+
(deg_first, y_first) = vertices[0]
|
|
1418
|
+
for i in range(1, len(vertices)):
|
|
1419
|
+
(deg_last, y_last) = vertices[i]
|
|
1420
|
+
slope_cur = (y_first - y_last) / (deg_last - deg_first)
|
|
1421
|
+
if slope_cur == slope:
|
|
1422
|
+
break
|
|
1423
|
+
elif slope_cur < slope:
|
|
1424
|
+
return one
|
|
1425
|
+
deg_first = deg_last
|
|
1426
|
+
y_first = y_last
|
|
1427
|
+
if slope_cur > slope:
|
|
1428
|
+
return one
|
|
1429
|
+
if deg_last == self.degree():
|
|
1430
|
+
div = self
|
|
1431
|
+
else:
|
|
1432
|
+
div = self._factor_of_degree(deg_last)
|
|
1433
|
+
if deg_first > 0:
|
|
1434
|
+
div2 = div._factor_of_degree(deg_first)
|
|
1435
|
+
div,_ = div.quo_rem(div2)
|
|
1436
|
+
return div.monic()
|
|
1437
|
+
|
|
1438
|
+
def slope_factorization(self):
|
|
1439
|
+
"""
|
|
1440
|
+
Return a factorization of ``self`` into a product of factors
|
|
1441
|
+
corresponding to each slope in the Newton polygon.
|
|
1442
|
+
|
|
1443
|
+
EXAMPLES::
|
|
1444
|
+
|
|
1445
|
+
sage: # needs sage.geometry.polyhedron sage.rings.padics
|
|
1446
|
+
sage: K = Qp(5)
|
|
1447
|
+
sage: R.<x> = K[]
|
|
1448
|
+
sage: K = Qp(5)
|
|
1449
|
+
sage: R.<t> = K[]
|
|
1450
|
+
sage: f = 5 + 3*t + t^4 + 25*t^10
|
|
1451
|
+
sage: f.newton_slopes()
|
|
1452
|
+
[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
|
|
1453
|
+
sage: F = f.slope_factorization()
|
|
1454
|
+
sage: F.prod() == f
|
|
1455
|
+
True
|
|
1456
|
+
sage: for (f,_) in F:
|
|
1457
|
+
....: print(f.newton_slopes())
|
|
1458
|
+
[-1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
|
|
1459
|
+
[0, 0, 0]
|
|
1460
|
+
[1]
|
|
1461
|
+
|
|
1462
|
+
TESTS::
|
|
1463
|
+
|
|
1464
|
+
sage: S.<x> = PowerSeriesRing(GF(5))
|
|
1465
|
+
sage: R.<y> = S[]
|
|
1466
|
+
sage: p = x^2 + y + x*y^2
|
|
1467
|
+
sage: p.slope_factorization() # needs sage.geometry.polyhedron
|
|
1468
|
+
(x)
|
|
1469
|
+
* ((x + O(x^22))*y + 1 + 4*x^3 + 4*x^6 + 3*x^9 + x^15 + 3*x^18 + O(x^21))
|
|
1470
|
+
* ((x^-1 + O(x^20))*y + x + x^4 + 2*x^7 + 4*x^13 + 2*x^16 + 2*x^19 + O(x^22))
|
|
1471
|
+
|
|
1472
|
+
AUTHOR:
|
|
1473
|
+
|
|
1474
|
+
- Xavier Caruso (2013-03-20)
|
|
1475
|
+
"""
|
|
1476
|
+
vertices = self.newton_polygon().vertices(copy=False)
|
|
1477
|
+
|
|
1478
|
+
unit = self.leading_coefficient()
|
|
1479
|
+
P = ~unit * self
|
|
1480
|
+
|
|
1481
|
+
deg_first = vertices[0][0]
|
|
1482
|
+
factors = [ ]
|
|
1483
|
+
if deg_first > 0:
|
|
1484
|
+
P >>= deg_first
|
|
1485
|
+
factors.append((self._parent.gen(), deg_first))
|
|
1486
|
+
if len(vertices) > 2:
|
|
1487
|
+
for i in range(1, len(vertices)-1):
|
|
1488
|
+
deg = vertices[i][0]
|
|
1489
|
+
div = P._factor_of_degree(deg-deg_first)
|
|
1490
|
+
factors.append((div,1))
|
|
1491
|
+
P,_ = P.quo_rem(div)
|
|
1492
|
+
deg_first = deg
|
|
1493
|
+
if len(vertices) > 1:
|
|
1494
|
+
factors.append((P, 1))
|
|
1495
|
+
factors.reverse()
|
|
1496
|
+
return Factorization(factors, sort=False, unit=unit)
|
|
1497
|
+
|
|
1498
|
+
def _roots(self, secure, minval, hint):
|
|
1499
|
+
"""
|
|
1500
|
+
Return the roots of this polynomial whose valuation is
|
|
1501
|
+
at least ``minval``.
|
|
1502
|
+
|
|
1503
|
+
This is a helper method for :meth:`roots`.
|
|
1504
|
+
It is not meant to be called directly.
|
|
1505
|
+
|
|
1506
|
+
INPUT:
|
|
1507
|
+
|
|
1508
|
+
- ``secure`` -- boolean; whether we raise an error or
|
|
1509
|
+
not in case of multiple roots
|
|
1510
|
+
|
|
1511
|
+
- ``minval`` -- integer
|
|
1512
|
+
|
|
1513
|
+
- ``hint`` -- list or ``None``; if given, it must be the
|
|
1514
|
+
list of roots of the residual polynomial of slope ``minval``
|
|
1515
|
+
|
|
1516
|
+
OUTPUT: list of pairs ``(root, multiplicity)``
|
|
1517
|
+
|
|
1518
|
+
TESTS::
|
|
1519
|
+
|
|
1520
|
+
sage: # needs sage.geometry.polyhedron sage.rings.padics
|
|
1521
|
+
sage: R = Zp(2)
|
|
1522
|
+
sage: S.<x> = R[]
|
|
1523
|
+
sage: P = (x-1) * (x-2) * (x-4) * (x-8) * (x-16)
|
|
1524
|
+
sage: Q = P^2
|
|
1525
|
+
sage: Q.roots(algorithm='sage') # indirect doctest
|
|
1526
|
+
[(2^4 + O(2^14), 2),
|
|
1527
|
+
(2^3 + O(2^13), 2),
|
|
1528
|
+
(2^2 + O(2^12), 2),
|
|
1529
|
+
(2 + O(2^11), 2),
|
|
1530
|
+
(1 + O(2^10), 2)]
|
|
1531
|
+
"""
|
|
1532
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1533
|
+
K = self.base_ring()
|
|
1534
|
+
Pk = PolynomialRing(K.residue_field(), names='xbar')
|
|
1535
|
+
x = self.parent().gen()
|
|
1536
|
+
|
|
1537
|
+
# Trivial cases
|
|
1538
|
+
if self.degree() == 0:
|
|
1539
|
+
return [ ]
|
|
1540
|
+
if self.degree() == 1:
|
|
1541
|
+
return [ (-self[0]/self[1], 1) ]
|
|
1542
|
+
|
|
1543
|
+
# We consider the case where zero is a (possibly multiple) root
|
|
1544
|
+
i = 0
|
|
1545
|
+
while self[i] == 0:
|
|
1546
|
+
i += 1
|
|
1547
|
+
if secure and i > 1:
|
|
1548
|
+
raise PrecisionError("not enough precision to determine the number of roots")
|
|
1549
|
+
if i == 0:
|
|
1550
|
+
roots = [ ]
|
|
1551
|
+
P = self
|
|
1552
|
+
else:
|
|
1553
|
+
vali = self[i].valuation()
|
|
1554
|
+
prec = min((self[j].precision_absolute()-vali) / (i-j) for j in range(i))
|
|
1555
|
+
if prec is not Infinity:
|
|
1556
|
+
prec = prec.ceil()
|
|
1557
|
+
roots = [ (K(0,prec), i) ]
|
|
1558
|
+
P = self // self[:i+1] # we do not shift because we need to track precision here
|
|
1559
|
+
|
|
1560
|
+
# We use Newton polygon and slope factorisation to find roots
|
|
1561
|
+
vertices = P.newton_polygon().vertices(copy=False)
|
|
1562
|
+
deg = 0
|
|
1563
|
+
for i in range(1, len(vertices)):
|
|
1564
|
+
deg_left, val_left = vertices[i-1]
|
|
1565
|
+
deg_right, val_right = vertices[i]
|
|
1566
|
+
slope = (val_right - val_left) / (deg_left - deg_right)
|
|
1567
|
+
if slope not in ZZ or slope < minval:
|
|
1568
|
+
continue
|
|
1569
|
+
if hint is not None and slope == minval:
|
|
1570
|
+
rootsbar = hint
|
|
1571
|
+
if not rootsbar:
|
|
1572
|
+
continue
|
|
1573
|
+
if i < len(vertices) - 1:
|
|
1574
|
+
F = P._factor_of_degree(deg_right - deg)
|
|
1575
|
+
P = P // F
|
|
1576
|
+
else:
|
|
1577
|
+
F = P
|
|
1578
|
+
if deg < deg_left:
|
|
1579
|
+
G = F._factor_of_degree(deg_left - deg)
|
|
1580
|
+
F //= G
|
|
1581
|
+
deg = deg_right
|
|
1582
|
+
val = F[0].valuation()
|
|
1583
|
+
if hint is None or slope != minval:
|
|
1584
|
+
Fbar = Pk([ F[j] >> (val - j*slope) for j in range(F.degree()+1) ])
|
|
1585
|
+
rootsbar = [ r for (r, _) in Fbar.roots() ]
|
|
1586
|
+
if not rootsbar:
|
|
1587
|
+
continue
|
|
1588
|
+
rbar = rootsbar.pop()
|
|
1589
|
+
shift = K(rbar).lift_to_precision() << slope # probably we should choose a better lift
|
|
1590
|
+
roots += [(r+shift, m) for (r, m) in F(x+shift)._roots(secure, slope, [r-rbar for r in rootsbar])] # recursive call
|
|
1591
|
+
return roots
|
|
1592
|
+
|
|
1593
|
+
|
|
1594
|
+
class Polynomial_generic_dense_cdv(Polynomial_generic_dense_inexact, Polynomial_generic_cdv):
|
|
1595
|
+
pass
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
class Polynomial_generic_sparse_cdv(Polynomial_generic_sparse, Polynomial_generic_cdv):
|
|
1599
|
+
pass
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
class Polynomial_generic_cdvr(Polynomial_generic_cdv):
|
|
1603
|
+
pass
|
|
1604
|
+
|
|
1605
|
+
|
|
1606
|
+
class Polynomial_generic_dense_cdvr(Polynomial_generic_dense_cdv, Polynomial_generic_cdvr):
|
|
1607
|
+
pass
|
|
1608
|
+
|
|
1609
|
+
|
|
1610
|
+
class Polynomial_generic_sparse_cdvr(Polynomial_generic_sparse_cdv, Polynomial_generic_cdvr):
|
|
1611
|
+
pass
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
class Polynomial_generic_cdvf(Polynomial_generic_cdv, Polynomial_generic_field):
|
|
1615
|
+
pass
|
|
1616
|
+
|
|
1617
|
+
|
|
1618
|
+
class Polynomial_generic_dense_cdvf(Polynomial_generic_dense_cdv, Polynomial_generic_cdvf):
|
|
1619
|
+
pass
|
|
1620
|
+
|
|
1621
|
+
|
|
1622
|
+
class Polynomial_generic_sparse_cdvf(Polynomial_generic_sparse_cdv, Polynomial_generic_cdvf):
|
|
1623
|
+
pass
|
|
1624
|
+
|
|
1625
|
+
|
|
1626
|
+
############################################################################
|
|
1627
|
+
# XXX: Ensures that the generic polynomials implemented in Sage via PARI #
|
|
1628
|
+
# until at least until 4.5.0 unpickle correctly as polynomials implemented #
|
|
1629
|
+
# via FLINT. #
|
|
1630
|
+
try:
|
|
1631
|
+
from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint
|
|
1632
|
+
except ImportError:
|
|
1633
|
+
pass
|
|
1634
|
+
else:
|
|
1635
|
+
from sage.misc.persist import register_unpickle_override
|
|
1636
|
+
register_unpickle_override('sage.rings.polynomial.polynomial_element_generic',
|
|
1637
|
+
'Polynomial_rational_dense', Polynomial_rational_flint)
|