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,2190 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Elements of Laurent polynomial rings
|
|
4
|
+
"""
|
|
5
|
+
# ****************************************************************************
|
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
# https://www.gnu.org/licenses/
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
from sage.categories.map cimport Map
|
|
13
|
+
from sage.structure.element import coerce_binop, parent
|
|
14
|
+
from sage.structure.factorization import Factorization
|
|
15
|
+
from sage.misc.derivative import multi_derivative
|
|
16
|
+
from sage.rings.polynomial.polynomial_element import Polynomial
|
|
17
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
18
|
+
from sage.structure.richcmp cimport richcmp, rich_to_bool
|
|
19
|
+
from sage.rings.infinity import minus_infinity
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
cdef class LaurentPolynomial(CommutativeAlgebraElement):
|
|
23
|
+
"""
|
|
24
|
+
Base class for Laurent polynomials.
|
|
25
|
+
"""
|
|
26
|
+
cdef LaurentPolynomial _new_c(self):
|
|
27
|
+
"""
|
|
28
|
+
Return a new Laurent polynomial.
|
|
29
|
+
|
|
30
|
+
EXAMPLES::
|
|
31
|
+
|
|
32
|
+
sage: L.<x,y> = LaurentPolynomialRing(QQ) # indirect doctest # needs sage.modules
|
|
33
|
+
sage: x*y # needs sage.modules
|
|
34
|
+
x*y
|
|
35
|
+
"""
|
|
36
|
+
cdef type t = type(self)
|
|
37
|
+
cdef LaurentPolynomial ans
|
|
38
|
+
ans = t.__new__(t)
|
|
39
|
+
ans._parent = self._parent
|
|
40
|
+
return ans
|
|
41
|
+
|
|
42
|
+
cpdef _add_(self, other):
|
|
43
|
+
"""
|
|
44
|
+
Abstract addition method.
|
|
45
|
+
|
|
46
|
+
EXAMPLES::
|
|
47
|
+
|
|
48
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
49
|
+
sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial
|
|
50
|
+
sage: LaurentPolynomial._add_(x, x)
|
|
51
|
+
Traceback (most recent call last):
|
|
52
|
+
...
|
|
53
|
+
NotImplementedError
|
|
54
|
+
"""
|
|
55
|
+
raise NotImplementedError
|
|
56
|
+
|
|
57
|
+
cpdef _mul_(self, other):
|
|
58
|
+
"""
|
|
59
|
+
Abstract multiplication method.
|
|
60
|
+
|
|
61
|
+
EXAMPLES::
|
|
62
|
+
|
|
63
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
64
|
+
sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial
|
|
65
|
+
sage: LaurentPolynomial._mul_(x, x)
|
|
66
|
+
Traceback (most recent call last):
|
|
67
|
+
...
|
|
68
|
+
NotImplementedError
|
|
69
|
+
"""
|
|
70
|
+
raise NotImplementedError
|
|
71
|
+
|
|
72
|
+
cpdef _floordiv_(self, other):
|
|
73
|
+
"""
|
|
74
|
+
Abstract floor division method.
|
|
75
|
+
|
|
76
|
+
EXAMPLES::
|
|
77
|
+
|
|
78
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
79
|
+
sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial
|
|
80
|
+
sage: LaurentPolynomial._floordiv_(x, x)
|
|
81
|
+
Traceback (most recent call last):
|
|
82
|
+
...
|
|
83
|
+
NotImplementedError
|
|
84
|
+
"""
|
|
85
|
+
raise NotImplementedError
|
|
86
|
+
|
|
87
|
+
def _integer_(self, ZZ):
|
|
88
|
+
r"""
|
|
89
|
+
Convert this Laurent polynomial to an integer.
|
|
90
|
+
|
|
91
|
+
This is only possible if the Laurent polynomial is constant.
|
|
92
|
+
|
|
93
|
+
OUTPUT: integer
|
|
94
|
+
|
|
95
|
+
TESTS::
|
|
96
|
+
|
|
97
|
+
sage: L.<a> = LaurentPolynomialRing(QQ)
|
|
98
|
+
sage: L(42)._integer_(ZZ)
|
|
99
|
+
42
|
|
100
|
+
sage: a._integer_(ZZ)
|
|
101
|
+
Traceback (most recent call last):
|
|
102
|
+
...
|
|
103
|
+
ValueError: a is not constant
|
|
104
|
+
sage: L(2/3)._integer_(ZZ)
|
|
105
|
+
Traceback (most recent call last):
|
|
106
|
+
...
|
|
107
|
+
TypeError: no conversion of this rational to integer
|
|
108
|
+
sage: ZZ(L(42))
|
|
109
|
+
42
|
|
110
|
+
|
|
111
|
+
::
|
|
112
|
+
|
|
113
|
+
sage: # needs sage.modules
|
|
114
|
+
sage: L.<a, b> = LaurentPolynomialRing(QQ)
|
|
115
|
+
sage: L(42)._integer_(ZZ)
|
|
116
|
+
42
|
|
117
|
+
sage: a._integer_(ZZ)
|
|
118
|
+
Traceback (most recent call last):
|
|
119
|
+
...
|
|
120
|
+
ValueError: a is not constant
|
|
121
|
+
sage: L(2/3)._integer_(ZZ)
|
|
122
|
+
Traceback (most recent call last):
|
|
123
|
+
...
|
|
124
|
+
TypeError: no conversion of this rational to integer
|
|
125
|
+
sage: ZZ(L(42))
|
|
126
|
+
42
|
|
127
|
+
"""
|
|
128
|
+
if not self.is_constant():
|
|
129
|
+
raise ValueError('{} is not constant'.format(self))
|
|
130
|
+
return ZZ(self.constant_coefficient())
|
|
131
|
+
|
|
132
|
+
def _rational_(self):
|
|
133
|
+
r"""
|
|
134
|
+
Convert this Laurent polynomial to a rational.
|
|
135
|
+
|
|
136
|
+
This is only possible if the Laurent polynomial is constant.
|
|
137
|
+
|
|
138
|
+
OUTPUT: a rational
|
|
139
|
+
|
|
140
|
+
TESTS::
|
|
141
|
+
|
|
142
|
+
sage: L.<a> = LaurentPolynomialRing(QQ)
|
|
143
|
+
sage: L(42)._rational_()
|
|
144
|
+
42
|
|
145
|
+
sage: a._rational_()
|
|
146
|
+
Traceback (most recent call last):
|
|
147
|
+
...
|
|
148
|
+
ValueError: a is not constant
|
|
149
|
+
sage: QQ(L(2/3))
|
|
150
|
+
2/3
|
|
151
|
+
|
|
152
|
+
::
|
|
153
|
+
|
|
154
|
+
sage: # needs sage.modules
|
|
155
|
+
sage: L.<a, b> = LaurentPolynomialRing(QQ)
|
|
156
|
+
sage: L(42)._rational_()
|
|
157
|
+
42
|
|
158
|
+
sage: a._rational_()
|
|
159
|
+
Traceback (most recent call last):
|
|
160
|
+
...
|
|
161
|
+
ValueError: a is not constant
|
|
162
|
+
sage: QQ(L(2/3))
|
|
163
|
+
2/3
|
|
164
|
+
"""
|
|
165
|
+
if not self.is_constant():
|
|
166
|
+
raise ValueError('{} is not constant'.format(self))
|
|
167
|
+
from sage.rings.rational_field import QQ
|
|
168
|
+
return QQ(self.constant_coefficient())
|
|
169
|
+
|
|
170
|
+
def change_ring(self, R):
|
|
171
|
+
"""
|
|
172
|
+
Return a copy of this Laurent polynomial, with coefficients in ``R``.
|
|
173
|
+
|
|
174
|
+
EXAMPLES::
|
|
175
|
+
|
|
176
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
177
|
+
sage: a = x^2 + 3*x^3 + 5*x^-1
|
|
178
|
+
sage: a.change_ring(GF(3))
|
|
179
|
+
2*x^-1 + x^2
|
|
180
|
+
|
|
181
|
+
Check that :issue:`22277` is fixed::
|
|
182
|
+
|
|
183
|
+
sage: # needs sage.modules
|
|
184
|
+
sage: R.<x, y> = LaurentPolynomialRing(QQ)
|
|
185
|
+
sage: a = 2*x^2 + 3*x^3 + 4*x^-1
|
|
186
|
+
sage: a.change_ring(GF(3))
|
|
187
|
+
-x^2 + x^-1
|
|
188
|
+
"""
|
|
189
|
+
return self._parent.change_ring(R)(self)
|
|
190
|
+
|
|
191
|
+
cpdef long number_of_terms(self) except -1:
|
|
192
|
+
"""
|
|
193
|
+
Abstract method for number of terms
|
|
194
|
+
|
|
195
|
+
EXAMPLES::
|
|
196
|
+
|
|
197
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
198
|
+
sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial
|
|
199
|
+
sage: LaurentPolynomial.number_of_terms(x)
|
|
200
|
+
Traceback (most recent call last):
|
|
201
|
+
...
|
|
202
|
+
NotImplementedError
|
|
203
|
+
"""
|
|
204
|
+
raise NotImplementedError
|
|
205
|
+
|
|
206
|
+
def hamming_weight(self):
|
|
207
|
+
"""
|
|
208
|
+
Return the hamming weight of ``self``.
|
|
209
|
+
|
|
210
|
+
The hamming weight is number of nonzero coefficients and
|
|
211
|
+
also known as the weight or sparsity.
|
|
212
|
+
|
|
213
|
+
EXAMPLES::
|
|
214
|
+
|
|
215
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
216
|
+
sage: f = x^3 - 1
|
|
217
|
+
sage: f.hamming_weight()
|
|
218
|
+
2
|
|
219
|
+
"""
|
|
220
|
+
return self.number_of_terms()
|
|
221
|
+
|
|
222
|
+
cpdef dict monomial_coefficients(self):
|
|
223
|
+
"""
|
|
224
|
+
Abstract ``dict`` method.
|
|
225
|
+
|
|
226
|
+
EXAMPLES::
|
|
227
|
+
|
|
228
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
229
|
+
sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial
|
|
230
|
+
sage: LaurentPolynomial.monomial_coefficients(x)
|
|
231
|
+
Traceback (most recent call last):
|
|
232
|
+
...
|
|
233
|
+
NotImplementedError
|
|
234
|
+
"""
|
|
235
|
+
raise NotImplementedError
|
|
236
|
+
|
|
237
|
+
dict = monomial_coefficients
|
|
238
|
+
|
|
239
|
+
def map_coefficients(self, f, new_base_ring=None):
|
|
240
|
+
"""
|
|
241
|
+
Apply ``f`` to the coefficients of ``self``.
|
|
242
|
+
|
|
243
|
+
If ``f`` is a :class:`sage.categories.map.Map`, then the resulting
|
|
244
|
+
polynomial will be defined over the codomain of ``f``. Otherwise, the
|
|
245
|
+
resulting polynomial will be over the same ring as ``self``. Set
|
|
246
|
+
``new_base_ring`` to override this behavior.
|
|
247
|
+
|
|
248
|
+
INPUT:
|
|
249
|
+
|
|
250
|
+
- ``f`` -- a callable that will be applied to the coefficients of ``self``
|
|
251
|
+
|
|
252
|
+
- ``new_base_ring`` -- (optional) if given, the resulting polynomial
|
|
253
|
+
will be defined over this ring
|
|
254
|
+
|
|
255
|
+
EXAMPLES::
|
|
256
|
+
|
|
257
|
+
sage: # needs sage.rings.finite_rings
|
|
258
|
+
sage: k.<a> = GF(9)
|
|
259
|
+
sage: R.<x> = LaurentPolynomialRing(k)
|
|
260
|
+
sage: f = x*a + a
|
|
261
|
+
sage: f.map_coefficients(lambda a: a + 1)
|
|
262
|
+
(a + 1) + (a + 1)*x
|
|
263
|
+
sage: R.<x,y> = LaurentPolynomialRing(k, 2) # needs sage.modules
|
|
264
|
+
sage: f = x*a + 2*x^3*y*a + a # needs sage.modules
|
|
265
|
+
sage: f.map_coefficients(lambda a: a + 1) # needs sage.modules
|
|
266
|
+
(2*a + 1)*x^3*y + (a + 1)*x + a + 1
|
|
267
|
+
|
|
268
|
+
Examples with different base ring::
|
|
269
|
+
|
|
270
|
+
sage: # needs sage.modules sage.rings.finite_rings
|
|
271
|
+
sage: R.<r> = GF(9); S.<s> = GF(81)
|
|
272
|
+
sage: h = Hom(R, S)[0]; h
|
|
273
|
+
Ring morphism:
|
|
274
|
+
From: Finite Field in r of size 3^2
|
|
275
|
+
To: Finite Field in s of size 3^4
|
|
276
|
+
Defn: r |--> 2*s^3 + 2*s^2 + 1
|
|
277
|
+
sage: T.<X,Y> = LaurentPolynomialRing(R, 2)
|
|
278
|
+
sage: f = r*X + Y
|
|
279
|
+
sage: g = f.map_coefficients(h); g
|
|
280
|
+
(2*s^3 + 2*s^2 + 1)*X + Y
|
|
281
|
+
sage: g.parent()
|
|
282
|
+
Multivariate Laurent Polynomial Ring in X, Y
|
|
283
|
+
over Finite Field in s of size 3^4
|
|
284
|
+
sage: h = lambda x: x.trace()
|
|
285
|
+
sage: g = f.map_coefficients(h); g
|
|
286
|
+
X - Y
|
|
287
|
+
sage: g.parent()
|
|
288
|
+
Multivariate Laurent Polynomial Ring in X, Y
|
|
289
|
+
over Finite Field in r of size 3^2
|
|
290
|
+
sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g
|
|
291
|
+
X - Y
|
|
292
|
+
sage: g.parent()
|
|
293
|
+
Multivariate Laurent Polynomial Ring in X, Y over Finite Field of size 3
|
|
294
|
+
"""
|
|
295
|
+
R = self.parent()
|
|
296
|
+
if new_base_ring is not None:
|
|
297
|
+
R = R.change_ring(new_base_ring)
|
|
298
|
+
elif isinstance(f, Map):
|
|
299
|
+
R = R.change_ring(f.codomain())
|
|
300
|
+
return R(dict([(k, f(v))
|
|
301
|
+
for k, v in self.monomial_coefficients().items()]))
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
cdef class LaurentPolynomial_univariate(LaurentPolynomial):
|
|
305
|
+
r"""
|
|
306
|
+
A univariate Laurent polynomial in the form of `t^n \cdot f`
|
|
307
|
+
where `f` is a polynomial in `t`.
|
|
308
|
+
|
|
309
|
+
INPUT:
|
|
310
|
+
|
|
311
|
+
- ``parent`` -- a Laurent polynomial ring
|
|
312
|
+
|
|
313
|
+
- ``f`` -- a polynomial (or something that can be coerced to one)
|
|
314
|
+
|
|
315
|
+
- ``n`` -- integer (default: 0)
|
|
316
|
+
|
|
317
|
+
AUTHORS:
|
|
318
|
+
|
|
319
|
+
- Tom Boothby (2011) copied this class almost verbatim from
|
|
320
|
+
``laurent_series_ring_element.pyx``, so most of the credit goes to
|
|
321
|
+
William Stein, David Joyner, and Robert Bradshaw
|
|
322
|
+
- Travis Scrimshaw (09-2013): Cleaned-up and added a few extra methods
|
|
323
|
+
"""
|
|
324
|
+
|
|
325
|
+
def __init__(self, parent, f, n=0):
|
|
326
|
+
r"""
|
|
327
|
+
Create the Laurent polynomial `t^n \cdot f`.
|
|
328
|
+
|
|
329
|
+
EXAMPLES::
|
|
330
|
+
|
|
331
|
+
sage: R.<q> = LaurentPolynomialRing(ZZ)
|
|
332
|
+
sage: R([1,2,3])
|
|
333
|
+
1 + 2*q + 3*q^2
|
|
334
|
+
sage: TestSuite(q^-3 + 3*q + 2).run()
|
|
335
|
+
|
|
336
|
+
::
|
|
337
|
+
|
|
338
|
+
sage: # needs sage.rings.padics
|
|
339
|
+
sage: S.<s> = LaurentPolynomialRing(GF(5))
|
|
340
|
+
sage: T.<t> = PolynomialRing(pAdicRing(5))
|
|
341
|
+
sage: S(t)
|
|
342
|
+
s
|
|
343
|
+
sage: parent(S(t))
|
|
344
|
+
Univariate Laurent Polynomial Ring in s over Finite Field of size 5
|
|
345
|
+
sage: parent(S(t)[1])
|
|
346
|
+
Finite Field of size 5
|
|
347
|
+
|
|
348
|
+
::
|
|
349
|
+
|
|
350
|
+
sage: R({})
|
|
351
|
+
0
|
|
352
|
+
"""
|
|
353
|
+
CommutativeAlgebraElement.__init__(self, parent)
|
|
354
|
+
|
|
355
|
+
if isinstance(f, LaurentPolynomial_univariate):
|
|
356
|
+
n += (< LaurentPolynomial_univariate > f).__n
|
|
357
|
+
if (< LaurentPolynomial_univariate > f).__u._parent is parent._R:
|
|
358
|
+
f = (< LaurentPolynomial_univariate > f).__u
|
|
359
|
+
else:
|
|
360
|
+
f = parent._R((< LaurentPolynomial_univariate > f).__u)
|
|
361
|
+
elif (not isinstance(f, Polynomial)) or (parent is not f.parent()):
|
|
362
|
+
if isinstance(f, dict):
|
|
363
|
+
v = min(f) if f else 0
|
|
364
|
+
f = {i-v: c for i, c in f.items()}
|
|
365
|
+
n += v
|
|
366
|
+
f = parent._R(f)
|
|
367
|
+
|
|
368
|
+
# self is that t^n * u:
|
|
369
|
+
self.__u = f
|
|
370
|
+
self.__n = n
|
|
371
|
+
self._normalize()
|
|
372
|
+
|
|
373
|
+
def __reduce__(self):
|
|
374
|
+
"""
|
|
375
|
+
Used in pickling.
|
|
376
|
+
|
|
377
|
+
EXAMPLES::
|
|
378
|
+
|
|
379
|
+
sage: R.<q> = LaurentPolynomialRing(ZZ)
|
|
380
|
+
sage: elt = q^-3 + 2 + q
|
|
381
|
+
sage: loads(dumps(elt)) == elt
|
|
382
|
+
True
|
|
383
|
+
"""
|
|
384
|
+
return LaurentPolynomial_univariate, (self._parent, self.__u, self.__n)
|
|
385
|
+
|
|
386
|
+
def _polynomial_(self, R):
|
|
387
|
+
r"""
|
|
388
|
+
TESTS::
|
|
389
|
+
|
|
390
|
+
sage: Lx = LaurentPolynomialRing(QQ, "x")
|
|
391
|
+
sage: Px = PolynomialRing(QQ, "x")
|
|
392
|
+
sage: Pxy = PolynomialRing(QQ, "x,y")
|
|
393
|
+
sage: Paxb = PolynomialRing(QQ, "a,x,b")
|
|
394
|
+
sage: Qx = PolynomialRing(ZZ, "x")
|
|
395
|
+
sage: Rx = PolynomialRing(GF(2), "x")
|
|
396
|
+
sage: p1 = Lx.gen()
|
|
397
|
+
sage: p2 = Lx.zero()
|
|
398
|
+
sage: p3 = Lx.one()
|
|
399
|
+
sage: p4 = Lx.gen()**3 - 3
|
|
400
|
+
sage: p5 = Lx.gen()**3 + 2*Lx.gen()**2
|
|
401
|
+
sage: p6 = Lx.gen() >> 2
|
|
402
|
+
|
|
403
|
+
sage: Pxes = [(Px, Px.gen()), (Qx, Qx.gen()),
|
|
404
|
+
....: (Pxy, Pxy.gen(0)), (Paxb, Paxb.gen(1))]
|
|
405
|
+
sage: Pxes += [(Rx, Rx.gen())]
|
|
406
|
+
sage: for P, x in Pxes:
|
|
407
|
+
....: assert P(p1) == x and parent(P(p1)) is P
|
|
408
|
+
....: assert P(p2) == P.zero() and parent(P(p2)) is P
|
|
409
|
+
....: assert P(p3) == P.one() and parent(P(p3)) is P
|
|
410
|
+
....: assert P(p4) == x**3 - 3 and parent(P(p4)) is P
|
|
411
|
+
....: assert P(p5) == x**3 + 2*x**2 and parent(P(p5)) is P
|
|
412
|
+
....: try: P(p6)
|
|
413
|
+
....: except ValueError: pass
|
|
414
|
+
....: else: raise RuntimeError
|
|
415
|
+
|
|
416
|
+
sage: Pa = ZZ["a"]
|
|
417
|
+
sage: Px = ZZ["x"]
|
|
418
|
+
sage: Pax = ZZ["a,x"]
|
|
419
|
+
sage: Pxa = ZZ["x,a"]
|
|
420
|
+
sage: Pa_x = ZZ["a"]["x"]
|
|
421
|
+
sage: Px_a = ZZ["x"]["a"]
|
|
422
|
+
sage: Lax = LaurentPolynomialRing(Pa, "x")
|
|
423
|
+
sage: Lxa = LaurentPolynomialRing(Px, "a")
|
|
424
|
+
sage: for poly in ["2*a*x^2 - 5*x*a + 3", "a*x^2 - 3*a^3*x"]:
|
|
425
|
+
....: assert Pax(Lax(poly)) == Pax(Lxa(poly)) == Pax(poly)
|
|
426
|
+
....: assert Pxa(Lax(poly)) == Pxa(Lxa(poly)) == Pxa(poly)
|
|
427
|
+
....: assert Pa_x(Lax(poly)) == Pa_x(poly)
|
|
428
|
+
....: assert Px_a(Lxa(poly)) == Px_a(poly)
|
|
429
|
+
"""
|
|
430
|
+
if self.__n < 0:
|
|
431
|
+
raise ValueError("Laurent polynomial with negative valuation cannot be converted to polynomial")
|
|
432
|
+
|
|
433
|
+
if isinstance(R, PolynomialRing_generic):
|
|
434
|
+
return R(self.__u) << self.__n
|
|
435
|
+
elif self.__n == 0:
|
|
436
|
+
return R(self.__u)
|
|
437
|
+
else:
|
|
438
|
+
u = R(self.__u)
|
|
439
|
+
x = R(self.__u._parent.gen())
|
|
440
|
+
return x**self.__n * u
|
|
441
|
+
|
|
442
|
+
def is_unit(self):
|
|
443
|
+
"""
|
|
444
|
+
Return ``True`` if this Laurent polynomial is a unit in this ring.
|
|
445
|
+
|
|
446
|
+
EXAMPLES::
|
|
447
|
+
|
|
448
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
449
|
+
sage: (2 + t).is_unit()
|
|
450
|
+
False
|
|
451
|
+
sage: f = 2*t
|
|
452
|
+
sage: f.is_unit()
|
|
453
|
+
True
|
|
454
|
+
sage: 1/f
|
|
455
|
+
1/2*t^-1
|
|
456
|
+
sage: R(0).is_unit()
|
|
457
|
+
False
|
|
458
|
+
sage: R.<s> = LaurentPolynomialRing(ZZ)
|
|
459
|
+
sage: g = 2*s
|
|
460
|
+
sage: g.is_unit()
|
|
461
|
+
False
|
|
462
|
+
sage: 1/g
|
|
463
|
+
1/2*s^-1
|
|
464
|
+
|
|
465
|
+
ALGORITHM: A Laurent polynomial is a unit if and only if its "unit
|
|
466
|
+
part" is a unit.
|
|
467
|
+
"""
|
|
468
|
+
return self.__u.is_term() and self.__u.coefficients()[0].is_unit()
|
|
469
|
+
|
|
470
|
+
def is_zero(self):
|
|
471
|
+
"""
|
|
472
|
+
Return ``1`` if ``self`` is 0, else return ``0``.
|
|
473
|
+
|
|
474
|
+
EXAMPLES::
|
|
475
|
+
|
|
476
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
477
|
+
sage: f = 1/x + x + x^2 + 3*x^4
|
|
478
|
+
sage: f.is_zero()
|
|
479
|
+
0
|
|
480
|
+
sage: z = 0*f
|
|
481
|
+
sage: z.is_zero()
|
|
482
|
+
1
|
|
483
|
+
"""
|
|
484
|
+
return self.__u.is_zero()
|
|
485
|
+
|
|
486
|
+
def __bool__(self):
|
|
487
|
+
"""
|
|
488
|
+
Check if ``self`` is nonzero.
|
|
489
|
+
|
|
490
|
+
EXAMPLES::
|
|
491
|
+
|
|
492
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
493
|
+
sage: f = 1/x + x + x^2 + 3*x^4
|
|
494
|
+
sage: not f
|
|
495
|
+
False
|
|
496
|
+
sage: z = 0*f
|
|
497
|
+
sage: not z
|
|
498
|
+
True
|
|
499
|
+
"""
|
|
500
|
+
return not self.__u.is_zero()
|
|
501
|
+
|
|
502
|
+
def _im_gens_(self, codomain, im_gens, base_map=None):
|
|
503
|
+
"""
|
|
504
|
+
Return the image of this element under the morphism defined by
|
|
505
|
+
``im_gens`` in ``codomain``, where elements of the
|
|
506
|
+
base ring are mapped by ``base_map``.
|
|
507
|
+
|
|
508
|
+
EXAMPLES::
|
|
509
|
+
|
|
510
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
511
|
+
sage: H = Hom(R, QQ)
|
|
512
|
+
sage: mor = H(2)
|
|
513
|
+
sage: mor(t^2 + t^-2)
|
|
514
|
+
17/4
|
|
515
|
+
sage: 4 + 1/4
|
|
516
|
+
17/4
|
|
517
|
+
|
|
518
|
+
You can specify a map on the base ring::
|
|
519
|
+
|
|
520
|
+
sage: # needs sage.rings.number_field
|
|
521
|
+
sage: Zx.<x> = ZZ[]
|
|
522
|
+
sage: K.<i> = NumberField(x^2 + 1)
|
|
523
|
+
sage: cc = K.hom([-i])
|
|
524
|
+
sage: R.<t> = LaurentPolynomialRing(K)
|
|
525
|
+
sage: H = Hom(R, R)
|
|
526
|
+
sage: phi = H([t^-2], base_map=cc)
|
|
527
|
+
sage: phi(i*t)
|
|
528
|
+
-i*t^-2
|
|
529
|
+
"""
|
|
530
|
+
x = im_gens[0]
|
|
531
|
+
u = self.__u
|
|
532
|
+
if base_map is not None:
|
|
533
|
+
u = u.map_coefficients(base_map)
|
|
534
|
+
return codomain(u(x) * x**self.__n)
|
|
535
|
+
|
|
536
|
+
cpdef _normalize(self):
|
|
537
|
+
r"""
|
|
538
|
+
A Laurent series is a pair `(u(t), n)`, where either `u = 0`
|
|
539
|
+
(to some precision) or `u` is a unit. This pair corresponds to
|
|
540
|
+
`t^n \cdot u(t)`.
|
|
541
|
+
|
|
542
|
+
EXAMPLES::
|
|
543
|
+
|
|
544
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
545
|
+
sage: elt = t^2 + t^4 # indirect doctest
|
|
546
|
+
sage: elt.polynomial_construction()
|
|
547
|
+
(t^2 + 1, 2)
|
|
548
|
+
|
|
549
|
+
Check that :issue:`21272` is fixed::
|
|
550
|
+
|
|
551
|
+
sage: (t - t).polynomial_construction()
|
|
552
|
+
(0, 0)
|
|
553
|
+
"""
|
|
554
|
+
if self.__u[0]:
|
|
555
|
+
return
|
|
556
|
+
elif self.__u.is_zero():
|
|
557
|
+
self.__n = 0
|
|
558
|
+
return
|
|
559
|
+
# we already caught the infinity and zero cases
|
|
560
|
+
cdef long v = <long > self.__u.valuation()
|
|
561
|
+
self.__n += v
|
|
562
|
+
self.__u = self.__u >> v
|
|
563
|
+
|
|
564
|
+
def _repr_(self):
|
|
565
|
+
"""
|
|
566
|
+
Return a string representation of ``self``.
|
|
567
|
+
|
|
568
|
+
EXAMPLES::
|
|
569
|
+
|
|
570
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
571
|
+
sage: 2 + (2/3)*t^3
|
|
572
|
+
2 + 2/3*t^3
|
|
573
|
+
"""
|
|
574
|
+
if self.is_zero():
|
|
575
|
+
return "0"
|
|
576
|
+
s = " "
|
|
577
|
+
v = self.__u.list()
|
|
578
|
+
valuation = self.__n
|
|
579
|
+
m = len(v)
|
|
580
|
+
X = self._parent.variable_name()
|
|
581
|
+
atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic')
|
|
582
|
+
first = True
|
|
583
|
+
for n in range(m):
|
|
584
|
+
x = v[n]
|
|
585
|
+
e = n + valuation
|
|
586
|
+
x = str(x)
|
|
587
|
+
if x != '0':
|
|
588
|
+
if not first:
|
|
589
|
+
s += " + "
|
|
590
|
+
if not atomic_repr and (x[1:].find("+") != -1 or x[1:].find("-") != -1):
|
|
591
|
+
x = "({})".format(x)
|
|
592
|
+
if e == 1:
|
|
593
|
+
var = "*{}".format(X)
|
|
594
|
+
elif e == 0:
|
|
595
|
+
var = ""
|
|
596
|
+
else:
|
|
597
|
+
var = "*{}^{}".format(X, e)
|
|
598
|
+
s += "{}{}".format(x, var)
|
|
599
|
+
first = False
|
|
600
|
+
s = s.replace(" + -", " - ")
|
|
601
|
+
s = s.replace(" 1*", " ")
|
|
602
|
+
s = s.replace(" -1*", " -")
|
|
603
|
+
return s[1:]
|
|
604
|
+
|
|
605
|
+
def _latex_(self):
|
|
606
|
+
r"""
|
|
607
|
+
EXAMPLES::
|
|
608
|
+
|
|
609
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
610
|
+
sage: f = (17/2)*x^-2 + x + x^2 + 3*x^4
|
|
611
|
+
sage: latex(f)
|
|
612
|
+
\frac{\frac{17}{2}}{x^{2}} + x + x^{2} + 3x^{4}
|
|
613
|
+
|
|
614
|
+
Verify that :issue:`6656` has been fixed::
|
|
615
|
+
|
|
616
|
+
sage: R.<a,b> = PolynomialRing(QQ)
|
|
617
|
+
sage: T.<x> = LaurentPolynomialRing(R)
|
|
618
|
+
sage: y = a*x + b*x
|
|
619
|
+
sage: y._latex_()
|
|
620
|
+
'\\left(a + b\\right)x'
|
|
621
|
+
sage: latex(y)
|
|
622
|
+
\left(a + b\right)x
|
|
623
|
+
|
|
624
|
+
TESTS::
|
|
625
|
+
|
|
626
|
+
sage: L.<lambda2> = LaurentPolynomialRing(QQ)
|
|
627
|
+
sage: latex(L.an_element())
|
|
628
|
+
\lambda_{2}
|
|
629
|
+
sage: L.<y2> = LaurentPolynomialRing(QQ)
|
|
630
|
+
sage: latex(L.an_element())
|
|
631
|
+
y_{2}
|
|
632
|
+
"""
|
|
633
|
+
from sage.misc.latex import latex
|
|
634
|
+
|
|
635
|
+
if self.is_zero():
|
|
636
|
+
return "0"
|
|
637
|
+
s = " "
|
|
638
|
+
v = self.__u.list()
|
|
639
|
+
valuation = self.__n
|
|
640
|
+
m = len(v)
|
|
641
|
+
X = self._parent.latex_variable_names()[0]
|
|
642
|
+
atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic')
|
|
643
|
+
first = True
|
|
644
|
+
for n in range(m):
|
|
645
|
+
x = v[n]
|
|
646
|
+
e = n + valuation
|
|
647
|
+
x = latex(x)
|
|
648
|
+
if x != '0':
|
|
649
|
+
if not first:
|
|
650
|
+
s += " + "
|
|
651
|
+
if not atomic_repr and e > 0 and (x[1:].find("+") != -1 or x[1:].find("-") != -1):
|
|
652
|
+
x = "\\left({}\\right)".format(x)
|
|
653
|
+
if e == 1:
|
|
654
|
+
var = "|{}".format(X)
|
|
655
|
+
elif e == 0:
|
|
656
|
+
var = ""
|
|
657
|
+
elif e > 0:
|
|
658
|
+
var = "|{}^{{{}}}".format(X, e)
|
|
659
|
+
if e >= 0:
|
|
660
|
+
s += "{}{}".format(x, var)
|
|
661
|
+
else: # negative e
|
|
662
|
+
if e == -1:
|
|
663
|
+
s += "\\frac{{{}}}{{{}}}".format(x, X)
|
|
664
|
+
else:
|
|
665
|
+
s += "\\frac{{{}}}{{{}^{{{}}}}}".format(x, X, -e)
|
|
666
|
+
first = False
|
|
667
|
+
s = s.replace(" + -", " - ")
|
|
668
|
+
s = s.replace(" 1|", " ")
|
|
669
|
+
s = s.replace(" -1|", " -")
|
|
670
|
+
s = s.replace("|", "")
|
|
671
|
+
|
|
672
|
+
return s[1:]
|
|
673
|
+
|
|
674
|
+
def __hash__(self):
|
|
675
|
+
"""
|
|
676
|
+
Return the hash of ``self``.
|
|
677
|
+
|
|
678
|
+
TESTS::
|
|
679
|
+
|
|
680
|
+
sage: R = LaurentPolynomialRing(QQ, 't')
|
|
681
|
+
|
|
682
|
+
sage: assert hash(R.zero()) == 0
|
|
683
|
+
sage: assert hash(R.one()) == 1
|
|
684
|
+
sage: assert hash(QQ['t'].gen()) == hash(R.gen())
|
|
685
|
+
|
|
686
|
+
sage: for _ in range(20):
|
|
687
|
+
....: p = QQ.random_element()
|
|
688
|
+
....: assert hash(R(p)) == hash(p), "p = {}".format(p)
|
|
689
|
+
|
|
690
|
+
sage: S.<t> = QQ[]
|
|
691
|
+
sage: for _ in range(20):
|
|
692
|
+
....: p = S.random_element()
|
|
693
|
+
....: assert hash(R(p)) == hash(p), "p = {}".format(p)
|
|
694
|
+
....: assert hash(R(t*p)) == hash(t*p), "p = {}".format(p)
|
|
695
|
+
|
|
696
|
+
Check that :issue:`21272` is fixed::
|
|
697
|
+
|
|
698
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
699
|
+
sage: hash(R.zero()) == hash(t - t)
|
|
700
|
+
True
|
|
701
|
+
"""
|
|
702
|
+
# we reimplement below the hash of polynomials to handle negative
|
|
703
|
+
# degrees
|
|
704
|
+
cdef long result = 0
|
|
705
|
+
cdef long result_mon
|
|
706
|
+
cdef int i, j
|
|
707
|
+
cdef long var_hash_name = hash(self.__u._parent._names[0])
|
|
708
|
+
for i in range(self.__u.degree()+1):
|
|
709
|
+
result_mon = hash(self.__u[i])
|
|
710
|
+
if result_mon:
|
|
711
|
+
j = i + self.__n
|
|
712
|
+
if j > 0:
|
|
713
|
+
result_mon = (1000003 * result_mon) ^ var_hash_name
|
|
714
|
+
result_mon = (1000003 * result_mon) ^ j
|
|
715
|
+
elif j < 0:
|
|
716
|
+
result_mon = (1000003 * result_mon) ^ var_hash_name
|
|
717
|
+
result_mon = (700005 * result_mon) ^ j
|
|
718
|
+
result += result_mon
|
|
719
|
+
return result
|
|
720
|
+
|
|
721
|
+
def __getitem__(self, i):
|
|
722
|
+
"""
|
|
723
|
+
Return the `i`-th coefficient of ``self``.
|
|
724
|
+
|
|
725
|
+
EXAMPLES::
|
|
726
|
+
|
|
727
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
728
|
+
sage: f = -5/t^(10) + t + t^2 - 10/3*t^3; f
|
|
729
|
+
-5*t^-10 + t + t^2 - 10/3*t^3
|
|
730
|
+
sage: f[-10]
|
|
731
|
+
-5
|
|
732
|
+
sage: f[1]
|
|
733
|
+
1
|
|
734
|
+
sage: f[3]
|
|
735
|
+
-10/3
|
|
736
|
+
sage: f[-9]
|
|
737
|
+
0
|
|
738
|
+
sage: f = -5/t^(10) + 1/3 + t + t^2 - 10/3*t^3; f
|
|
739
|
+
-5*t^-10 + 1/3 + t + t^2 - 10/3*t^3
|
|
740
|
+
|
|
741
|
+
Slicing can be used to truncate Laurent polynomials::
|
|
742
|
+
|
|
743
|
+
sage: f[:3]
|
|
744
|
+
-5*t^-10 + 1/3 + t + t^2
|
|
745
|
+
|
|
746
|
+
Any other kind of slicing is an error, see :issue:`18940`::
|
|
747
|
+
|
|
748
|
+
sage: f[-10:2]
|
|
749
|
+
Traceback (most recent call last):
|
|
750
|
+
...
|
|
751
|
+
IndexError: polynomial slicing with a start is not defined
|
|
752
|
+
|
|
753
|
+
sage: f[-14:5:2]
|
|
754
|
+
Traceback (most recent call last):
|
|
755
|
+
...
|
|
756
|
+
IndexError: polynomial slicing with a step is not defined
|
|
757
|
+
"""
|
|
758
|
+
cdef LaurentPolynomial_univariate ret
|
|
759
|
+
if isinstance(i, slice):
|
|
760
|
+
start, stop, step = i.start, i.stop, i.step
|
|
761
|
+
if start is not None or step is not None:
|
|
762
|
+
self.__u[start:stop:step] # error out, see issue #18940
|
|
763
|
+
stop = stop - self.__n if stop is not None else self.__u.degree() + 1
|
|
764
|
+
f = self.__u[:stop]
|
|
765
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
766
|
+
ret.__u = f
|
|
767
|
+
ret.__n = self.__n
|
|
768
|
+
ret._normalize()
|
|
769
|
+
return ret
|
|
770
|
+
|
|
771
|
+
return self.__u[i - self.__n]
|
|
772
|
+
|
|
773
|
+
cpdef long number_of_terms(self) except -1:
|
|
774
|
+
"""
|
|
775
|
+
Return the number of nonzero coefficients of ``self``.
|
|
776
|
+
|
|
777
|
+
Also called weight, hamming weight or sparsity.
|
|
778
|
+
|
|
779
|
+
EXAMPLES::
|
|
780
|
+
|
|
781
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
782
|
+
sage: f = x^3 - 1
|
|
783
|
+
sage: f.number_of_terms()
|
|
784
|
+
2
|
|
785
|
+
sage: R(0).number_of_terms()
|
|
786
|
+
0
|
|
787
|
+
sage: f = (x+1)^100
|
|
788
|
+
sage: f.number_of_terms()
|
|
789
|
+
101
|
|
790
|
+
|
|
791
|
+
The method :meth:`hamming_weight` is an alias::
|
|
792
|
+
|
|
793
|
+
sage: f.hamming_weight()
|
|
794
|
+
101
|
|
795
|
+
"""
|
|
796
|
+
return self.__u.number_of_terms()
|
|
797
|
+
|
|
798
|
+
def __iter__(self):
|
|
799
|
+
"""
|
|
800
|
+
Iterate through the coefficients from the first nonzero one to the
|
|
801
|
+
last nonzero one.
|
|
802
|
+
|
|
803
|
+
EXAMPLES::
|
|
804
|
+
|
|
805
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
806
|
+
sage: f = -5/t^(2) + t + t^2 - 10/3*t^3; f
|
|
807
|
+
-5*t^-2 + t + t^2 - 10/3*t^3
|
|
808
|
+
sage: for a in f: print(a)
|
|
809
|
+
-5
|
|
810
|
+
0
|
|
811
|
+
0
|
|
812
|
+
1
|
|
813
|
+
1
|
|
814
|
+
-10/3
|
|
815
|
+
"""
|
|
816
|
+
return iter(self.__u)
|
|
817
|
+
|
|
818
|
+
def _symbolic_(self, R):
|
|
819
|
+
"""
|
|
820
|
+
EXAMPLES::
|
|
821
|
+
|
|
822
|
+
sage: # needs sage.symbolic
|
|
823
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
824
|
+
sage: f = x^3 + 2/x
|
|
825
|
+
sage: g = f._symbolic_(SR); g
|
|
826
|
+
(x^4 + 2)/x
|
|
827
|
+
sage: g(x=2)
|
|
828
|
+
9
|
|
829
|
+
sage: g = SR(f)
|
|
830
|
+
sage: g(x=2)
|
|
831
|
+
9
|
|
832
|
+
|
|
833
|
+
Since :issue:`24072` the symbolic ring does not accept positive
|
|
834
|
+
characteristic::
|
|
835
|
+
|
|
836
|
+
sage: R.<w> = LaurentPolynomialRing(GF(7))
|
|
837
|
+
sage: SR(2*w^3 + 1) # needs sage.symbolic
|
|
838
|
+
Traceback (most recent call last):
|
|
839
|
+
...
|
|
840
|
+
TypeError: positive characteristic not allowed in symbolic computations
|
|
841
|
+
"""
|
|
842
|
+
d = {repr(g): R.var(g) for g in self._parent.gens()}
|
|
843
|
+
return self.subs(**d)
|
|
844
|
+
|
|
845
|
+
cpdef dict monomial_coefficients(self):
|
|
846
|
+
"""
|
|
847
|
+
Return a dictionary representing ``self``.
|
|
848
|
+
|
|
849
|
+
EXAMPLES::
|
|
850
|
+
|
|
851
|
+
sage: R.<x,y> = ZZ[]
|
|
852
|
+
sage: Q.<t> = LaurentPolynomialRing(R)
|
|
853
|
+
sage: f = (x^3 + y/t^3)^3 + t^2; f
|
|
854
|
+
y^3*t^-9 + 3*x^3*y^2*t^-6 + 3*x^6*y*t^-3 + x^9 + t^2
|
|
855
|
+
sage: f.monomial_coefficients()
|
|
856
|
+
{-9: y^3, -6: 3*x^3*y^2, -3: 3*x^6*y, 0: x^9, 2: 1}
|
|
857
|
+
|
|
858
|
+
``dict`` is an alias::
|
|
859
|
+
|
|
860
|
+
sage: f.dict()
|
|
861
|
+
{-9: y^3, -6: 3*x^3*y^2, -3: 3*x^6*y, 0: x^9, 2: 1}
|
|
862
|
+
"""
|
|
863
|
+
cdef dict d = self.__u.monomial_coefficients()
|
|
864
|
+
return {k + self.__n: d[k] for k in d}
|
|
865
|
+
|
|
866
|
+
dict = monomial_coefficients
|
|
867
|
+
|
|
868
|
+
def coefficients(self):
|
|
869
|
+
"""
|
|
870
|
+
Return the nonzero coefficients of ``self``.
|
|
871
|
+
|
|
872
|
+
EXAMPLES::
|
|
873
|
+
|
|
874
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
875
|
+
sage: f = -5/t^(2) + t + t^2 - 10/3*t^3
|
|
876
|
+
sage: f.coefficients()
|
|
877
|
+
[-5, 1, 1, -10/3]
|
|
878
|
+
"""
|
|
879
|
+
return self.__u.coefficients()
|
|
880
|
+
|
|
881
|
+
def exponents(self):
|
|
882
|
+
"""
|
|
883
|
+
Return the exponents appearing in ``self`` with nonzero coefficients.
|
|
884
|
+
|
|
885
|
+
EXAMPLES::
|
|
886
|
+
|
|
887
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
888
|
+
sage: f = -5/t^(2) + t + t^2 - 10/3*t^3
|
|
889
|
+
sage: f.exponents()
|
|
890
|
+
[-2, 1, 2, 3]
|
|
891
|
+
"""
|
|
892
|
+
return [i + self.__n for i in self.__u.exponents()]
|
|
893
|
+
|
|
894
|
+
def __setitem__(self, n, value):
|
|
895
|
+
"""
|
|
896
|
+
EXAMPLES::
|
|
897
|
+
|
|
898
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
899
|
+
sage: f = t^2 + t^-3
|
|
900
|
+
sage: f[2] = 5
|
|
901
|
+
Traceback (most recent call last):
|
|
902
|
+
...
|
|
903
|
+
IndexError: Laurent polynomials are immutable
|
|
904
|
+
"""
|
|
905
|
+
raise IndexError("Laurent polynomials are immutable")
|
|
906
|
+
|
|
907
|
+
cpdef _unsafe_mutate(self, i, value):
|
|
908
|
+
r"""
|
|
909
|
+
Sage assumes throughout that commutative ring elements are
|
|
910
|
+
immutable. This is relevant for caching, etc. But sometimes you
|
|
911
|
+
need to change a Laurent polynomial and you really know what you're
|
|
912
|
+
doing. That's when this function is for you.
|
|
913
|
+
|
|
914
|
+
EXAMPLES::
|
|
915
|
+
|
|
916
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
917
|
+
sage: f = t^2 + t^-3
|
|
918
|
+
sage: f._unsafe_mutate(2, 3)
|
|
919
|
+
sage: f
|
|
920
|
+
t^-3 + 3*t^2
|
|
921
|
+
"""
|
|
922
|
+
j = i - self.__n
|
|
923
|
+
if j >= 0:
|
|
924
|
+
self.__u._unsafe_mutate(j, value)
|
|
925
|
+
else: # off to the left
|
|
926
|
+
if value != 0:
|
|
927
|
+
self.__n = self.__n + j
|
|
928
|
+
R = self._parent.base_ring()
|
|
929
|
+
coeffs = [value] + [R.zero() for _ in range(1, -j)] + self.__u.list()
|
|
930
|
+
self.__u = self.__u._parent(coeffs)
|
|
931
|
+
self._normalize()
|
|
932
|
+
|
|
933
|
+
cpdef _add_(self, right_m):
|
|
934
|
+
"""
|
|
935
|
+
Add two Laurent polynomials with the same parent.
|
|
936
|
+
|
|
937
|
+
EXAMPLES::
|
|
938
|
+
|
|
939
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
940
|
+
sage: t + t
|
|
941
|
+
2*t
|
|
942
|
+
sage: f = 1/t + t^2 + t^3 - 17/3 * t^4
|
|
943
|
+
sage: g = 2/t + t^3
|
|
944
|
+
sage: f + g
|
|
945
|
+
3*t^-1 + t^2 + 2*t^3 - 17/3*t^4
|
|
946
|
+
sage: f + 0
|
|
947
|
+
t^-1 + t^2 + t^3 - 17/3*t^4
|
|
948
|
+
sage: 0 + f
|
|
949
|
+
t^-1 + t^2 + t^3 - 17/3*t^4
|
|
950
|
+
sage: R(0) + R(0)
|
|
951
|
+
0
|
|
952
|
+
sage: t^3 + t^-3
|
|
953
|
+
t^-3 + t^3
|
|
954
|
+
|
|
955
|
+
ALGORITHM: Shift the unit parts to align them, then add.
|
|
956
|
+
"""
|
|
957
|
+
cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate > right_m
|
|
958
|
+
cdef long m
|
|
959
|
+
cdef LaurentPolynomial_univariate ret
|
|
960
|
+
|
|
961
|
+
# 1. Special case when one or the other is 0.
|
|
962
|
+
if not right:
|
|
963
|
+
return self
|
|
964
|
+
if not self:
|
|
965
|
+
return right
|
|
966
|
+
|
|
967
|
+
# 2. Align the unit parts.
|
|
968
|
+
if self.__n < right.__n:
|
|
969
|
+
m = self.__n
|
|
970
|
+
f1 = self.__u
|
|
971
|
+
f2 = right.__u << right.__n - m
|
|
972
|
+
elif self.__n > right.__n:
|
|
973
|
+
m = right.__n
|
|
974
|
+
f1 = self.__u << self.__n - m
|
|
975
|
+
f2 = right.__u
|
|
976
|
+
else:
|
|
977
|
+
m = self.__n
|
|
978
|
+
f1 = self.__u
|
|
979
|
+
f2 = right.__u
|
|
980
|
+
# 3. Add
|
|
981
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
982
|
+
ret.__u = <ModuleElement > (f1 + f2)
|
|
983
|
+
ret.__n = m
|
|
984
|
+
ret._normalize()
|
|
985
|
+
return ret
|
|
986
|
+
|
|
987
|
+
cpdef _sub_(self, right_m):
|
|
988
|
+
"""
|
|
989
|
+
Subtract two Laurent polynomials with the same parent.
|
|
990
|
+
|
|
991
|
+
EXAMPLES::
|
|
992
|
+
|
|
993
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
994
|
+
sage: t - t
|
|
995
|
+
0
|
|
996
|
+
sage: t^5 + 2 * t^-5
|
|
997
|
+
2*t^-5 + t^5
|
|
998
|
+
|
|
999
|
+
ALGORITHM: Shift the unit parts to align them, then subtract.
|
|
1000
|
+
"""
|
|
1001
|
+
cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate > right_m
|
|
1002
|
+
cdef long m
|
|
1003
|
+
cdef LaurentPolynomial_univariate ret
|
|
1004
|
+
|
|
1005
|
+
# 1. Special case when one or the other is 0.
|
|
1006
|
+
if not right:
|
|
1007
|
+
return self
|
|
1008
|
+
if not self:
|
|
1009
|
+
return -right
|
|
1010
|
+
|
|
1011
|
+
# 2. Align the unit parts.
|
|
1012
|
+
if self.__n < right.__n:
|
|
1013
|
+
m = self.__n
|
|
1014
|
+
f1 = self.__u
|
|
1015
|
+
f2 = right.__u << right.__n - m
|
|
1016
|
+
else:
|
|
1017
|
+
m = right.__n
|
|
1018
|
+
f1 = self.__u << self.__n - m
|
|
1019
|
+
f2 = right.__u
|
|
1020
|
+
# 3. Subtract
|
|
1021
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1022
|
+
ret.__u = <ModuleElement > (f1 - f2)
|
|
1023
|
+
ret.__n = m
|
|
1024
|
+
ret._normalize()
|
|
1025
|
+
return ret
|
|
1026
|
+
|
|
1027
|
+
def degree(self):
|
|
1028
|
+
r"""
|
|
1029
|
+
Return the degree of ``self``.
|
|
1030
|
+
|
|
1031
|
+
EXAMPLES::
|
|
1032
|
+
|
|
1033
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1034
|
+
sage: g = x^2 - x^4
|
|
1035
|
+
sage: g.degree()
|
|
1036
|
+
4
|
|
1037
|
+
sage: g = -10/x^5 + x^2 - x^7
|
|
1038
|
+
sage: g.degree()
|
|
1039
|
+
7
|
|
1040
|
+
|
|
1041
|
+
The zero polynomial is defined to have degree `-\infty`::
|
|
1042
|
+
|
|
1043
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1044
|
+
sage: R.zero().degree()
|
|
1045
|
+
-Infinity
|
|
1046
|
+
"""
|
|
1047
|
+
# The zero polynomial is defined to have degree -Infinity
|
|
1048
|
+
if self.is_zero():
|
|
1049
|
+
return minus_infinity
|
|
1050
|
+
return self.__u.degree() + self.__n
|
|
1051
|
+
|
|
1052
|
+
def __neg__(self):
|
|
1053
|
+
"""
|
|
1054
|
+
Return the negative of ``self``.
|
|
1055
|
+
|
|
1056
|
+
EXAMPLES::
|
|
1057
|
+
|
|
1058
|
+
sage: R.<t> = LaurentPolynomialRing(ZZ)
|
|
1059
|
+
sage: -(1+t^5)
|
|
1060
|
+
-1 - t^5
|
|
1061
|
+
"""
|
|
1062
|
+
cdef LaurentPolynomial_univariate ret
|
|
1063
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1064
|
+
ret.__u = <ModuleElement > -self.__u
|
|
1065
|
+
ret.__n = self.__n
|
|
1066
|
+
# No need to normalize
|
|
1067
|
+
return ret
|
|
1068
|
+
|
|
1069
|
+
cpdef _mul_(self, right_r):
|
|
1070
|
+
"""
|
|
1071
|
+
EXAMPLES::
|
|
1072
|
+
|
|
1073
|
+
sage: R.<x> = LaurentPolynomialRing(GF(2))
|
|
1074
|
+
sage: f = 1/x^3 + x + x^2 + 3*x^4
|
|
1075
|
+
sage: g = 1 - x + x^2 - x^4
|
|
1076
|
+
sage: f*g
|
|
1077
|
+
x^-3 + x^-2 + x^-1 + x^8
|
|
1078
|
+
"""
|
|
1079
|
+
cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate > right_r
|
|
1080
|
+
cdef LaurentPolynomial_univariate ret
|
|
1081
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1082
|
+
ret.__u = <ModuleElement > (self.__u * right.__u)
|
|
1083
|
+
ret.__n = self.__n + right.__n
|
|
1084
|
+
ret._normalize()
|
|
1085
|
+
return ret
|
|
1086
|
+
|
|
1087
|
+
cpdef _rmul_(self, Element c):
|
|
1088
|
+
"""
|
|
1089
|
+
EXAMPLES::
|
|
1090
|
+
|
|
1091
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1092
|
+
sage: f = 1/x^3 + x + x^2 + 3*x^4
|
|
1093
|
+
sage: 3 * f
|
|
1094
|
+
3*x^-3 + 3*x + 3*x^2 + 9*x^4
|
|
1095
|
+
"""
|
|
1096
|
+
cdef LaurentPolynomial_univariate ret
|
|
1097
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1098
|
+
ret.__u = <ModuleElement > self.__u._rmul_(c)
|
|
1099
|
+
ret.__n = self.__n
|
|
1100
|
+
ret._normalize()
|
|
1101
|
+
return ret
|
|
1102
|
+
|
|
1103
|
+
cpdef _lmul_(self, Element c):
|
|
1104
|
+
"""
|
|
1105
|
+
EXAMPLES::
|
|
1106
|
+
|
|
1107
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1108
|
+
sage: f = 1/x^3 + x + x^2 + 3*x^4
|
|
1109
|
+
sage: f * 3
|
|
1110
|
+
3*x^-3 + 3*x + 3*x^2 + 9*x^4
|
|
1111
|
+
"""
|
|
1112
|
+
cdef LaurentPolynomial_univariate ret
|
|
1113
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1114
|
+
ret.__u = <ModuleElement > self.__u._lmul_(c)
|
|
1115
|
+
ret.__n = self.__n
|
|
1116
|
+
ret._normalize()
|
|
1117
|
+
return ret
|
|
1118
|
+
|
|
1119
|
+
def is_monomial(self):
|
|
1120
|
+
r"""
|
|
1121
|
+
Return ``True`` if ``self`` is a monomial; that is, if ``self``
|
|
1122
|
+
is `x^n` for some integer `n`.
|
|
1123
|
+
|
|
1124
|
+
EXAMPLES::
|
|
1125
|
+
|
|
1126
|
+
sage: k.<z> = LaurentPolynomialRing(QQ)
|
|
1127
|
+
sage: z.is_monomial()
|
|
1128
|
+
True
|
|
1129
|
+
sage: k(1).is_monomial()
|
|
1130
|
+
True
|
|
1131
|
+
sage: (z+1).is_monomial()
|
|
1132
|
+
False
|
|
1133
|
+
sage: (z^-2909).is_monomial()
|
|
1134
|
+
True
|
|
1135
|
+
sage: (38*z^-2909).is_monomial()
|
|
1136
|
+
False
|
|
1137
|
+
"""
|
|
1138
|
+
return self.__u.is_monomial()
|
|
1139
|
+
|
|
1140
|
+
def __pow__(_self, r, mod):
|
|
1141
|
+
"""
|
|
1142
|
+
EXAMPLES::
|
|
1143
|
+
|
|
1144
|
+
sage: x = LaurentPolynomialRing(QQ,'x').0
|
|
1145
|
+
sage: f = x + x^2 + 3*x^4
|
|
1146
|
+
sage: g = 1/x^10 - x
|
|
1147
|
+
sage: f^3
|
|
1148
|
+
x^3 + 3*x^4 + 3*x^5 + 10*x^6 + 18*x^7 + 9*x^8 + 27*x^9 + 27*x^10 + 27*x^12
|
|
1149
|
+
sage: g^4
|
|
1150
|
+
x^-40 - 4*x^-29 + 6*x^-18 - 4*x^-7 + x^4
|
|
1151
|
+
|
|
1152
|
+
sage: R.<x> = LaurentPolynomialRing(Zmod(6))
|
|
1153
|
+
sage: x^-2
|
|
1154
|
+
x^-2
|
|
1155
|
+
sage: (5*x^2)^-4
|
|
1156
|
+
x^-8
|
|
1157
|
+
sage: (5*x^-4)^-3
|
|
1158
|
+
5*x^12
|
|
1159
|
+
|
|
1160
|
+
Check that using third argument raises an error::
|
|
1161
|
+
|
|
1162
|
+
sage: L.<x> = LaurentPolynomialRing(R)
|
|
1163
|
+
sage: pow(x, 2, x)
|
|
1164
|
+
Traceback (most recent call last):
|
|
1165
|
+
...
|
|
1166
|
+
NotImplementedError: pow() with a modulus is not implemented for this ring
|
|
1167
|
+
"""
|
|
1168
|
+
cdef LaurentPolynomial_univariate self = _self
|
|
1169
|
+
cdef long right = r
|
|
1170
|
+
if mod is not None:
|
|
1171
|
+
raise NotImplementedError(
|
|
1172
|
+
"pow() with a modulus is not implemented for this ring"
|
|
1173
|
+
)
|
|
1174
|
+
if right != r:
|
|
1175
|
+
raise ValueError("exponent must be an integer")
|
|
1176
|
+
try:
|
|
1177
|
+
return self._parent.element_class(self._parent, self.__u**right, self.__n*right)
|
|
1178
|
+
except TypeError as err:
|
|
1179
|
+
# we need to handle the special case of negative powers and a unit
|
|
1180
|
+
if not self.__u.is_constant() or not self.__u.leading_coefficient().is_unit():
|
|
1181
|
+
raise
|
|
1182
|
+
c = self._parent._R(self.__u.leading_coefficient() ** right)
|
|
1183
|
+
return self._parent.element_class(self._parent, c, self.__n*right)
|
|
1184
|
+
|
|
1185
|
+
cpdef _floordiv_(self, rhs):
|
|
1186
|
+
"""
|
|
1187
|
+
Perform division with remainder and return the quotient.
|
|
1188
|
+
|
|
1189
|
+
EXAMPLES::
|
|
1190
|
+
|
|
1191
|
+
sage: L.<x> = LaurentPolynomialRing(QQ)
|
|
1192
|
+
sage: f = x^3 + x^-3
|
|
1193
|
+
sage: g = x^-1 + x
|
|
1194
|
+
sage: f // g
|
|
1195
|
+
x^-2 - 1 + x^2
|
|
1196
|
+
sage: g * (f // g) == f
|
|
1197
|
+
True
|
|
1198
|
+
sage: f // 1
|
|
1199
|
+
x^-3 + x^3
|
|
1200
|
+
sage: 1 // f
|
|
1201
|
+
0
|
|
1202
|
+
"""
|
|
1203
|
+
cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate > rhs
|
|
1204
|
+
cdef LaurentPolynomial_univariate ret
|
|
1205
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1206
|
+
ret.__u = <ModuleElement > (self.__u // right.__u)
|
|
1207
|
+
ret.__n = self.__n - right.__n
|
|
1208
|
+
ret._normalize()
|
|
1209
|
+
return ret
|
|
1210
|
+
|
|
1211
|
+
def shift(self, k):
|
|
1212
|
+
r"""
|
|
1213
|
+
Return this Laurent polynomial multiplied by the power `t^n`.
|
|
1214
|
+
Does not change this polynomial.
|
|
1215
|
+
|
|
1216
|
+
EXAMPLES::
|
|
1217
|
+
|
|
1218
|
+
sage: R.<t> = LaurentPolynomialRing(QQ['y'])
|
|
1219
|
+
sage: f = (t+t^-1)^4; f
|
|
1220
|
+
t^-4 + 4*t^-2 + 6 + 4*t^2 + t^4
|
|
1221
|
+
sage: f.shift(10)
|
|
1222
|
+
t^6 + 4*t^8 + 6*t^10 + 4*t^12 + t^14
|
|
1223
|
+
sage: f >> 10
|
|
1224
|
+
t^-14 + 4*t^-12 + 6*t^-10 + 4*t^-8 + t^-6
|
|
1225
|
+
sage: f << 4
|
|
1226
|
+
1 + 4*t^2 + 6*t^4 + 4*t^6 + t^8
|
|
1227
|
+
"""
|
|
1228
|
+
cdef LaurentPolynomial_univariate ret
|
|
1229
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1230
|
+
ret.__u = self.__u
|
|
1231
|
+
ret.__n = self.__n + k
|
|
1232
|
+
# No need to normalize
|
|
1233
|
+
return ret
|
|
1234
|
+
|
|
1235
|
+
def __lshift__(LaurentPolynomial_univariate self, k):
|
|
1236
|
+
"""
|
|
1237
|
+
Return the left shift of ``self``.
|
|
1238
|
+
|
|
1239
|
+
EXAMPLES::
|
|
1240
|
+
|
|
1241
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1242
|
+
sage: f = (t+t^-1)^4; f
|
|
1243
|
+
t^-4 + 4*t^-2 + 6 + 4*t^2 + t^4
|
|
1244
|
+
sage: f << 4
|
|
1245
|
+
1 + 4*t^2 + 6*t^4 + 4*t^6 + t^8
|
|
1246
|
+
"""
|
|
1247
|
+
cdef LaurentPolynomial_univariate ret
|
|
1248
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1249
|
+
ret.__u = self.__u
|
|
1250
|
+
ret.__n = self.__n + k
|
|
1251
|
+
# No need to normalize
|
|
1252
|
+
return ret
|
|
1253
|
+
|
|
1254
|
+
def __rshift__(LaurentPolynomial_univariate self, k):
|
|
1255
|
+
"""
|
|
1256
|
+
Return the right shift of ``self``.
|
|
1257
|
+
|
|
1258
|
+
EXAMPLES::
|
|
1259
|
+
|
|
1260
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1261
|
+
sage: f = (t+t^-1)^4; f
|
|
1262
|
+
t^-4 + 4*t^-2 + 6 + 4*t^2 + t^4
|
|
1263
|
+
sage: f >> 10
|
|
1264
|
+
t^-14 + 4*t^-12 + 6*t^-10 + 4*t^-8 + t^-6
|
|
1265
|
+
"""
|
|
1266
|
+
cdef LaurentPolynomial_univariate ret
|
|
1267
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1268
|
+
ret.__u = self.__u
|
|
1269
|
+
ret.__n = self.__n - k
|
|
1270
|
+
# No need to normalize
|
|
1271
|
+
return ret
|
|
1272
|
+
|
|
1273
|
+
cpdef _div_(self, rhs):
|
|
1274
|
+
"""
|
|
1275
|
+
EXAMPLES::
|
|
1276
|
+
|
|
1277
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1278
|
+
sage: f = x + x^2 + 3*x^4
|
|
1279
|
+
sage: g = 1/x^7 - x + x^2 - x^4
|
|
1280
|
+
sage: f / x
|
|
1281
|
+
1 + x + 3*x^3
|
|
1282
|
+
sage: f / g
|
|
1283
|
+
(-3*x^11 - x^9 - x^8)/(x^11 - x^9 + x^8 - 1)
|
|
1284
|
+
sage: (x^-2 + x)*(x^-2 + 1) / ((x^5 + x^8)*(x + 2))
|
|
1285
|
+
(x^2 + 1)/(x^10 + 2*x^9)
|
|
1286
|
+
sage: (x^-2 + x)*(x^-2 + 1) / ((x^-5 + x^-8)*(x + 2))
|
|
1287
|
+
(x^6 + x^4)/(x + 2)
|
|
1288
|
+
"""
|
|
1289
|
+
cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate > rhs
|
|
1290
|
+
if right.__u.is_zero():
|
|
1291
|
+
raise ZeroDivisionError
|
|
1292
|
+
return self * ~right
|
|
1293
|
+
|
|
1294
|
+
def __invert__(self):
|
|
1295
|
+
"""
|
|
1296
|
+
Return the inverse of ``self``.
|
|
1297
|
+
|
|
1298
|
+
EXAMPLES::
|
|
1299
|
+
|
|
1300
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1301
|
+
sage: i = ~(t^-2); i
|
|
1302
|
+
t^2
|
|
1303
|
+
sage: i.parent() is R
|
|
1304
|
+
True
|
|
1305
|
+
sage: i = ~(2*t^2); i
|
|
1306
|
+
1/2*t^-2
|
|
1307
|
+
sage: i.parent() is R
|
|
1308
|
+
True
|
|
1309
|
+
sage: i = ~(t^-2 + 2 + t^2); i
|
|
1310
|
+
t^2/(t^4 + 2*t^2 + 1)
|
|
1311
|
+
sage: i.parent()
|
|
1312
|
+
Fraction Field of Univariate Polynomial Ring in t over Rational Field
|
|
1313
|
+
"""
|
|
1314
|
+
cdef LaurentPolynomial_univariate ret
|
|
1315
|
+
if self.__u.is_constant(): # this has a single term c*x^n
|
|
1316
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1317
|
+
if self.__u.is_unit():
|
|
1318
|
+
ret.__u = self.__u.inverse_of_unit()
|
|
1319
|
+
ret.__n = -self.__n
|
|
1320
|
+
ret._normalize()
|
|
1321
|
+
return ret
|
|
1322
|
+
# Enlarge the ring so we can divide by the coefficient
|
|
1323
|
+
R = self._parent.base_ring().fraction_field()
|
|
1324
|
+
P = self._parent.change_ring(R)
|
|
1325
|
+
return P.element_class(P, ~R(self.__u), -self.__n)
|
|
1326
|
+
P = self._parent._R
|
|
1327
|
+
if self.__n < 0:
|
|
1328
|
+
return P.gen()**-self.__n / self.__u
|
|
1329
|
+
return P.one() / (P.gen()**self.__n * self.__u)
|
|
1330
|
+
|
|
1331
|
+
def inverse_of_unit(self):
|
|
1332
|
+
"""
|
|
1333
|
+
Return the inverse of ``self`` if a unit.
|
|
1334
|
+
|
|
1335
|
+
EXAMPLES::
|
|
1336
|
+
|
|
1337
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1338
|
+
sage: (t^-2).inverse_of_unit()
|
|
1339
|
+
t^2
|
|
1340
|
+
sage: (t + 2).inverse_of_unit()
|
|
1341
|
+
Traceback (most recent call last):
|
|
1342
|
+
...
|
|
1343
|
+
ArithmeticError: element is not a unit
|
|
1344
|
+
"""
|
|
1345
|
+
if self.is_unit():
|
|
1346
|
+
return ~self
|
|
1347
|
+
raise ArithmeticError("element is not a unit")
|
|
1348
|
+
|
|
1349
|
+
@coerce_binop
|
|
1350
|
+
def xgcd(self, other):
|
|
1351
|
+
r"""
|
|
1352
|
+
Extended :meth:`gcd` for univariate Laurent polynomial rings over a field.
|
|
1353
|
+
|
|
1354
|
+
OUTPUT:
|
|
1355
|
+
|
|
1356
|
+
A triple ``(g, p, q)`` such that ``g`` is the :meth:`gcd` of
|
|
1357
|
+
``self`` (`= a`) and ``other`` (`= b`), and ``p`` and ``q`` are
|
|
1358
|
+
cofactors satisfying the Bezout identity
|
|
1359
|
+
|
|
1360
|
+
.. MATH::
|
|
1361
|
+
|
|
1362
|
+
g = p \cdot a + q \cdot b.
|
|
1363
|
+
|
|
1364
|
+
EXAMPLES::
|
|
1365
|
+
|
|
1366
|
+
sage: S.<t> = LaurentPolynomialRing(QQ)
|
|
1367
|
+
sage: a = t^-2 + 1
|
|
1368
|
+
sage: b = t^-3 + 1
|
|
1369
|
+
sage: g, p, q = a.xgcd(b); (g, p, q)
|
|
1370
|
+
(t^-3, 1/2*t^-1 - 1/2 - 1/2*t, 1/2 + 1/2*t)
|
|
1371
|
+
sage: g == p * a + q * b
|
|
1372
|
+
True
|
|
1373
|
+
sage: g == a.gcd(b)
|
|
1374
|
+
True
|
|
1375
|
+
sage: t.xgcd(t)
|
|
1376
|
+
(t, 0, 1)
|
|
1377
|
+
sage: t.xgcd(5)
|
|
1378
|
+
(1, 0, 1/5)
|
|
1379
|
+
"""
|
|
1380
|
+
cdef LaurentPolynomial_univariate elt = other
|
|
1381
|
+
cdef LaurentPolynomial_univariate ret_gcd, ret_p, ret_q
|
|
1382
|
+
cdef long n = min(self.__n, elt.__n)
|
|
1383
|
+
|
|
1384
|
+
h, p, q = self.__u.xgcd(elt.__u)
|
|
1385
|
+
|
|
1386
|
+
ret_gcd = <LaurentPolynomial_univariate> self._new_c()
|
|
1387
|
+
ret_gcd.__u = h
|
|
1388
|
+
ret_gcd.__n = n
|
|
1389
|
+
ret_gcd._normalize()
|
|
1390
|
+
|
|
1391
|
+
ret_p = <LaurentPolynomial_univariate> self._new_c()
|
|
1392
|
+
ret_p.__u = p
|
|
1393
|
+
ret_p.__n = n - self.__n
|
|
1394
|
+
ret_p._normalize()
|
|
1395
|
+
|
|
1396
|
+
ret_q = <LaurentPolynomial_univariate> self._new_c()
|
|
1397
|
+
ret_q.__u = q
|
|
1398
|
+
ret_q.__n = n - elt.__n
|
|
1399
|
+
ret_q._normalize()
|
|
1400
|
+
|
|
1401
|
+
return (ret_gcd, ret_p, ret_q)
|
|
1402
|
+
|
|
1403
|
+
def inverse_mod(a, m):
|
|
1404
|
+
"""
|
|
1405
|
+
Invert the polynomial ``a`` with respect to ``m``, or raise a :exc:`ValueError`
|
|
1406
|
+
if no such inverse exists.
|
|
1407
|
+
|
|
1408
|
+
The parameter ``m`` may be either a single polynomial or an ideal
|
|
1409
|
+
(for consistency with :meth:`inverse_mod` in other rings).
|
|
1410
|
+
|
|
1411
|
+
ALGORITHM: Solve the system `as + mt = 1`, returning `s` as the inverse
|
|
1412
|
+
of `a` mod `m`.
|
|
1413
|
+
|
|
1414
|
+
EXAMPLES::
|
|
1415
|
+
|
|
1416
|
+
sage: S.<t> = LaurentPolynomialRing(QQ)
|
|
1417
|
+
sage: f = inverse_mod(t^-2 + 1, t^-3 + 1); f
|
|
1418
|
+
1/2*t^2 - 1/2*t^3 - 1/2*t^4
|
|
1419
|
+
sage: f * (t^-2 + 1) + (1/2*t^4 + 1/2*t^3) * (t^-3 + 1)
|
|
1420
|
+
1
|
|
1421
|
+
"""
|
|
1422
|
+
from sage.rings.ideal import Ideal_generic
|
|
1423
|
+
if isinstance(m, Ideal_generic):
|
|
1424
|
+
v = m.gens_reduced()
|
|
1425
|
+
if len(v) > 1:
|
|
1426
|
+
raise NotImplementedError("only inversion modulo principal ideals implemented")
|
|
1427
|
+
m = v[0]
|
|
1428
|
+
if m.degree() == 1 and m[1].is_unit():
|
|
1429
|
+
# a(x) mod (x-r) = a(r)
|
|
1430
|
+
r = -m[0]
|
|
1431
|
+
if not m[1].is_one():
|
|
1432
|
+
r *= m.base_ring()(~m[1])
|
|
1433
|
+
u = a(r)
|
|
1434
|
+
if u.is_unit():
|
|
1435
|
+
return a.parent()(~u)
|
|
1436
|
+
g, s, _ = a.xgcd(m)
|
|
1437
|
+
if g == 1:
|
|
1438
|
+
return s
|
|
1439
|
+
elif g.is_unit():
|
|
1440
|
+
return g.inverse_of_unit() * s
|
|
1441
|
+
raise ValueError("impossible inverse modulo")
|
|
1442
|
+
|
|
1443
|
+
def _fraction_pair(self):
|
|
1444
|
+
"""
|
|
1445
|
+
Return one representation of ``self`` as a pair
|
|
1446
|
+
``(numerator, denominator)``.
|
|
1447
|
+
|
|
1448
|
+
Here both the numerator and the denominator are polynomials.
|
|
1449
|
+
|
|
1450
|
+
This is used for coercion into the fraction field.
|
|
1451
|
+
|
|
1452
|
+
EXAMPLES::
|
|
1453
|
+
|
|
1454
|
+
sage: L.<x> = LaurentPolynomialRing(QQ)
|
|
1455
|
+
sage: f = 4*x^-7 + 3*x^3 + 1 + 2*x^4 + x^6
|
|
1456
|
+
sage: f._fraction_pair()
|
|
1457
|
+
(x^13 + 2*x^11 + 3*x^10 + x^7 + 4, x^7)
|
|
1458
|
+
"""
|
|
1459
|
+
P = self._parent._R
|
|
1460
|
+
numer = self.__u
|
|
1461
|
+
denom = P.one()
|
|
1462
|
+
if self.__n > 0:
|
|
1463
|
+
numer *= P.gen()**self.__n
|
|
1464
|
+
elif self.__n < 0:
|
|
1465
|
+
denom *= P.gen()**-self.__n
|
|
1466
|
+
return (numer, denom)
|
|
1467
|
+
|
|
1468
|
+
def gcd(self, right):
|
|
1469
|
+
"""
|
|
1470
|
+
Return the gcd of ``self`` with ``right`` where the common divisor
|
|
1471
|
+
``d`` makes both ``self`` and ``right`` into polynomials with
|
|
1472
|
+
the lowest possible degree.
|
|
1473
|
+
|
|
1474
|
+
EXAMPLES::
|
|
1475
|
+
|
|
1476
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1477
|
+
sage: t.gcd(2)
|
|
1478
|
+
1
|
|
1479
|
+
sage: gcd(t^-2 + 1, t^-4 + 3*t^-1)
|
|
1480
|
+
t^-4
|
|
1481
|
+
sage: gcd((t^-2 + t)*(t + t^-1), (t^5 + t^8)*(1 + t^-2))
|
|
1482
|
+
t^-3 + t^-1 + 1 + t^2
|
|
1483
|
+
"""
|
|
1484
|
+
b = <LaurentPolynomial_univariate > self._parent(right)
|
|
1485
|
+
cdef LaurentPolynomial_univariate ret
|
|
1486
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1487
|
+
ret.__u = self.__u.gcd(b.__u)
|
|
1488
|
+
ret.__n = min(self.__n, b.__n)
|
|
1489
|
+
ret._normalize()
|
|
1490
|
+
return ret
|
|
1491
|
+
|
|
1492
|
+
def euclidean_degree(self):
|
|
1493
|
+
r"""
|
|
1494
|
+
Return the degree of ``self`` as an element of an Euclidean domain.
|
|
1495
|
+
|
|
1496
|
+
This is the Euclidean degree of the underlying polynomial.
|
|
1497
|
+
|
|
1498
|
+
EXAMPLES::
|
|
1499
|
+
|
|
1500
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1501
|
+
sage: (x^-5 + x^2).euclidean_degree()
|
|
1502
|
+
7
|
|
1503
|
+
|
|
1504
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1505
|
+
sage: (x^-5 + x^2).euclidean_degree()
|
|
1506
|
+
Traceback (most recent call last):
|
|
1507
|
+
...
|
|
1508
|
+
NotImplementedError
|
|
1509
|
+
"""
|
|
1510
|
+
return self.__u.euclidean_degree()
|
|
1511
|
+
|
|
1512
|
+
@coerce_binop
|
|
1513
|
+
def quo_rem(self, other):
|
|
1514
|
+
r"""
|
|
1515
|
+
Divide ``self`` by ``other`` and return a quotient ``q``
|
|
1516
|
+
and a remainder ``r`` such that ``self == q * other + r``.
|
|
1517
|
+
|
|
1518
|
+
EXAMPLES::
|
|
1519
|
+
|
|
1520
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1521
|
+
sage: (t^-3 - t^3).quo_rem(t^-1 - t)
|
|
1522
|
+
(t^-2 + 1 + t^2, 0)
|
|
1523
|
+
sage: (t^-2 + 3 + t).quo_rem(t^-4)
|
|
1524
|
+
(t^2 + 3*t^4 + t^5, 0)
|
|
1525
|
+
|
|
1526
|
+
sage: num = t^-2 + t
|
|
1527
|
+
sage: den = t^-2 + 1
|
|
1528
|
+
sage: q, r = num.quo_rem(den)
|
|
1529
|
+
sage: num == q * den + r
|
|
1530
|
+
True
|
|
1531
|
+
|
|
1532
|
+
TESTS:
|
|
1533
|
+
|
|
1534
|
+
Check that :issue:`34330` is fixed::
|
|
1535
|
+
|
|
1536
|
+
sage: num = t^-2 + 3 + t
|
|
1537
|
+
sage: den = t^-4 + t
|
|
1538
|
+
sage: q, r = num.quo_rem(den); q, r
|
|
1539
|
+
(0, t^-2 + 3 + t)
|
|
1540
|
+
sage: num == q * den + r
|
|
1541
|
+
True
|
|
1542
|
+
|
|
1543
|
+
sage: num = 2*t^-4 + t^-3 + t^-2 + 2*t + 2*t^2
|
|
1544
|
+
sage: q, r = num.quo_rem(den); q, r
|
|
1545
|
+
(2 + 2*t, -t^-3 + t^-2)
|
|
1546
|
+
sage: num == q * den + r
|
|
1547
|
+
True
|
|
1548
|
+
"""
|
|
1549
|
+
cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate > other
|
|
1550
|
+
q, r = self.__u.quo_rem(right.__u)
|
|
1551
|
+
cdef LaurentPolynomial_univariate ql, qr
|
|
1552
|
+
ql = <LaurentPolynomial_univariate > self._new_c()
|
|
1553
|
+
ql.__u = <ModuleElement > q
|
|
1554
|
+
ql.__n = self.__n - right.__n
|
|
1555
|
+
ql._normalize()
|
|
1556
|
+
qr = <LaurentPolynomial_univariate > self._new_c()
|
|
1557
|
+
qr.__u = <ModuleElement > r
|
|
1558
|
+
qr.__n = self.__n
|
|
1559
|
+
qr._normalize()
|
|
1560
|
+
return ql, qr
|
|
1561
|
+
|
|
1562
|
+
cpdef _richcmp_(self, right_r, int op):
|
|
1563
|
+
r"""
|
|
1564
|
+
Comparison of ``self`` and ``right_r``.
|
|
1565
|
+
|
|
1566
|
+
EXAMPLES::
|
|
1567
|
+
|
|
1568
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1569
|
+
sage: f = x^(-1) + 1 + x
|
|
1570
|
+
sage: g = x^(-1) + 1
|
|
1571
|
+
sage: f == g
|
|
1572
|
+
False
|
|
1573
|
+
|
|
1574
|
+
::
|
|
1575
|
+
|
|
1576
|
+
sage: f = x^(-1) + 1 + x
|
|
1577
|
+
sage: g = x^(-1) + 2
|
|
1578
|
+
sage: f == g
|
|
1579
|
+
False
|
|
1580
|
+
sage: f != g
|
|
1581
|
+
True
|
|
1582
|
+
sage: f < g
|
|
1583
|
+
True
|
|
1584
|
+
sage: f <= g
|
|
1585
|
+
True
|
|
1586
|
+
sage: f > g
|
|
1587
|
+
False
|
|
1588
|
+
sage: f >= g
|
|
1589
|
+
False
|
|
1590
|
+
|
|
1591
|
+
::
|
|
1592
|
+
|
|
1593
|
+
sage: f = x^(-2) + 1 + x
|
|
1594
|
+
sage: g = x^(-1) + 2
|
|
1595
|
+
sage: f == g
|
|
1596
|
+
False
|
|
1597
|
+
sage: f < g
|
|
1598
|
+
False
|
|
1599
|
+
sage: f > g
|
|
1600
|
+
True
|
|
1601
|
+
"""
|
|
1602
|
+
cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate > right_r
|
|
1603
|
+
|
|
1604
|
+
zero = self._parent.base_ring().zero()
|
|
1605
|
+
|
|
1606
|
+
if not self and not right:
|
|
1607
|
+
return rich_to_bool(op, 0)
|
|
1608
|
+
|
|
1609
|
+
# zero pad coefficients on the left, to line them up for comparison
|
|
1610
|
+
cdef long n = min(self.__n, right.__n)
|
|
1611
|
+
x = [zero] * (self.__n - n) + self.__u.list()
|
|
1612
|
+
y = [zero] * (right.__n - n) + right.__u.list()
|
|
1613
|
+
|
|
1614
|
+
# zero pad on right to make the lists the same length
|
|
1615
|
+
# (this is necessary since the power series list() function just
|
|
1616
|
+
# returns the coefficients of the underlying polynomial, which may
|
|
1617
|
+
# have zeroes in the high coefficients)
|
|
1618
|
+
if len(x) < len(y):
|
|
1619
|
+
x.extend([zero] * (len(y) - len(x)))
|
|
1620
|
+
elif len(y) < len(x):
|
|
1621
|
+
y.extend([zero] * (len(x) - len(y)))
|
|
1622
|
+
|
|
1623
|
+
return richcmp(x, y, op)
|
|
1624
|
+
|
|
1625
|
+
def valuation(self, p=None):
|
|
1626
|
+
"""
|
|
1627
|
+
Return the valuation of ``self``.
|
|
1628
|
+
|
|
1629
|
+
The valuation of a Laurent polynomial `t^n u` is `n` plus the
|
|
1630
|
+
valuation of `u`.
|
|
1631
|
+
|
|
1632
|
+
EXAMPLES::
|
|
1633
|
+
|
|
1634
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1635
|
+
sage: f = 1/x + x^2 + 3*x^4
|
|
1636
|
+
sage: g = 1 - x + x^2 - x^4
|
|
1637
|
+
sage: f.valuation()
|
|
1638
|
+
-1
|
|
1639
|
+
sage: g.valuation()
|
|
1640
|
+
0
|
|
1641
|
+
"""
|
|
1642
|
+
return self.__n + self.__u.valuation(p)
|
|
1643
|
+
|
|
1644
|
+
def truncate(self, n):
|
|
1645
|
+
"""
|
|
1646
|
+
Return a polynomial with degree at most `n-1` whose `j`-th coefficients
|
|
1647
|
+
agree with ``self`` for all `j < n`.
|
|
1648
|
+
|
|
1649
|
+
EXAMPLES::
|
|
1650
|
+
|
|
1651
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1652
|
+
sage: f = 1/x^12 + x^3 + x^5 + x^9
|
|
1653
|
+
sage: f.truncate(10)
|
|
1654
|
+
x^-12 + x^3 + x^5 + x^9
|
|
1655
|
+
sage: f.truncate(5)
|
|
1656
|
+
x^-12 + x^3
|
|
1657
|
+
sage: f.truncate(-16)
|
|
1658
|
+
0
|
|
1659
|
+
"""
|
|
1660
|
+
if n <= self.valuation():
|
|
1661
|
+
return self._parent.zero()
|
|
1662
|
+
cdef LaurentPolynomial_univariate ret
|
|
1663
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1664
|
+
ret.__u = <ModuleElement > self.__u.truncate(n - self.__n)
|
|
1665
|
+
ret.__n = self.__n
|
|
1666
|
+
ret._normalize()
|
|
1667
|
+
return ret
|
|
1668
|
+
|
|
1669
|
+
def variable_name(self):
|
|
1670
|
+
"""
|
|
1671
|
+
Return the name of variable of ``self`` as a string.
|
|
1672
|
+
|
|
1673
|
+
EXAMPLES::
|
|
1674
|
+
|
|
1675
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1676
|
+
sage: f = 1/x + x^2 + 3*x^4
|
|
1677
|
+
sage: f.variable_name()
|
|
1678
|
+
'x'
|
|
1679
|
+
"""
|
|
1680
|
+
return self._parent.variable_name()
|
|
1681
|
+
|
|
1682
|
+
def variables(self):
|
|
1683
|
+
"""
|
|
1684
|
+
Return the tuple of variables occurring in this Laurent polynomial.
|
|
1685
|
+
|
|
1686
|
+
EXAMPLES::
|
|
1687
|
+
|
|
1688
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1689
|
+
sage: f = 1/x + x^2 + 3*x^4
|
|
1690
|
+
sage: f.variables()
|
|
1691
|
+
(x,)
|
|
1692
|
+
sage: R.one().variables()
|
|
1693
|
+
()
|
|
1694
|
+
"""
|
|
1695
|
+
if self.is_constant():
|
|
1696
|
+
return ()
|
|
1697
|
+
return self._parent.gens()
|
|
1698
|
+
|
|
1699
|
+
def polynomial_construction(self):
|
|
1700
|
+
"""
|
|
1701
|
+
Return the polynomial and the shift in power used to construct the
|
|
1702
|
+
Laurent polynomial `t^n u`.
|
|
1703
|
+
|
|
1704
|
+
OUTPUT:
|
|
1705
|
+
|
|
1706
|
+
A tuple ``(u, n)`` where ``u`` is the underlying polynomial and ``n``
|
|
1707
|
+
is the power of the exponent shift.
|
|
1708
|
+
|
|
1709
|
+
EXAMPLES::
|
|
1710
|
+
|
|
1711
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1712
|
+
sage: f = 1/x + x^2 + 3*x^4
|
|
1713
|
+
sage: f.polynomial_construction()
|
|
1714
|
+
(3*x^5 + x^3 + 1, -1)
|
|
1715
|
+
"""
|
|
1716
|
+
return (self.__u, self.__n)
|
|
1717
|
+
|
|
1718
|
+
def monomial_reduction(self):
|
|
1719
|
+
"""
|
|
1720
|
+
Return the decomposition as a polynomial and a power of the variable.
|
|
1721
|
+
Constructed for compatibility with the multivariate case.
|
|
1722
|
+
|
|
1723
|
+
OUTPUT:
|
|
1724
|
+
|
|
1725
|
+
A tuple ``(u, t^n)`` where ``u`` is the underlying polynomial and ``n``
|
|
1726
|
+
is the power of the exponent shift.
|
|
1727
|
+
|
|
1728
|
+
EXAMPLES::
|
|
1729
|
+
|
|
1730
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1731
|
+
sage: f = 1/x + x^2 + 3*x^4
|
|
1732
|
+
sage: f.monomial_reduction()
|
|
1733
|
+
(3*x^5 + x^3 + 1, x^-1)
|
|
1734
|
+
"""
|
|
1735
|
+
return (self.__u, self._parent.gen(0) ** self.__n)
|
|
1736
|
+
|
|
1737
|
+
def is_constant(self):
|
|
1738
|
+
"""
|
|
1739
|
+
Return whether this Laurent polynomial is constant.
|
|
1740
|
+
|
|
1741
|
+
EXAMPLES::
|
|
1742
|
+
|
|
1743
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1744
|
+
sage: x.is_constant()
|
|
1745
|
+
False
|
|
1746
|
+
sage: R.one().is_constant()
|
|
1747
|
+
True
|
|
1748
|
+
sage: (x^-2).is_constant()
|
|
1749
|
+
False
|
|
1750
|
+
sage: (x^2).is_constant()
|
|
1751
|
+
False
|
|
1752
|
+
sage: (x^-2 + 2).is_constant()
|
|
1753
|
+
False
|
|
1754
|
+
sage: R(0).is_constant()
|
|
1755
|
+
True
|
|
1756
|
+
sage: R(42).is_constant()
|
|
1757
|
+
True
|
|
1758
|
+
sage: x.is_constant()
|
|
1759
|
+
False
|
|
1760
|
+
sage: (1/x).is_constant()
|
|
1761
|
+
False
|
|
1762
|
+
"""
|
|
1763
|
+
return self.__n == 0 and self.__u.is_constant()
|
|
1764
|
+
|
|
1765
|
+
def is_square(self, root=False):
|
|
1766
|
+
r"""
|
|
1767
|
+
Return whether this Laurent polynomial is a square.
|
|
1768
|
+
|
|
1769
|
+
If ``root`` is set to ``True`` then return a pair made of the
|
|
1770
|
+
boolean answer together with ``None`` or a square root.
|
|
1771
|
+
|
|
1772
|
+
EXAMPLES::
|
|
1773
|
+
|
|
1774
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1775
|
+
|
|
1776
|
+
sage: R.one().is_square()
|
|
1777
|
+
True
|
|
1778
|
+
sage: R(2).is_square()
|
|
1779
|
+
False
|
|
1780
|
+
|
|
1781
|
+
sage: t.is_square()
|
|
1782
|
+
False
|
|
1783
|
+
sage: (t**-2).is_square()
|
|
1784
|
+
True
|
|
1785
|
+
|
|
1786
|
+
Usage of the ``root`` option::
|
|
1787
|
+
|
|
1788
|
+
sage: p = (1 + t^-1 - 2*t^3)
|
|
1789
|
+
sage: p.is_square(root=True)
|
|
1790
|
+
(False, None)
|
|
1791
|
+
sage: (p**2).is_square(root=True)
|
|
1792
|
+
(True, -t^-1 - 1 + 2*t^3)
|
|
1793
|
+
|
|
1794
|
+
The answer is dependent of the base ring::
|
|
1795
|
+
|
|
1796
|
+
sage: # needs sage.rings.number_field
|
|
1797
|
+
sage: S.<u> = LaurentPolynomialRing(QQbar)
|
|
1798
|
+
sage: (2 + 4*t + 2*t^2).is_square()
|
|
1799
|
+
False
|
|
1800
|
+
sage: (2 + 4*u + 2*u^2).is_square()
|
|
1801
|
+
True
|
|
1802
|
+
|
|
1803
|
+
TESTS::
|
|
1804
|
+
|
|
1805
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
1806
|
+
sage: (t - t).is_square(True)
|
|
1807
|
+
(True, 0)
|
|
1808
|
+
|
|
1809
|
+
sage: for _ in range(10):
|
|
1810
|
+
....: p = t ** randint(-15,15) * sum(QQ.random_element() * t**n for n in range(randint(5,10)))
|
|
1811
|
+
....: ans, r = (p**2).is_square(root=True)
|
|
1812
|
+
....: assert ans
|
|
1813
|
+
....: assert r*r == p*p
|
|
1814
|
+
"""
|
|
1815
|
+
cdef LaurentPolynomial_univariate sqrt
|
|
1816
|
+
if self.__n % 2:
|
|
1817
|
+
return (False, None) if root else False
|
|
1818
|
+
elif root:
|
|
1819
|
+
ans, r = self.__u.is_square(True)
|
|
1820
|
+
if ans:
|
|
1821
|
+
sqrt = self._new_c()
|
|
1822
|
+
sqrt.__u = r
|
|
1823
|
+
sqrt.__n = self.__n // 2
|
|
1824
|
+
return (True, sqrt)
|
|
1825
|
+
else:
|
|
1826
|
+
return (False, None)
|
|
1827
|
+
else:
|
|
1828
|
+
return self.__u.is_square(False)
|
|
1829
|
+
|
|
1830
|
+
def __copy__(self):
|
|
1831
|
+
"""
|
|
1832
|
+
Return a copy of ``self``.
|
|
1833
|
+
|
|
1834
|
+
EXAMPLES::
|
|
1835
|
+
|
|
1836
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1837
|
+
sage: f = 1/x + x^2 + 3*x^4
|
|
1838
|
+
sage: cf = copy(f)
|
|
1839
|
+
sage: cf == f
|
|
1840
|
+
True
|
|
1841
|
+
sage: cf is not f
|
|
1842
|
+
True
|
|
1843
|
+
"""
|
|
1844
|
+
from copy import copy
|
|
1845
|
+
cdef LaurentPolynomial_univariate ret
|
|
1846
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1847
|
+
ret.__u = copy(self.__u)
|
|
1848
|
+
ret.__n = self.__n
|
|
1849
|
+
# No need to normalize
|
|
1850
|
+
return ret
|
|
1851
|
+
|
|
1852
|
+
def derivative(self, *args):
|
|
1853
|
+
"""
|
|
1854
|
+
The formal derivative of this Laurent polynomial, with respect
|
|
1855
|
+
to variables supplied in args.
|
|
1856
|
+
|
|
1857
|
+
Multiple variables and iteration counts may be supplied. See
|
|
1858
|
+
documentation for the global :func:`derivative` function for more
|
|
1859
|
+
details.
|
|
1860
|
+
|
|
1861
|
+
.. SEEALSO::
|
|
1862
|
+
|
|
1863
|
+
:meth:`_derivative`
|
|
1864
|
+
|
|
1865
|
+
EXAMPLES::
|
|
1866
|
+
|
|
1867
|
+
sage: R.<x> = LaurentPolynomialRing(QQ)
|
|
1868
|
+
sage: g = 1/x^10 - x + x^2 - x^4
|
|
1869
|
+
sage: g.derivative()
|
|
1870
|
+
-10*x^-11 - 1 + 2*x - 4*x^3
|
|
1871
|
+
sage: g.derivative(x)
|
|
1872
|
+
-10*x^-11 - 1 + 2*x - 4*x^3
|
|
1873
|
+
|
|
1874
|
+
::
|
|
1875
|
+
|
|
1876
|
+
sage: R.<t> = PolynomialRing(ZZ)
|
|
1877
|
+
sage: S.<x> = LaurentPolynomialRing(R)
|
|
1878
|
+
sage: f = 2*t/x + (3*t^2 + 6*t)*x
|
|
1879
|
+
sage: f.derivative()
|
|
1880
|
+
-2*t*x^-2 + (3*t^2 + 6*t)
|
|
1881
|
+
sage: f.derivative(x)
|
|
1882
|
+
-2*t*x^-2 + (3*t^2 + 6*t)
|
|
1883
|
+
sage: f.derivative(t)
|
|
1884
|
+
2*x^-1 + (6*t + 6)*x
|
|
1885
|
+
"""
|
|
1886
|
+
return multi_derivative(self, args)
|
|
1887
|
+
|
|
1888
|
+
def _derivative(self, var=None):
|
|
1889
|
+
"""
|
|
1890
|
+
The formal derivative of this Laurent series with respect to ``var``.
|
|
1891
|
+
|
|
1892
|
+
If ``var`` is ``None`` or the generator of this ring, it's the formal
|
|
1893
|
+
derivative as expected. Otherwise, ``_derivative(var)`` gets called
|
|
1894
|
+
recursively on each coefficient.
|
|
1895
|
+
|
|
1896
|
+
.. SEEALSO::
|
|
1897
|
+
|
|
1898
|
+
:meth:`derivative`
|
|
1899
|
+
|
|
1900
|
+
EXAMPLES::
|
|
1901
|
+
|
|
1902
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1903
|
+
sage: f = x^2 + 3*x^4
|
|
1904
|
+
sage: f._derivative()
|
|
1905
|
+
2*x + 12*x^3
|
|
1906
|
+
sage: f._derivative(x)
|
|
1907
|
+
2*x + 12*x^3
|
|
1908
|
+
sage: g = 1/x^10 - x + x^2 - x^4
|
|
1909
|
+
sage: g._derivative()
|
|
1910
|
+
-10*x^-11 - 1 + 2*x - 4*x^3
|
|
1911
|
+
|
|
1912
|
+
Differentiating with respect to something other than the generator
|
|
1913
|
+
gets recursed into the base ring::
|
|
1914
|
+
|
|
1915
|
+
sage: R.<t> = PolynomialRing(ZZ)
|
|
1916
|
+
sage: S.<x> = LaurentPolynomialRing(R)
|
|
1917
|
+
sage: f = 2*t/x + (3*t^2 + 6*t)*x
|
|
1918
|
+
sage: f._derivative(t)
|
|
1919
|
+
2*x^-1 + (6*t + 6)*x
|
|
1920
|
+
|
|
1921
|
+
Check that :issue:`28187` is fixed::
|
|
1922
|
+
|
|
1923
|
+
sage: # needs sage.symbolic
|
|
1924
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
1925
|
+
sage: p = 1/x + 1 + x
|
|
1926
|
+
sage: x,y = var("x, y")
|
|
1927
|
+
sage: p._derivative(x)
|
|
1928
|
+
-x^-2 + 1
|
|
1929
|
+
sage: p._derivative(y)
|
|
1930
|
+
Traceback (most recent call last):
|
|
1931
|
+
...
|
|
1932
|
+
ValueError: cannot differentiate with respect to y
|
|
1933
|
+
"""
|
|
1934
|
+
cdef LaurentPolynomial_univariate ret
|
|
1935
|
+
if var is not None and var != self._parent.gen():
|
|
1936
|
+
try:
|
|
1937
|
+
# call _derivative() recursively on coefficients
|
|
1938
|
+
u = [coeff._derivative(var) for coeff in self.__u.list(copy=False)]
|
|
1939
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1940
|
+
ret.__u = <ModuleElement > self._parent._R(u)
|
|
1941
|
+
ret.__n = self.__n
|
|
1942
|
+
ret._normalize()
|
|
1943
|
+
return ret
|
|
1944
|
+
except AttributeError:
|
|
1945
|
+
raise ValueError('cannot differentiate with respect to {}'.format(var))
|
|
1946
|
+
|
|
1947
|
+
# compute formal derivative with respect to generator
|
|
1948
|
+
if self.is_zero():
|
|
1949
|
+
return self # this is already 0
|
|
1950
|
+
cdef long m, n = self.__n
|
|
1951
|
+
cdef list a = self.__u.list(copy=True)
|
|
1952
|
+
for m in range(len(a)):
|
|
1953
|
+
a[m] *= n + m
|
|
1954
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
1955
|
+
ret.__u = <ModuleElement > self._parent._R(a)
|
|
1956
|
+
ret.__n = self.__n - 1
|
|
1957
|
+
ret._normalize()
|
|
1958
|
+
return ret
|
|
1959
|
+
|
|
1960
|
+
def integral(self):
|
|
1961
|
+
r"""
|
|
1962
|
+
The formal integral of this Laurent series with 0 constant term.
|
|
1963
|
+
|
|
1964
|
+
EXAMPLES:
|
|
1965
|
+
|
|
1966
|
+
The integral may or may not be defined if the base ring
|
|
1967
|
+
is not a field.
|
|
1968
|
+
|
|
1969
|
+
::
|
|
1970
|
+
|
|
1971
|
+
sage: t = LaurentPolynomialRing(ZZ, 't').0
|
|
1972
|
+
sage: f = 2*t^-3 + 3*t^2
|
|
1973
|
+
sage: f.integral()
|
|
1974
|
+
-t^-2 + t^3
|
|
1975
|
+
|
|
1976
|
+
::
|
|
1977
|
+
|
|
1978
|
+
sage: f = t^3
|
|
1979
|
+
sage: f.integral()
|
|
1980
|
+
Traceback (most recent call last):
|
|
1981
|
+
...
|
|
1982
|
+
ArithmeticError: coefficients of integral cannot be coerced into the base ring
|
|
1983
|
+
|
|
1984
|
+
The integral of `1/t` is `\log(t)`, which is not given by a
|
|
1985
|
+
Laurent polynomial::
|
|
1986
|
+
|
|
1987
|
+
sage: t = LaurentPolynomialRing(ZZ,'t').0
|
|
1988
|
+
sage: f = -1/t^3 - 31/t
|
|
1989
|
+
sage: f.integral()
|
|
1990
|
+
Traceback (most recent call last):
|
|
1991
|
+
...
|
|
1992
|
+
ArithmeticError: the integral of is not a Laurent polynomial, since t^-1 has nonzero coefficient
|
|
1993
|
+
|
|
1994
|
+
Another example with just one negative coefficient::
|
|
1995
|
+
|
|
1996
|
+
sage: A.<t> = LaurentPolynomialRing(QQ)
|
|
1997
|
+
sage: f = -2*t^(-4)
|
|
1998
|
+
sage: f.integral()
|
|
1999
|
+
2/3*t^-3
|
|
2000
|
+
sage: f.integral().derivative() == f
|
|
2001
|
+
True
|
|
2002
|
+
"""
|
|
2003
|
+
cdef long i, n = self.__n
|
|
2004
|
+
cdef LaurentPolynomial_univariate ret
|
|
2005
|
+
if self[-1] != 0:
|
|
2006
|
+
raise ArithmeticError("the integral of is not a Laurent polynomial,"
|
|
2007
|
+
" since t^-1 has nonzero coefficient")
|
|
2008
|
+
|
|
2009
|
+
cdef list a = self.__u.list(copy=False)
|
|
2010
|
+
if n < 0:
|
|
2011
|
+
v = [a[i]/(n+i+1) for i in range(min(-1-n, len(a)))] + [0]
|
|
2012
|
+
else:
|
|
2013
|
+
v = []
|
|
2014
|
+
v += [a[i]/(n+i+1) for i in range(max(-n, 0), len(a))]
|
|
2015
|
+
try:
|
|
2016
|
+
u = self._parent._R(v)
|
|
2017
|
+
except TypeError:
|
|
2018
|
+
raise ArithmeticError("coefficients of integral cannot be coerced into the base ring")
|
|
2019
|
+
ret = <LaurentPolynomial_univariate > self._new_c()
|
|
2020
|
+
ret.__u = <ModuleElement > u
|
|
2021
|
+
ret.__n = n + 1
|
|
2022
|
+
ret._normalize()
|
|
2023
|
+
return ret
|
|
2024
|
+
|
|
2025
|
+
def __call__(self, *x, **kwds):
|
|
2026
|
+
"""
|
|
2027
|
+
Compute value of this Laurent polynomial at ``x``.
|
|
2028
|
+
|
|
2029
|
+
EXAMPLES::
|
|
2030
|
+
|
|
2031
|
+
sage: R.<t> = LaurentPolynomialRing(ZZ)
|
|
2032
|
+
sage: f = t^(-2) + t^2
|
|
2033
|
+
sage: f(2)
|
|
2034
|
+
17/4
|
|
2035
|
+
sage: f(-1)
|
|
2036
|
+
2
|
|
2037
|
+
sage: f(1/3)
|
|
2038
|
+
82/9
|
|
2039
|
+
sage: f(t=-1)
|
|
2040
|
+
2
|
|
2041
|
+
sage: f(x=-1)
|
|
2042
|
+
t^-2 + t^2
|
|
2043
|
+
sage: f()
|
|
2044
|
+
t^-2 + t^2
|
|
2045
|
+
sage: f(1,2)
|
|
2046
|
+
Traceback (most recent call last):
|
|
2047
|
+
...
|
|
2048
|
+
TypeError: number of arguments does not match number of
|
|
2049
|
+
variables in parent
|
|
2050
|
+
"""
|
|
2051
|
+
if kwds:
|
|
2052
|
+
f = self.subs(**kwds)
|
|
2053
|
+
if x: # If there are non-keyword arguments
|
|
2054
|
+
return f(*x)
|
|
2055
|
+
else:
|
|
2056
|
+
return f
|
|
2057
|
+
|
|
2058
|
+
if not x:
|
|
2059
|
+
return self
|
|
2060
|
+
if len(x) != 1:
|
|
2061
|
+
raise TypeError("number of arguments does not match number"
|
|
2062
|
+
" of variables in parent")
|
|
2063
|
+
if isinstance(x[0], tuple):
|
|
2064
|
+
x = x[0]
|
|
2065
|
+
return self.__u(x) * (x[0]**self.__n)
|
|
2066
|
+
|
|
2067
|
+
def factor(self):
|
|
2068
|
+
"""
|
|
2069
|
+
Return a Laurent monomial (the unit part of the factorization) and
|
|
2070
|
+
a factored polynomial.
|
|
2071
|
+
|
|
2072
|
+
EXAMPLES::
|
|
2073
|
+
|
|
2074
|
+
sage: R.<t> = LaurentPolynomialRing(ZZ)
|
|
2075
|
+
sage: f = 4*t^-7 + 3*t^3 + 2*t^4 + t^-6
|
|
2076
|
+
sage: f.factor() # needs sage.libs.pari
|
|
2077
|
+
(t^-7) * (4 + t + 3*t^10 + 2*t^11)
|
|
2078
|
+
"""
|
|
2079
|
+
cdef LaurentPolynomial_univariate u, d
|
|
2080
|
+
pf = self.__u.factor()
|
|
2081
|
+
u = <LaurentPolynomial_univariate > self._new_c()
|
|
2082
|
+
u.__u = pf.unit()
|
|
2083
|
+
u.__n = self.__n
|
|
2084
|
+
u._normalize()
|
|
2085
|
+
|
|
2086
|
+
f = []
|
|
2087
|
+
for t in pf:
|
|
2088
|
+
d = <LaurentPolynomial_univariate > self._new_c()
|
|
2089
|
+
d.__u = t[0]
|
|
2090
|
+
d.__n = 0
|
|
2091
|
+
d._normalize()
|
|
2092
|
+
if d.is_unit():
|
|
2093
|
+
u *= d ** t[1]
|
|
2094
|
+
else:
|
|
2095
|
+
f.append((d, t[1]))
|
|
2096
|
+
|
|
2097
|
+
return Factorization(f, unit=u)
|
|
2098
|
+
|
|
2099
|
+
def residue(self):
|
|
2100
|
+
"""
|
|
2101
|
+
Return the residue of ``self``.
|
|
2102
|
+
|
|
2103
|
+
The residue is the coefficient of `t^-1`.
|
|
2104
|
+
|
|
2105
|
+
EXAMPLES::
|
|
2106
|
+
|
|
2107
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
2108
|
+
sage: f = 3*t^-2 - t^-1 + 3 + t^2
|
|
2109
|
+
sage: f.residue()
|
|
2110
|
+
-1
|
|
2111
|
+
sage: g = -2*t^-2 + 4 + 3*t
|
|
2112
|
+
sage: g.residue()
|
|
2113
|
+
0
|
|
2114
|
+
sage: f.residue().parent()
|
|
2115
|
+
Rational Field
|
|
2116
|
+
"""
|
|
2117
|
+
return self.__u[-1 - self.__n]
|
|
2118
|
+
|
|
2119
|
+
def constant_coefficient(self):
|
|
2120
|
+
"""
|
|
2121
|
+
Return the coefficient of the constant term of ``self``.
|
|
2122
|
+
|
|
2123
|
+
EXAMPLES::
|
|
2124
|
+
|
|
2125
|
+
sage: R.<t> = LaurentPolynomialRing(QQ)
|
|
2126
|
+
sage: f = 3*t^-2 - t^-1 + 3 + t^2
|
|
2127
|
+
sage: f.constant_coefficient()
|
|
2128
|
+
3
|
|
2129
|
+
sage: g = -2*t^-2 + t^-1 + 3*t
|
|
2130
|
+
sage: g.constant_coefficient()
|
|
2131
|
+
0
|
|
2132
|
+
"""
|
|
2133
|
+
return self.__u[-self.__n]
|
|
2134
|
+
|
|
2135
|
+
def _as_extended_polynomial(self):
|
|
2136
|
+
"""
|
|
2137
|
+
This Laurent polynomial seen as a polynomial in twice as many variables,
|
|
2138
|
+
where half of the variables are the inverses of the other half.
|
|
2139
|
+
|
|
2140
|
+
EXAMPLES::
|
|
2141
|
+
|
|
2142
|
+
sage: L.<t> = LaurentPolynomialRing(QQ)
|
|
2143
|
+
sage: f = t-t^-2
|
|
2144
|
+
sage: f._as_extended_polynomial()
|
|
2145
|
+
-tinv^2 + t
|
|
2146
|
+
sage: _.parent()
|
|
2147
|
+
Multivariate Polynomial Ring in t, tinv over Rational Field
|
|
2148
|
+
"""
|
|
2149
|
+
dres = {}
|
|
2150
|
+
for e, c in self.monomial_coefficients().items():
|
|
2151
|
+
if e > 0:
|
|
2152
|
+
dres[(e, 0)] = c
|
|
2153
|
+
else:
|
|
2154
|
+
dres[(0, -e)] = c
|
|
2155
|
+
return self.parent()._extended_ring(dres)
|
|
2156
|
+
|
|
2157
|
+
@coerce_binop
|
|
2158
|
+
def divides(self, other):
|
|
2159
|
+
r"""
|
|
2160
|
+
Return ``True`` if ``self`` divides ``other``.
|
|
2161
|
+
|
|
2162
|
+
EXAMPLES::
|
|
2163
|
+
|
|
2164
|
+
sage: R.<x> = LaurentPolynomialRing(ZZ)
|
|
2165
|
+
sage: (2*x**-1 + 1).divides(4*x**-2 - 1)
|
|
2166
|
+
True
|
|
2167
|
+
sage: (2*x + 1).divides(4*x**2 + 1)
|
|
2168
|
+
False
|
|
2169
|
+
sage: (2*x + x**-1).divides(R(0))
|
|
2170
|
+
True
|
|
2171
|
+
sage: R(0).divides(2*x ** -1 + 1)
|
|
2172
|
+
False
|
|
2173
|
+
sage: R(0).divides(R(0))
|
|
2174
|
+
True
|
|
2175
|
+
sage: R.<x> = LaurentPolynomialRing(Zmod(6))
|
|
2176
|
+
sage: p = 4*x + 3*x^-1
|
|
2177
|
+
sage: q = 5*x^2 + x + 2*x^-2
|
|
2178
|
+
sage: p.divides(q)
|
|
2179
|
+
False
|
|
2180
|
+
|
|
2181
|
+
sage: R.<x,y> = GF(2)[]
|
|
2182
|
+
sage: S.<z> = LaurentPolynomialRing(R)
|
|
2183
|
+
sage: p = (x+y+1) * z**-1 + x*y
|
|
2184
|
+
sage: q = (y^2-x^2) * z**-2 + z + x-y
|
|
2185
|
+
sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular
|
|
2186
|
+
(False, True)
|
|
2187
|
+
"""
|
|
2188
|
+
p = self.polynomial_construction()[0]
|
|
2189
|
+
q = other.polynomial_construction()[0]
|
|
2190
|
+
return p.divides(q)
|