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,3028 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
"""
|
|
3
|
+
Power Series
|
|
4
|
+
|
|
5
|
+
Sage provides an implementation of dense and sparse power series
|
|
6
|
+
over any Sage base ring. This is the base class of the implementations
|
|
7
|
+
of univariate and multivariate power series ring elements in Sage
|
|
8
|
+
(see also :doc:`power_series_poly`, :doc:`multi_power_series_ring_element`).
|
|
9
|
+
|
|
10
|
+
AUTHORS:
|
|
11
|
+
|
|
12
|
+
- William Stein
|
|
13
|
+
- David Harvey (2006-09-11): added solve_linear_de() method
|
|
14
|
+
- Robert Bradshaw (2007-04): sqrt, rmul, lmul, shifting
|
|
15
|
+
- Robert Bradshaw (2007-04): Cython version
|
|
16
|
+
- Simon King (2012-08): use category and coercion framework, :issue:`13412`
|
|
17
|
+
|
|
18
|
+
EXAMPLES::
|
|
19
|
+
|
|
20
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
21
|
+
sage: TestSuite(R).run()
|
|
22
|
+
sage: R([1,2,3])
|
|
23
|
+
1 + 2*x + 3*x^2
|
|
24
|
+
sage: R([1,2,3], 10)
|
|
25
|
+
1 + 2*x + 3*x^2 + O(x^10)
|
|
26
|
+
sage: f = 1 + 2*x - 3*x^3 + O(x^4); f
|
|
27
|
+
1 + 2*x - 3*x^3 + O(x^4)
|
|
28
|
+
sage: f^10
|
|
29
|
+
1 + 20*x + 180*x^2 + 930*x^3 + O(x^4)
|
|
30
|
+
sage: g = 1/f; g
|
|
31
|
+
1 - 2*x + 4*x^2 - 5*x^3 + O(x^4)
|
|
32
|
+
sage: g * f
|
|
33
|
+
1 + O(x^4)
|
|
34
|
+
|
|
35
|
+
In Python (as opposed to Sage) create the power series ring and
|
|
36
|
+
its generator as follows::
|
|
37
|
+
|
|
38
|
+
sage: R = PowerSeriesRing(ZZ, 'x')
|
|
39
|
+
sage: x = R.gen()
|
|
40
|
+
sage: parent(x)
|
|
41
|
+
Power Series Ring in x over Integer Ring
|
|
42
|
+
|
|
43
|
+
EXAMPLES:
|
|
44
|
+
|
|
45
|
+
This example illustrates that coercion for power
|
|
46
|
+
series rings is consistent with coercion for polynomial rings.
|
|
47
|
+
|
|
48
|
+
::
|
|
49
|
+
|
|
50
|
+
sage: poly_ring1.<gen1> = PolynomialRing(QQ)
|
|
51
|
+
sage: poly_ring2.<gen2> = PolynomialRing(QQ)
|
|
52
|
+
sage: huge_ring.<x> = PolynomialRing(poly_ring1)
|
|
53
|
+
|
|
54
|
+
The generator of the first ring gets coerced in as itself, since it
|
|
55
|
+
is the base ring.
|
|
56
|
+
|
|
57
|
+
::
|
|
58
|
+
|
|
59
|
+
sage: huge_ring(gen1)
|
|
60
|
+
gen1
|
|
61
|
+
|
|
62
|
+
The generator of the second ring gets mapped via the natural map
|
|
63
|
+
sending one generator to the other.
|
|
64
|
+
|
|
65
|
+
::
|
|
66
|
+
|
|
67
|
+
sage: huge_ring(gen2)
|
|
68
|
+
x
|
|
69
|
+
|
|
70
|
+
With power series the behavior is the same.
|
|
71
|
+
|
|
72
|
+
::
|
|
73
|
+
|
|
74
|
+
sage: power_ring1.<gen1> = PowerSeriesRing(QQ)
|
|
75
|
+
sage: power_ring2.<gen2> = PowerSeriesRing(QQ)
|
|
76
|
+
sage: huge_power_ring.<x> = PowerSeriesRing(power_ring1)
|
|
77
|
+
sage: huge_power_ring(gen1)
|
|
78
|
+
gen1
|
|
79
|
+
sage: huge_power_ring(gen2)
|
|
80
|
+
x
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
# ****************************************************************************
|
|
84
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
85
|
+
# 2017 Vincent Delecroix <20100.delecroix@gmail.com>
|
|
86
|
+
#
|
|
87
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
88
|
+
#
|
|
89
|
+
# This code is distributed in the hope that it will be useful,
|
|
90
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
91
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
92
|
+
# General Public License for more details.
|
|
93
|
+
#
|
|
94
|
+
# The full text of the GPL is available at:
|
|
95
|
+
#
|
|
96
|
+
# https://www.gnu.org/licenses/
|
|
97
|
+
# ****************************************************************************
|
|
98
|
+
|
|
99
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
100
|
+
from sage.rings.infinity import infinity, InfinityElement
|
|
101
|
+
|
|
102
|
+
from sage.rings.rational_field import QQ
|
|
103
|
+
|
|
104
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
105
|
+
import sage.arith.all as arith
|
|
106
|
+
import sage.misc.latex
|
|
107
|
+
from sage.rings.integer import Integer
|
|
108
|
+
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
|
|
109
|
+
|
|
110
|
+
from sage.categories.fields import Fields
|
|
111
|
+
_Fields = Fields()
|
|
112
|
+
|
|
113
|
+
from sage.misc.derivative import multi_derivative
|
|
114
|
+
from sage.structure.element cimport AlgebraElement, RingElement
|
|
115
|
+
from sage.structure.richcmp cimport richcmp
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def is_PowerSeries(x):
|
|
119
|
+
"""
|
|
120
|
+
Return ``True`` if ``x`` is an instance of a univariate
|
|
121
|
+
or multivariate power series.
|
|
122
|
+
|
|
123
|
+
EXAMPLES::
|
|
124
|
+
|
|
125
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
126
|
+
sage: from sage.rings.power_series_ring_element import is_PowerSeries
|
|
127
|
+
sage: is_PowerSeries(1 + x^2)
|
|
128
|
+
doctest:warning...
|
|
129
|
+
DeprecationWarning: The function is_PowerSeries is deprecated; use 'isinstance(..., PowerSeries)' instead.
|
|
130
|
+
See https://github.com/sagemath/sage/issues/38266 for details.
|
|
131
|
+
True
|
|
132
|
+
sage: is_PowerSeries(x - x)
|
|
133
|
+
True
|
|
134
|
+
sage: is_PowerSeries(0)
|
|
135
|
+
False
|
|
136
|
+
sage: var('x') # needs sage.symbolic
|
|
137
|
+
x
|
|
138
|
+
sage: is_PowerSeries(1 + x^2) # needs sage.symbolic
|
|
139
|
+
False
|
|
140
|
+
"""
|
|
141
|
+
from sage.misc.superseded import deprecation_cython
|
|
142
|
+
deprecation_cython(38266,
|
|
143
|
+
"The function is_PowerSeries is deprecated; "
|
|
144
|
+
"use 'isinstance(..., PowerSeries)' instead.")
|
|
145
|
+
return isinstance(x, PowerSeries)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
cdef class PowerSeries(AlgebraElement):
|
|
149
|
+
"""
|
|
150
|
+
A power series. Base class of univariate and
|
|
151
|
+
multivariate power series. The following methods
|
|
152
|
+
are available with both types of objects.
|
|
153
|
+
"""
|
|
154
|
+
def __init__(self, parent, prec, is_gen=False):
|
|
155
|
+
"""
|
|
156
|
+
Initialize a power series. Not for public use.
|
|
157
|
+
It gets called by the ``PowerSeries_poly`` and
|
|
158
|
+
``MPowerSeries`` constructors.
|
|
159
|
+
|
|
160
|
+
EXAMPLES::
|
|
161
|
+
|
|
162
|
+
sage: PowerSeriesRing(CC, 'q') # needs sage.rings.real_mpfr
|
|
163
|
+
Power Series Ring in q over Complex Field with 53 bits of precision
|
|
164
|
+
sage: T = PowerSeriesRing(GF(3), 5, 't'); T
|
|
165
|
+
Multivariate Power Series Ring in t0, t1, t2, t3, t4
|
|
166
|
+
over Finite Field of size 3
|
|
167
|
+
"""
|
|
168
|
+
AlgebraElement.__init__(self, parent)
|
|
169
|
+
self._is_gen = is_gen
|
|
170
|
+
self._prec = prec
|
|
171
|
+
|
|
172
|
+
def __hash__(self):
|
|
173
|
+
"""
|
|
174
|
+
Compute a hash of ``self``.
|
|
175
|
+
|
|
176
|
+
EXAMPLES::
|
|
177
|
+
|
|
178
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
179
|
+
sage: (1+x^2).__hash__() # random
|
|
180
|
+
15360174650385709
|
|
181
|
+
"""
|
|
182
|
+
return hash(self.polynomial())
|
|
183
|
+
|
|
184
|
+
def __reduce__(self):
|
|
185
|
+
"""
|
|
186
|
+
EXAMPLES::
|
|
187
|
+
|
|
188
|
+
sage: K.<t> = PowerSeriesRing(QQ, 5)
|
|
189
|
+
sage: f = 1 + t - t^3 + O(t^12)
|
|
190
|
+
sage: loads(dumps(f)) == f
|
|
191
|
+
True
|
|
192
|
+
"""
|
|
193
|
+
return make_element_from_parent_v0, (self._parent, self.polynomial(), self.prec())
|
|
194
|
+
|
|
195
|
+
def is_sparse(self):
|
|
196
|
+
"""
|
|
197
|
+
EXAMPLES::
|
|
198
|
+
|
|
199
|
+
sage: R.<t> = PowerSeriesRing(ZZ)
|
|
200
|
+
sage: t.is_sparse()
|
|
201
|
+
False
|
|
202
|
+
sage: R.<t> = PowerSeriesRing(ZZ, sparse=True)
|
|
203
|
+
sage: t.is_sparse()
|
|
204
|
+
True
|
|
205
|
+
"""
|
|
206
|
+
return self._parent.is_sparse()
|
|
207
|
+
|
|
208
|
+
def is_dense(self):
|
|
209
|
+
"""
|
|
210
|
+
EXAMPLES::
|
|
211
|
+
|
|
212
|
+
sage: R.<t> = PowerSeriesRing(ZZ)
|
|
213
|
+
sage: t.is_dense()
|
|
214
|
+
True
|
|
215
|
+
sage: R.<t> = PowerSeriesRing(ZZ, sparse=True)
|
|
216
|
+
sage: t.is_dense()
|
|
217
|
+
False
|
|
218
|
+
"""
|
|
219
|
+
return self._parent.is_dense()
|
|
220
|
+
|
|
221
|
+
def is_gen(self):
|
|
222
|
+
"""
|
|
223
|
+
Return ``True`` if this is the generator (the variable) of the power
|
|
224
|
+
series ring.
|
|
225
|
+
|
|
226
|
+
EXAMPLES::
|
|
227
|
+
|
|
228
|
+
sage: R.<t> = QQ[[]]
|
|
229
|
+
sage: t.is_gen()
|
|
230
|
+
True
|
|
231
|
+
sage: (1 + 2*t).is_gen()
|
|
232
|
+
False
|
|
233
|
+
|
|
234
|
+
Note that this only returns ``True`` on the actual generator, not on
|
|
235
|
+
something that happens to be equal to it.
|
|
236
|
+
|
|
237
|
+
::
|
|
238
|
+
|
|
239
|
+
sage: (1*t).is_gen()
|
|
240
|
+
False
|
|
241
|
+
sage: 1*t == t
|
|
242
|
+
True
|
|
243
|
+
"""
|
|
244
|
+
return bool(self._is_gen)
|
|
245
|
+
|
|
246
|
+
def _im_gens_(self, codomain, im_gens, base_map=None):
|
|
247
|
+
"""
|
|
248
|
+
Return the image of this series under the map that sends the
|
|
249
|
+
generators to ``im_gens``. This is used internally for computing
|
|
250
|
+
homomorphisms.
|
|
251
|
+
|
|
252
|
+
EXAMPLES::
|
|
253
|
+
|
|
254
|
+
sage: R.<t> = QQ[[]]
|
|
255
|
+
sage: f = 1 + t + t^2
|
|
256
|
+
sage: f._im_gens_(ZZ, [3])
|
|
257
|
+
13
|
|
258
|
+
"""
|
|
259
|
+
if base_map is None:
|
|
260
|
+
return codomain(self(im_gens[0]))
|
|
261
|
+
else:
|
|
262
|
+
raise NotImplementedError
|
|
263
|
+
|
|
264
|
+
cpdef base_extend(self, R):
|
|
265
|
+
"""
|
|
266
|
+
Return a copy of this power series but with coefficients in R.
|
|
267
|
+
|
|
268
|
+
The following coercion uses ``base_extend`` implicitly::
|
|
269
|
+
|
|
270
|
+
sage: R.<t> = ZZ[['t']]
|
|
271
|
+
sage: (t - t^2) * Mod(1, 3)
|
|
272
|
+
t + 2*t^2
|
|
273
|
+
"""
|
|
274
|
+
S = self._parent.base_extend(R)
|
|
275
|
+
return S(self)
|
|
276
|
+
|
|
277
|
+
def change_ring(self, R):
|
|
278
|
+
"""
|
|
279
|
+
Change if possible the coefficients of ``self`` to lie in R.
|
|
280
|
+
|
|
281
|
+
EXAMPLES::
|
|
282
|
+
|
|
283
|
+
sage: R.<T> = QQ[[]]; R
|
|
284
|
+
Power Series Ring in T over Rational Field
|
|
285
|
+
sage: f = 1 - 1/2*T + 1/3*T^2 + O(T^3)
|
|
286
|
+
sage: f.base_extend(GF(5))
|
|
287
|
+
Traceback (most recent call last):
|
|
288
|
+
...
|
|
289
|
+
TypeError: no base extension defined
|
|
290
|
+
sage: f.change_ring(GF(5))
|
|
291
|
+
1 + 2*T + 2*T^2 + O(T^3)
|
|
292
|
+
sage: f.change_ring(GF(3))
|
|
293
|
+
Traceback (most recent call last):
|
|
294
|
+
...
|
|
295
|
+
ZeroDivisionError: inverse of Mod(0, 3) does not exist
|
|
296
|
+
|
|
297
|
+
We can only change the ring if there is a ``__call__`` coercion
|
|
298
|
+
defined. The following succeeds because ``ZZ(K(4))`` is defined.
|
|
299
|
+
|
|
300
|
+
::
|
|
301
|
+
|
|
302
|
+
sage: K.<a> = NumberField(cyclotomic_polynomial(3), 'a') # needs sage.rings.number_field
|
|
303
|
+
sage: R.<t> = K[['t']] # needs sage.rings.number_field
|
|
304
|
+
sage: (4*t).change_ring(ZZ) # needs sage.rings.number_field
|
|
305
|
+
4*t
|
|
306
|
+
|
|
307
|
+
This does not succeed because ``ZZ(K(a+1))`` is not defined.
|
|
308
|
+
|
|
309
|
+
::
|
|
310
|
+
|
|
311
|
+
sage: K.<a> = NumberField(cyclotomic_polynomial(3), 'a') # needs sage.rings.number_field
|
|
312
|
+
sage: R.<t> = K[['t']] # needs sage.rings.number_field
|
|
313
|
+
sage: ((a+1)*t).change_ring(ZZ) # needs sage.rings.number_field
|
|
314
|
+
Traceback (most recent call last):
|
|
315
|
+
...
|
|
316
|
+
TypeError: Unable to coerce a + 1 to an integer
|
|
317
|
+
"""
|
|
318
|
+
S = self._parent.change_ring(R)
|
|
319
|
+
return S(self)
|
|
320
|
+
|
|
321
|
+
cpdef _richcmp_(self, right, int op):
|
|
322
|
+
r"""
|
|
323
|
+
Comparison of ``self`` and ``right``.
|
|
324
|
+
|
|
325
|
+
We say two approximate power series are equal if they agree for
|
|
326
|
+
all coefficients up to the *minimum* of the precisions of each.
|
|
327
|
+
Thus, e.g., `f = 1 + q + O(q^2)` is equal to `g = 1 + O(q)`.
|
|
328
|
+
|
|
329
|
+
This is how PARI defines equality of power series, but not how
|
|
330
|
+
Magma defines equality. (Magma would declare `f` and `g` unequal.)
|
|
331
|
+
The PARI/Sage convention is consistent with the idea that
|
|
332
|
+
comparison should take place after coercing both elements into
|
|
333
|
+
a common parent. Hence, in the above example `f` is truncated
|
|
334
|
+
to `f + O(q)`, which is considered to be equal to `g`, even
|
|
335
|
+
though the coefficients of `q` are unknown for both series in
|
|
336
|
+
that comparison.
|
|
337
|
+
|
|
338
|
+
Comparison is done in dictionary order from lowest degree to
|
|
339
|
+
highest degree coefficients. This is different than polynomial
|
|
340
|
+
comparison.
|
|
341
|
+
|
|
342
|
+
EXAMPLES::
|
|
343
|
+
|
|
344
|
+
sage: R.<q> = ZZ[[ ]]; R
|
|
345
|
+
Power Series Ring in q over Integer Ring
|
|
346
|
+
sage: f=1+q+O(q^2); g = 1+O(q)
|
|
347
|
+
sage: f == g
|
|
348
|
+
True
|
|
349
|
+
sage: 1 - 2*q + q^2 +O(q^3) == 1 - 2*q^2 + q^2 + O(q^4)
|
|
350
|
+
False
|
|
351
|
+
|
|
352
|
+
::
|
|
353
|
+
|
|
354
|
+
sage: R.<t> = ZZ[[]]
|
|
355
|
+
sage: 1 + t^2 < 2 - t
|
|
356
|
+
True
|
|
357
|
+
sage: f = 1 + t + t^7 - 5*t^10
|
|
358
|
+
sage: g = 1 + t + t^7 - 5*t^10 + O(t^15)
|
|
359
|
+
sage: f == f
|
|
360
|
+
True
|
|
361
|
+
sage: f < g
|
|
362
|
+
False
|
|
363
|
+
sage: f == g
|
|
364
|
+
True
|
|
365
|
+
|
|
366
|
+
TESTS:
|
|
367
|
+
|
|
368
|
+
:issue:`9457` is fixed::
|
|
369
|
+
|
|
370
|
+
sage: A.<t> = PowerSeriesRing(ZZ)
|
|
371
|
+
sage: g = t + t^3 + t^5 + O(t^6); g
|
|
372
|
+
t + t^3 + t^5 + O(t^6)
|
|
373
|
+
sage: [g == g.add_bigoh(i) for i in range(7)]
|
|
374
|
+
[True, True, True, True, True, True, True]
|
|
375
|
+
sage: A(g.polynomial()) == g
|
|
376
|
+
True
|
|
377
|
+
|
|
378
|
+
sage: f = t + t^2 + O(t^10)
|
|
379
|
+
sage: f == f.truncate()
|
|
380
|
+
True
|
|
381
|
+
"""
|
|
382
|
+
if op == Py_EQ:
|
|
383
|
+
return not (self-right)
|
|
384
|
+
if op == Py_NE:
|
|
385
|
+
return bool(self-right)
|
|
386
|
+
prec = self.common_prec(right)
|
|
387
|
+
x = self.list()
|
|
388
|
+
y = right.list()
|
|
389
|
+
if not (prec is infinity):
|
|
390
|
+
x += [0]*(prec - len(x)) # self.list() does not include trailing zeroes
|
|
391
|
+
x = x[:prec] # truncate x to common prec
|
|
392
|
+
y += [0]*(prec - len(y))
|
|
393
|
+
y = y[:prec]
|
|
394
|
+
return richcmp(x, y, op)
|
|
395
|
+
|
|
396
|
+
def __call__(self, x):
|
|
397
|
+
"""
|
|
398
|
+
Implementations *MUST* override this in the derived class.
|
|
399
|
+
|
|
400
|
+
EXAMPLES::
|
|
401
|
+
|
|
402
|
+
sage: from sage.rings.power_series_ring_element import PowerSeries
|
|
403
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
404
|
+
sage: PowerSeries.__call__(1+x^2,x)
|
|
405
|
+
Traceback (most recent call last):
|
|
406
|
+
...
|
|
407
|
+
NotImplementedError
|
|
408
|
+
"""
|
|
409
|
+
raise NotImplementedError
|
|
410
|
+
|
|
411
|
+
def coefficients(self):
|
|
412
|
+
"""
|
|
413
|
+
Return the nonzero coefficients of ``self``.
|
|
414
|
+
|
|
415
|
+
EXAMPLES::
|
|
416
|
+
|
|
417
|
+
sage: R.<t> = PowerSeriesRing(QQ)
|
|
418
|
+
sage: f = t + t^2 - 10/3*t^3
|
|
419
|
+
sage: f.coefficients()
|
|
420
|
+
[1, 1, -10/3]
|
|
421
|
+
"""
|
|
422
|
+
zero = self.parent().base_ring().zero()
|
|
423
|
+
return [c for c in self.list() if c != zero]
|
|
424
|
+
|
|
425
|
+
def exponents(self):
|
|
426
|
+
"""
|
|
427
|
+
Return the exponents appearing in ``self`` with nonzero coefficients.
|
|
428
|
+
|
|
429
|
+
EXAMPLES::
|
|
430
|
+
|
|
431
|
+
sage: R.<t> = PowerSeriesRing(QQ)
|
|
432
|
+
sage: f = t + t^2 - 10/3*t^3
|
|
433
|
+
sage: f.exponents()
|
|
434
|
+
[1, 2, 3]
|
|
435
|
+
"""
|
|
436
|
+
zero = self.parent().base_ring().zero()
|
|
437
|
+
l = self.list()
|
|
438
|
+
return [i for i in range(len(l)) if l[i] != zero]
|
|
439
|
+
|
|
440
|
+
def list(self):
|
|
441
|
+
"""
|
|
442
|
+
See this method in derived classes:
|
|
443
|
+
|
|
444
|
+
- :meth:`sage.rings.power_series_poly.PowerSeries_poly.list`,
|
|
445
|
+
|
|
446
|
+
- :meth:`sage.rings.multi_power_series_ring_element.MPowerSeries.list`
|
|
447
|
+
|
|
448
|
+
Implementations *MUST* override this in the derived class.
|
|
449
|
+
|
|
450
|
+
EXAMPLES::
|
|
451
|
+
|
|
452
|
+
sage: from sage.rings.power_series_ring_element import PowerSeries
|
|
453
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
454
|
+
sage: PowerSeries.list(1 + x^2)
|
|
455
|
+
Traceback (most recent call last):
|
|
456
|
+
...
|
|
457
|
+
NotImplementedError
|
|
458
|
+
"""
|
|
459
|
+
raise NotImplementedError
|
|
460
|
+
|
|
461
|
+
def polynomial(self):
|
|
462
|
+
"""
|
|
463
|
+
See this method in derived classes:
|
|
464
|
+
|
|
465
|
+
- :meth:`sage.rings.power_series_poly.PowerSeries_poly.polynomial`,
|
|
466
|
+
|
|
467
|
+
- :meth:`sage.rings.multi_power_series_ring_element.MPowerSeries.polynomial`
|
|
468
|
+
|
|
469
|
+
Implementations *MUST* override this in the derived class.
|
|
470
|
+
|
|
471
|
+
EXAMPLES::
|
|
472
|
+
|
|
473
|
+
sage: from sage.rings.power_series_ring_element import PowerSeries
|
|
474
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
475
|
+
sage: PowerSeries.polynomial(1 + x^2)
|
|
476
|
+
Traceback (most recent call last):
|
|
477
|
+
...
|
|
478
|
+
NotImplementedError
|
|
479
|
+
"""
|
|
480
|
+
raise NotImplementedError
|
|
481
|
+
|
|
482
|
+
def lift_to_precision(self, absprec=None):
|
|
483
|
+
"""
|
|
484
|
+
Return a congruent power series with absolute precision at least
|
|
485
|
+
``absprec``.
|
|
486
|
+
|
|
487
|
+
INPUT:
|
|
488
|
+
|
|
489
|
+
- ``absprec`` -- integer or ``None`` (default: ``None``); the
|
|
490
|
+
absolute precision of the result. If ``None``, lifts to an exact
|
|
491
|
+
element.
|
|
492
|
+
|
|
493
|
+
EXAMPLES::
|
|
494
|
+
|
|
495
|
+
sage: A.<t> = PowerSeriesRing(GF(5))
|
|
496
|
+
sage: x = t + t^2 + O(t^5)
|
|
497
|
+
sage: x.lift_to_precision(10)
|
|
498
|
+
t + t^2 + O(t^10)
|
|
499
|
+
sage: x.lift_to_precision()
|
|
500
|
+
t + t^2
|
|
501
|
+
"""
|
|
502
|
+
if absprec is not None and absprec <= self.precision_absolute():
|
|
503
|
+
return self
|
|
504
|
+
|
|
505
|
+
exact = self._parent(self.list())
|
|
506
|
+
if absprec is None:
|
|
507
|
+
return exact
|
|
508
|
+
else:
|
|
509
|
+
return exact.add_bigoh(absprec)
|
|
510
|
+
|
|
511
|
+
def __copy__(self):
|
|
512
|
+
"""
|
|
513
|
+
Return this power series. Power series are immutable so copy can
|
|
514
|
+
safely just return the same polynomial.
|
|
515
|
+
|
|
516
|
+
EXAMPLES::
|
|
517
|
+
|
|
518
|
+
sage: R.<q> = ZZ[[ ]]; R
|
|
519
|
+
Power Series Ring in q over Integer Ring
|
|
520
|
+
sage: f = 1 + 3*q + O(q^10)
|
|
521
|
+
sage: copy(f) is f # !!! ok since power series are immutable.
|
|
522
|
+
True
|
|
523
|
+
"""
|
|
524
|
+
return self
|
|
525
|
+
|
|
526
|
+
def base_ring(self):
|
|
527
|
+
"""
|
|
528
|
+
Return the base ring that this power series is defined over.
|
|
529
|
+
|
|
530
|
+
EXAMPLES::
|
|
531
|
+
|
|
532
|
+
sage: R.<t> = GF(49,'alpha')[[]] # needs sage.rings.finite_rings
|
|
533
|
+
sage: (t^2 + O(t^3)).base_ring() # needs sage.rings.finite_rings
|
|
534
|
+
Finite Field in alpha of size 7^2
|
|
535
|
+
"""
|
|
536
|
+
return self._parent.base_ring()
|
|
537
|
+
|
|
538
|
+
def padded_list(self, n=None):
|
|
539
|
+
"""
|
|
540
|
+
Return a list of coefficients of ``self`` up to (but not including)
|
|
541
|
+
`q^n`.
|
|
542
|
+
|
|
543
|
+
Includes 0s in the list on the right so that the list has length `n`.
|
|
544
|
+
|
|
545
|
+
INPUT:
|
|
546
|
+
|
|
547
|
+
- ``n`` -- (optional) an integer that is at least 0. If ``n`` is
|
|
548
|
+
not given, it will be taken to be the precision of ``self``,
|
|
549
|
+
unless this is ``+Infinity``, in which case we just return
|
|
550
|
+
``self.list()``.
|
|
551
|
+
|
|
552
|
+
EXAMPLES::
|
|
553
|
+
|
|
554
|
+
sage: R.<q> = PowerSeriesRing(QQ)
|
|
555
|
+
sage: f = 1 - 17*q + 13*q^2 + 10*q^4 + O(q^7)
|
|
556
|
+
sage: f.list()
|
|
557
|
+
[1, -17, 13, 0, 10]
|
|
558
|
+
sage: f.padded_list(7)
|
|
559
|
+
[1, -17, 13, 0, 10, 0, 0]
|
|
560
|
+
sage: f.padded_list(10)
|
|
561
|
+
[1, -17, 13, 0, 10, 0, 0, 0, 0, 0]
|
|
562
|
+
sage: f.padded_list(3)
|
|
563
|
+
[1, -17, 13]
|
|
564
|
+
sage: f.padded_list()
|
|
565
|
+
[1, -17, 13, 0, 10, 0, 0]
|
|
566
|
+
sage: g = 1 - 17*q + 13*q^2 + 10*q^4
|
|
567
|
+
sage: g.list()
|
|
568
|
+
[1, -17, 13, 0, 10]
|
|
569
|
+
sage: g.padded_list()
|
|
570
|
+
[1, -17, 13, 0, 10]
|
|
571
|
+
sage: g.padded_list(10)
|
|
572
|
+
[1, -17, 13, 0, 10, 0, 0, 0, 0, 0]
|
|
573
|
+
"""
|
|
574
|
+
if n is None:
|
|
575
|
+
if self._prec is infinity:
|
|
576
|
+
return self.list()
|
|
577
|
+
else:
|
|
578
|
+
n = self._prec
|
|
579
|
+
if n < 0:
|
|
580
|
+
raise ValueError("n must be at least 0")
|
|
581
|
+
v = self.list()
|
|
582
|
+
if len(v) < n:
|
|
583
|
+
z = self._parent.base_ring()(0)
|
|
584
|
+
return v + [z]*(n - len(v))
|
|
585
|
+
else:
|
|
586
|
+
return v[:int(n)]
|
|
587
|
+
|
|
588
|
+
def prec(self):
|
|
589
|
+
"""
|
|
590
|
+
The precision of `...+O(x^r)` is by definition
|
|
591
|
+
`r`.
|
|
592
|
+
|
|
593
|
+
EXAMPLES::
|
|
594
|
+
|
|
595
|
+
sage: R.<t> = ZZ[[]]
|
|
596
|
+
sage: (t^2 + O(t^3)).prec()
|
|
597
|
+
3
|
|
598
|
+
sage: (1 - t^2 + O(t^100)).prec()
|
|
599
|
+
100
|
|
600
|
+
"""
|
|
601
|
+
return self._prec
|
|
602
|
+
|
|
603
|
+
def precision_absolute(self):
|
|
604
|
+
"""
|
|
605
|
+
Return the absolute precision of this series.
|
|
606
|
+
|
|
607
|
+
By definition, the absolute precision of
|
|
608
|
+
`...+O(x^r)` is `r`.
|
|
609
|
+
|
|
610
|
+
EXAMPLES::
|
|
611
|
+
|
|
612
|
+
sage: R.<t> = ZZ[[]]
|
|
613
|
+
sage: (t^2 + O(t^3)).precision_absolute()
|
|
614
|
+
3
|
|
615
|
+
sage: (1 - t^2 + O(t^100)).precision_absolute()
|
|
616
|
+
100
|
|
617
|
+
"""
|
|
618
|
+
return self.prec()
|
|
619
|
+
|
|
620
|
+
def precision_relative(self):
|
|
621
|
+
"""
|
|
622
|
+
Return the relative precision of this series, that
|
|
623
|
+
is the difference between its absolute precision
|
|
624
|
+
and its valuation.
|
|
625
|
+
|
|
626
|
+
By convention, the relative precision of `0` (or
|
|
627
|
+
`O(x^r)` for any `r`) is `0`.
|
|
628
|
+
|
|
629
|
+
EXAMPLES::
|
|
630
|
+
|
|
631
|
+
sage: R.<t> = ZZ[[]]
|
|
632
|
+
sage: (t^2 + O(t^3)).precision_relative()
|
|
633
|
+
1
|
|
634
|
+
sage: (1 - t^2 + O(t^100)).precision_relative()
|
|
635
|
+
100
|
|
636
|
+
sage: O(t^4).precision_relative()
|
|
637
|
+
0
|
|
638
|
+
"""
|
|
639
|
+
if self.is_zero():
|
|
640
|
+
return 0
|
|
641
|
+
else:
|
|
642
|
+
return self.prec() - self.valuation()
|
|
643
|
+
|
|
644
|
+
def _repr_(self):
|
|
645
|
+
"""
|
|
646
|
+
Return the string representation of this power series.
|
|
647
|
+
|
|
648
|
+
EXAMPLES::
|
|
649
|
+
|
|
650
|
+
sage: R.<t> = ZZ[[]]
|
|
651
|
+
sage: (t^2 + O(t^3))._repr_()
|
|
652
|
+
't^2 + O(t^3)'
|
|
653
|
+
|
|
654
|
+
::
|
|
655
|
+
|
|
656
|
+
sage: R.<t> = QQ[[]]
|
|
657
|
+
sage: 1 / (1+2*t +O(t^5))
|
|
658
|
+
1 - 2*t + 4*t^2 - 8*t^3 + 16*t^4 + O(t^5)
|
|
659
|
+
|
|
660
|
+
::
|
|
661
|
+
|
|
662
|
+
sage: R.<t> = PowerSeriesRing(QQ, sparse=True)
|
|
663
|
+
sage: 1 / (1+2*t +O(t^5))
|
|
664
|
+
1 - 2*t + 4*t^2 - 8*t^3 + 16*t^4 + O(t^5)
|
|
665
|
+
sage: -13/2 * t^3 + 5*t^5 + O(t^10)
|
|
666
|
+
-13/2*t^3 + 5*t^5 + O(t^10)
|
|
667
|
+
"""
|
|
668
|
+
if self.is_zero():
|
|
669
|
+
if self.prec() is infinity:
|
|
670
|
+
return "0"
|
|
671
|
+
else:
|
|
672
|
+
return "O(%s^%s)" % (self._parent.variable_name(), self.prec())
|
|
673
|
+
|
|
674
|
+
atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic')
|
|
675
|
+
X = self._parent.variable_name()
|
|
676
|
+
|
|
677
|
+
s = " "
|
|
678
|
+
if self.is_sparse():
|
|
679
|
+
f = self.polynomial()
|
|
680
|
+
m = f.degree() + 1
|
|
681
|
+
d = f._dict_unsafe()
|
|
682
|
+
coeffs = sorted(d.items())
|
|
683
|
+
for (n, x) in coeffs:
|
|
684
|
+
x = repr(x)
|
|
685
|
+
if x != '0':
|
|
686
|
+
if s != ' ':
|
|
687
|
+
s += " + "
|
|
688
|
+
if not atomic_repr and n > 0 and (x.find("+") != -1 or x.find("-") != -1):
|
|
689
|
+
x = "(%s)" % x
|
|
690
|
+
if n > 1:
|
|
691
|
+
var = "*%s^%s" % (X, n)
|
|
692
|
+
elif n==1:
|
|
693
|
+
var = "*%s" % X
|
|
694
|
+
else:
|
|
695
|
+
var = ""
|
|
696
|
+
s += "%s%s" % (x, var)
|
|
697
|
+
else:
|
|
698
|
+
v = self.list()
|
|
699
|
+
m = len(v)
|
|
700
|
+
first = True
|
|
701
|
+
for n in range(m):
|
|
702
|
+
x = v[n]
|
|
703
|
+
x = repr(x)
|
|
704
|
+
if x != '0':
|
|
705
|
+
if not first:
|
|
706
|
+
s += " + "
|
|
707
|
+
if not atomic_repr and n > 0 and (x[1:].find("+") != -1 or x[1:].find("-") != -1):
|
|
708
|
+
x = "(%s)" % x
|
|
709
|
+
if n > 1:
|
|
710
|
+
var = "*%s^%s" % (X, n)
|
|
711
|
+
elif n==1:
|
|
712
|
+
var = "*%s" % X
|
|
713
|
+
else:
|
|
714
|
+
var = ""
|
|
715
|
+
s += "%s%s" % (x, var)
|
|
716
|
+
first = False
|
|
717
|
+
# end
|
|
718
|
+
|
|
719
|
+
s = s.replace(" + -", " - ")
|
|
720
|
+
s = s.replace(" 1*"," ")
|
|
721
|
+
s = s.replace(" -1*", " -")
|
|
722
|
+
if not (self._prec is infinity):
|
|
723
|
+
if self._prec == 0:
|
|
724
|
+
bigoh = "O(1)"
|
|
725
|
+
elif self._prec == 1:
|
|
726
|
+
bigoh = "O(%s)" % self._parent.variable_name()
|
|
727
|
+
else:
|
|
728
|
+
bigoh = "O(%s^%s)" % (self._parent.variable_name(),self._prec)
|
|
729
|
+
if s==" ":
|
|
730
|
+
return bigoh
|
|
731
|
+
s += " + %s" % bigoh
|
|
732
|
+
return s[1:]
|
|
733
|
+
|
|
734
|
+
def _latex_(self):
|
|
735
|
+
r"""
|
|
736
|
+
Return the latex representation of this power series.
|
|
737
|
+
|
|
738
|
+
EXAMPLES::
|
|
739
|
+
|
|
740
|
+
sage: R.<t> = QQ[[]]
|
|
741
|
+
sage: f = -1/2 * t + 2/3*t^2 - 9/7 * t^15 + O(t^20); f
|
|
742
|
+
-1/2*t + 2/3*t^2 - 9/7*t^15 + O(t^20)
|
|
743
|
+
sage: latex(f)
|
|
744
|
+
-\frac{1}{2} t + \frac{2}{3} t^{2} - \frac{9}{7} t^{15} + O(t^{20})
|
|
745
|
+
|
|
746
|
+
Check that :issue:`26606` is fixed::
|
|
747
|
+
|
|
748
|
+
sage: R.<beta> = QQ[]
|
|
749
|
+
sage: S.<x> = R[[]]
|
|
750
|
+
sage: latex(beta*x)
|
|
751
|
+
\beta x
|
|
752
|
+
"""
|
|
753
|
+
if self.is_zero():
|
|
754
|
+
if self.prec() is infinity:
|
|
755
|
+
return "0"
|
|
756
|
+
else:
|
|
757
|
+
return "0 + \\cdots"
|
|
758
|
+
s = " "
|
|
759
|
+
v = self.list()
|
|
760
|
+
m = len(v)
|
|
761
|
+
X = self._parent.latex_variable_names()[0]
|
|
762
|
+
atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic')
|
|
763
|
+
first = True
|
|
764
|
+
for n in range(m):
|
|
765
|
+
x = v[n]
|
|
766
|
+
x = sage.misc.latex.latex(x)
|
|
767
|
+
if x != '0':
|
|
768
|
+
if not first:
|
|
769
|
+
s += " + "
|
|
770
|
+
if not atomic_repr and n > 0 and (x[1:].find("+") != -1 or x[1:].find("-") != -1):
|
|
771
|
+
x = "\\left(%s\\right)" % x
|
|
772
|
+
if n > 1:
|
|
773
|
+
var = "%s^{%s}" % (X, n)
|
|
774
|
+
elif n==1:
|
|
775
|
+
var = "%s" % X
|
|
776
|
+
else:
|
|
777
|
+
var = ""
|
|
778
|
+
if n > 0:
|
|
779
|
+
s += "%s| %s" % (x, var)
|
|
780
|
+
else:
|
|
781
|
+
s += repr(x)
|
|
782
|
+
first = False
|
|
783
|
+
|
|
784
|
+
s = s.replace(" + -", " - ")
|
|
785
|
+
s = s.replace(" -1|", " -")
|
|
786
|
+
s = s.replace(" 1|"," ")
|
|
787
|
+
s = s.replace("|","")
|
|
788
|
+
if not (self._prec is infinity):
|
|
789
|
+
if self._prec == 0:
|
|
790
|
+
bigoh = "O(1)"
|
|
791
|
+
elif self._prec == 1:
|
|
792
|
+
bigoh = "O(%s)" % (X,)
|
|
793
|
+
else:
|
|
794
|
+
bigoh = "O(%s^{%s})" % (X, self._prec)
|
|
795
|
+
if s == " ":
|
|
796
|
+
return bigoh
|
|
797
|
+
s += " + %s" % bigoh
|
|
798
|
+
return s.lstrip(" ")
|
|
799
|
+
|
|
800
|
+
def truncate(self, prec=infinity):
|
|
801
|
+
"""
|
|
802
|
+
The polynomial obtained from power series by truncation.
|
|
803
|
+
|
|
804
|
+
EXAMPLES::
|
|
805
|
+
|
|
806
|
+
sage: R.<I> = GF(2)[[]]
|
|
807
|
+
sage: f = 1/(1+I+O(I^8)); f
|
|
808
|
+
1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8)
|
|
809
|
+
sage: f.truncate(5)
|
|
810
|
+
I^4 + I^3 + I^2 + I + 1
|
|
811
|
+
"""
|
|
812
|
+
if prec is infinity:
|
|
813
|
+
prec = self._prec
|
|
814
|
+
a = self.list()
|
|
815
|
+
v = [a[i] for i in range(min(prec, len(a)))]
|
|
816
|
+
return self._parent._poly_ring()(v)
|
|
817
|
+
|
|
818
|
+
cdef _inplace_truncate(self, long prec):
|
|
819
|
+
return self.truncate(prec)
|
|
820
|
+
|
|
821
|
+
def add_bigoh(self, prec):
|
|
822
|
+
r"""
|
|
823
|
+
Return the power series of precision at most ``prec`` got by adding
|
|
824
|
+
`O(q^\text{prec})` to `f`, where `q` is the variable.
|
|
825
|
+
|
|
826
|
+
EXAMPLES::
|
|
827
|
+
|
|
828
|
+
sage: R.<A> = RDF[[]]
|
|
829
|
+
sage: f = (1+A+O(A^5))^5; f
|
|
830
|
+
1.0 + 5.0*A + 10.0*A^2 + 10.0*A^3 + 5.0*A^4 + O(A^5)
|
|
831
|
+
sage: f.add_bigoh(3)
|
|
832
|
+
1.0 + 5.0*A + 10.0*A^2 + O(A^3)
|
|
833
|
+
sage: f.add_bigoh(5)
|
|
834
|
+
1.0 + 5.0*A + 10.0*A^2 + 10.0*A^3 + 5.0*A^4 + O(A^5)
|
|
835
|
+
"""
|
|
836
|
+
if prec is infinity or prec > self.prec():
|
|
837
|
+
return self
|
|
838
|
+
a = self.list()
|
|
839
|
+
v = [a[i] for i in range(min(prec, len(a)))]
|
|
840
|
+
return self._parent(v, prec)
|
|
841
|
+
|
|
842
|
+
def __getitem__(self, n):
|
|
843
|
+
r"""
|
|
844
|
+
Return the coefficient of `t^n` in this power series, where
|
|
845
|
+
`t` is the indeterminate of the power series ring.
|
|
846
|
+
|
|
847
|
+
If `n` is negative return 0. If `n` is beyond the precision, raise an
|
|
848
|
+
:exc:`IndexError`.
|
|
849
|
+
|
|
850
|
+
EXAMPLES::
|
|
851
|
+
|
|
852
|
+
sage: # needs sage.rings.complex_double sage.symbolic
|
|
853
|
+
sage: R.<m> = CDF[[]]
|
|
854
|
+
sage: f = CDF(pi)^2 + m^3 + CDF(e)*m^4 + O(m^10); f # abs tol 5e-16
|
|
855
|
+
9.869604401089358 + 0.0*m + 0.0*m^2 + 1.0*m^3 + 2.718281828459045*m^4 + O(m^10)
|
|
856
|
+
sage: f[-5]
|
|
857
|
+
0.0
|
|
858
|
+
sage: f[0]
|
|
859
|
+
9.869604401089358
|
|
860
|
+
sage: f[4] # abs tol 5e-16
|
|
861
|
+
2.718281828459045
|
|
862
|
+
sage: f[9]
|
|
863
|
+
0.0
|
|
864
|
+
sage: f[10]
|
|
865
|
+
Traceback (most recent call last):
|
|
866
|
+
...
|
|
867
|
+
IndexError: coefficient not known
|
|
868
|
+
sage: f[1000]
|
|
869
|
+
Traceback (most recent call last):
|
|
870
|
+
...
|
|
871
|
+
IndexError: coefficient not known
|
|
872
|
+
"""
|
|
873
|
+
if n<0:
|
|
874
|
+
return self.base_ring()(0)
|
|
875
|
+
c = self.list()
|
|
876
|
+
if n >= len(c):
|
|
877
|
+
if self._prec > n:
|
|
878
|
+
return self.base_ring()(0)
|
|
879
|
+
else:
|
|
880
|
+
raise IndexError("coefficient not known")
|
|
881
|
+
return c[n]
|
|
882
|
+
|
|
883
|
+
def common_prec(self, f):
|
|
884
|
+
r"""
|
|
885
|
+
Return minimum precision of `f` and ``self``.
|
|
886
|
+
|
|
887
|
+
EXAMPLES::
|
|
888
|
+
|
|
889
|
+
sage: R.<t> = PowerSeriesRing(QQ)
|
|
890
|
+
|
|
891
|
+
::
|
|
892
|
+
|
|
893
|
+
sage: f = t + t^2 + O(t^3)
|
|
894
|
+
sage: g = t + t^3 + t^4 + O(t^4)
|
|
895
|
+
sage: f.common_prec(g)
|
|
896
|
+
3
|
|
897
|
+
sage: g.common_prec(f)
|
|
898
|
+
3
|
|
899
|
+
|
|
900
|
+
::
|
|
901
|
+
|
|
902
|
+
sage: f = t + t^2 + O(t^3)
|
|
903
|
+
sage: g = t^2
|
|
904
|
+
sage: f.common_prec(g)
|
|
905
|
+
3
|
|
906
|
+
sage: g.common_prec(f)
|
|
907
|
+
3
|
|
908
|
+
|
|
909
|
+
::
|
|
910
|
+
|
|
911
|
+
sage: f = t + t^2
|
|
912
|
+
sage: f = t^2
|
|
913
|
+
sage: f.common_prec(g)
|
|
914
|
+
+Infinity
|
|
915
|
+
"""
|
|
916
|
+
if self.prec() is infinity:
|
|
917
|
+
return f.prec()
|
|
918
|
+
elif f.prec() is infinity:
|
|
919
|
+
return self.prec()
|
|
920
|
+
return min(self.prec(), f.prec())
|
|
921
|
+
|
|
922
|
+
cdef common_prec_c(self, PowerSeries f):
|
|
923
|
+
if self._prec is infinity:
|
|
924
|
+
return f._prec
|
|
925
|
+
elif f._prec is infinity:
|
|
926
|
+
return self._prec
|
|
927
|
+
elif self._prec < f._prec:
|
|
928
|
+
return self._prec
|
|
929
|
+
else:
|
|
930
|
+
return f._prec
|
|
931
|
+
|
|
932
|
+
def _mul_prec(self, RingElement right_r):
|
|
933
|
+
cdef PowerSeries right = <PowerSeries>right_r
|
|
934
|
+
sp = self._prec
|
|
935
|
+
rp = right._prec
|
|
936
|
+
if sp is infinity:
|
|
937
|
+
if rp is infinity:
|
|
938
|
+
prec = infinity
|
|
939
|
+
else:
|
|
940
|
+
prec = rp + self.valuation()
|
|
941
|
+
else: # sp != infinity
|
|
942
|
+
if rp is infinity:
|
|
943
|
+
prec = sp + right.valuation()
|
|
944
|
+
else:
|
|
945
|
+
prec = min(rp + self.valuation(), sp + right.valuation())
|
|
946
|
+
# endif
|
|
947
|
+
return prec
|
|
948
|
+
|
|
949
|
+
def __bool__(self):
|
|
950
|
+
"""
|
|
951
|
+
Return ``True`` if this power series is not equal to 0.
|
|
952
|
+
|
|
953
|
+
EXAMPLES::
|
|
954
|
+
|
|
955
|
+
sage: R.<q> = ZZ[[ ]]; R
|
|
956
|
+
Power Series Ring in q over Integer Ring
|
|
957
|
+
sage: f = 1 + 3*q + O(q^10)
|
|
958
|
+
sage: f.is_zero()
|
|
959
|
+
False
|
|
960
|
+
sage: (0 + O(q^2)).is_zero()
|
|
961
|
+
True
|
|
962
|
+
sage: R(0).is_zero()
|
|
963
|
+
True
|
|
964
|
+
sage: (0 + O(q^1000)).is_zero()
|
|
965
|
+
True
|
|
966
|
+
"""
|
|
967
|
+
return not not self.polynomial()
|
|
968
|
+
|
|
969
|
+
def is_unit(self):
|
|
970
|
+
"""
|
|
971
|
+
Return ``True`` if this power series is invertible.
|
|
972
|
+
|
|
973
|
+
A power series is invertible precisely when the
|
|
974
|
+
constant term is invertible.
|
|
975
|
+
|
|
976
|
+
EXAMPLES::
|
|
977
|
+
|
|
978
|
+
sage: R.<t> = PowerSeriesRing(ZZ)
|
|
979
|
+
sage: (-1 + t - t^5).is_unit()
|
|
980
|
+
True
|
|
981
|
+
sage: (3 + t - t^5).is_unit()
|
|
982
|
+
False
|
|
983
|
+
sage: O(t^0).is_unit()
|
|
984
|
+
False
|
|
985
|
+
|
|
986
|
+
AUTHORS:
|
|
987
|
+
|
|
988
|
+
- David Harvey (2006-09-03)
|
|
989
|
+
"""
|
|
990
|
+
# Return False for O(t^0) (the only power-series-ring element with precision_absolute == 0).
|
|
991
|
+
if self.precision_absolute() == 0:
|
|
992
|
+
return False
|
|
993
|
+
return self[0].is_unit()
|
|
994
|
+
|
|
995
|
+
def inverse(self):
|
|
996
|
+
"""
|
|
997
|
+
Return the inverse of self, i.e., self^(-1).
|
|
998
|
+
|
|
999
|
+
EXAMPLES::
|
|
1000
|
+
|
|
1001
|
+
sage: R.<t> = PowerSeriesRing(QQ, sparse=True)
|
|
1002
|
+
sage: t.inverse()
|
|
1003
|
+
t^-1
|
|
1004
|
+
sage: type(_)
|
|
1005
|
+
<class 'sage.rings.laurent_series_ring_element.LaurentSeries'>
|
|
1006
|
+
sage: (1-t).inverse()
|
|
1007
|
+
1 + t + t^2 + t^3 + t^4 + t^5 + t^6 + t^7 + t^8 + ...
|
|
1008
|
+
"""
|
|
1009
|
+
return ~self
|
|
1010
|
+
|
|
1011
|
+
def valuation_zero_part(self):
|
|
1012
|
+
r"""
|
|
1013
|
+
Factor ``self`` as `q^n \cdot (a_0 + a_1 q + \cdots)` with
|
|
1014
|
+
`a_0` nonzero. Then this function returns
|
|
1015
|
+
`a_0 + a_1 q + \cdots` .
|
|
1016
|
+
|
|
1017
|
+
.. NOTE::
|
|
1018
|
+
|
|
1019
|
+
This valuation zero part need not be a unit if, e.g.,
|
|
1020
|
+
`a_0` is not invertible in the base ring.
|
|
1021
|
+
|
|
1022
|
+
EXAMPLES::
|
|
1023
|
+
|
|
1024
|
+
sage: R.<t> = PowerSeriesRing(QQ)
|
|
1025
|
+
sage: ((1/3)*t^5*(17-2/3*t^3)).valuation_zero_part()
|
|
1026
|
+
17/3 - 2/9*t^3
|
|
1027
|
+
|
|
1028
|
+
In this example the valuation 0 part is not a unit::
|
|
1029
|
+
|
|
1030
|
+
sage: R.<t> = PowerSeriesRing(ZZ, sparse=True)
|
|
1031
|
+
sage: u = (-2*t^5*(17-t^3)).valuation_zero_part(); u
|
|
1032
|
+
-34 + 2*t^3
|
|
1033
|
+
sage: u.is_unit()
|
|
1034
|
+
False
|
|
1035
|
+
sage: u.valuation()
|
|
1036
|
+
0
|
|
1037
|
+
"""
|
|
1038
|
+
if self.is_zero():
|
|
1039
|
+
raise ValueError("power series has no valuation 0 part")
|
|
1040
|
+
n = self.valuation()
|
|
1041
|
+
if n == 0:
|
|
1042
|
+
return self
|
|
1043
|
+
elif self.is_dense():
|
|
1044
|
+
v = self.list()[int(n):]
|
|
1045
|
+
else:
|
|
1046
|
+
n = int(n)
|
|
1047
|
+
v = {}
|
|
1048
|
+
for k, x in self.monomial_coefficients().items():
|
|
1049
|
+
if k >= n:
|
|
1050
|
+
v[k-n] = x
|
|
1051
|
+
return self._parent(v, self.prec()-n)
|
|
1052
|
+
|
|
1053
|
+
cpdef _div_(self, denom_r):
|
|
1054
|
+
"""
|
|
1055
|
+
EXAMPLES::
|
|
1056
|
+
|
|
1057
|
+
sage: k.<t> = QQ[[]]
|
|
1058
|
+
sage: t/t
|
|
1059
|
+
1
|
|
1060
|
+
sage: (t/(t^3 + 1)) * (t^3 + 1)
|
|
1061
|
+
t + O(t^21)
|
|
1062
|
+
sage: (t^5/(t^2 - 2)) * (t^2 -2 )
|
|
1063
|
+
t^5 + O(t^25)
|
|
1064
|
+
|
|
1065
|
+
TESTS:
|
|
1066
|
+
|
|
1067
|
+
The following tests against bugs that were fixed in :issue:`8972`::
|
|
1068
|
+
|
|
1069
|
+
sage: P.<t> = ZZ[]
|
|
1070
|
+
sage: R.<x> = P[[]]
|
|
1071
|
+
sage: 1/(t*x)
|
|
1072
|
+
1/t*x^-1
|
|
1073
|
+
sage: R.<x> = ZZ[[]]
|
|
1074
|
+
sage: (1/x).parent()
|
|
1075
|
+
Laurent Series Ring in x over Rational Field
|
|
1076
|
+
sage: F = FractionField(R)
|
|
1077
|
+
sage: 1/x in F
|
|
1078
|
+
True
|
|
1079
|
+
sage: (1/(2*x)).parent()
|
|
1080
|
+
Laurent Series Ring in x over Rational Field
|
|
1081
|
+
"""
|
|
1082
|
+
denom = <PowerSeries>denom_r
|
|
1083
|
+
if denom.is_zero():
|
|
1084
|
+
raise ZeroDivisionError("Can't divide by something indistinguishable from 0")
|
|
1085
|
+
u = denom.valuation_zero_part()
|
|
1086
|
+
inv = ~u # inverse
|
|
1087
|
+
|
|
1088
|
+
v = denom.valuation()
|
|
1089
|
+
if v > self.valuation():
|
|
1090
|
+
try:
|
|
1091
|
+
R = self._parent.fraction_field()
|
|
1092
|
+
except (TypeError, NotImplementedError): # no integral domain
|
|
1093
|
+
R = self._parent.laurent_series_ring()
|
|
1094
|
+
return R(self) / R(denom)
|
|
1095
|
+
|
|
1096
|
+
# Algorithm: Cancel common factors of q from top and bottom,
|
|
1097
|
+
# then invert the denominator. We do the cancellation first
|
|
1098
|
+
# because we can only invert a unit (and remain in the ring
|
|
1099
|
+
# of power series).
|
|
1100
|
+
|
|
1101
|
+
if v > 0:
|
|
1102
|
+
num = self >> v
|
|
1103
|
+
else:
|
|
1104
|
+
num = self
|
|
1105
|
+
return num*inv
|
|
1106
|
+
|
|
1107
|
+
def __mod__(self, other):
|
|
1108
|
+
"""
|
|
1109
|
+
EXAMPLES::
|
|
1110
|
+
|
|
1111
|
+
sage: R.<T> = Qp(7)[[]] # needs sage.rings.padics
|
|
1112
|
+
sage: f = (48*67 + 46*67^2)*T + (1 + 42*67 + 5*67^3)*T^2 + O(T^3) # needs sage.rings.padics
|
|
1113
|
+
sage: f % 67 # needs sage.rings.padics
|
|
1114
|
+
T^2 + O(T^3)
|
|
1115
|
+
"""
|
|
1116
|
+
from sage.rings.power_series_ring import PowerSeriesRing
|
|
1117
|
+
if isinstance(other, (int, Integer)):
|
|
1118
|
+
return PowerSeriesRing(IntegerModRing(other), self.variable())(self)
|
|
1119
|
+
raise NotImplementedError("Mod on power series ring elements not defined except modulo an integer.")
|
|
1120
|
+
|
|
1121
|
+
def __pow__(self, r, dummy):
|
|
1122
|
+
"""
|
|
1123
|
+
EXAMPLES::
|
|
1124
|
+
|
|
1125
|
+
sage: x = QQ[['x']].0
|
|
1126
|
+
sage: f = x^2 + x^4 + O(x^6)
|
|
1127
|
+
sage: f^(1/2)
|
|
1128
|
+
x + 1/2*x^3 + O(x^5)
|
|
1129
|
+
sage: f^7
|
|
1130
|
+
x^14 + 7*x^16 + O(x^18)
|
|
1131
|
+
sage: f^(7/2)
|
|
1132
|
+
x^7 + 7/2*x^9 + O(x^11)
|
|
1133
|
+
sage: h = x^2 + 2*x^4 + x^6
|
|
1134
|
+
sage: h^(1/2)
|
|
1135
|
+
x + x^3
|
|
1136
|
+
sage: O(x^4)^(1/2)
|
|
1137
|
+
O(x^2)
|
|
1138
|
+
"""
|
|
1139
|
+
try:
|
|
1140
|
+
right = QQ.coerce(r)
|
|
1141
|
+
except TypeError:
|
|
1142
|
+
raise ValueError("exponent must be a rational number")
|
|
1143
|
+
|
|
1144
|
+
if right.denominator() == 1:
|
|
1145
|
+
right = right.numerator()
|
|
1146
|
+
return super().__pow__(right, dummy)
|
|
1147
|
+
|
|
1148
|
+
if self.is_zero():
|
|
1149
|
+
return self.parent()(0).O((self.prec()*right).floor())
|
|
1150
|
+
|
|
1151
|
+
d = right.denominator()
|
|
1152
|
+
n = right.numerator()
|
|
1153
|
+
|
|
1154
|
+
return self.nth_root(d)**n
|
|
1155
|
+
|
|
1156
|
+
def shift(self, n):
|
|
1157
|
+
r"""
|
|
1158
|
+
Return this power series multiplied by the power `t^n`.
|
|
1159
|
+
|
|
1160
|
+
If `n` is negative, terms below `t^{-n}` are discarded.
|
|
1161
|
+
|
|
1162
|
+
This power series is left unchanged.
|
|
1163
|
+
|
|
1164
|
+
.. NOTE::
|
|
1165
|
+
|
|
1166
|
+
Despite the fact that higher order terms are printed to the
|
|
1167
|
+
right in a power series, right shifting decreases the
|
|
1168
|
+
powers of `t`, while left shifting increases them.
|
|
1169
|
+
This is to be consistent with polynomials, integers, etc.
|
|
1170
|
+
|
|
1171
|
+
EXAMPLES::
|
|
1172
|
+
|
|
1173
|
+
sage: R.<t> = PowerSeriesRing(QQ['y'], 't', 5)
|
|
1174
|
+
sage: f = ~(1+t); f
|
|
1175
|
+
1 - t + t^2 - t^3 + t^4 + O(t^5)
|
|
1176
|
+
sage: f.shift(3)
|
|
1177
|
+
t^3 - t^4 + t^5 - t^6 + t^7 + O(t^8)
|
|
1178
|
+
sage: f >> 2
|
|
1179
|
+
1 - t + t^2 + O(t^3)
|
|
1180
|
+
sage: f << 10
|
|
1181
|
+
t^10 - t^11 + t^12 - t^13 + t^14 + O(t^15)
|
|
1182
|
+
sage: t << 29
|
|
1183
|
+
t^30
|
|
1184
|
+
|
|
1185
|
+
AUTHORS:
|
|
1186
|
+
|
|
1187
|
+
- Robert Bradshaw (2007-04-18)
|
|
1188
|
+
"""
|
|
1189
|
+
if not n:
|
|
1190
|
+
return self
|
|
1191
|
+
prec = max(0, self.prec() + Integer(n))
|
|
1192
|
+
return self._parent(self.polynomial().shift(n), prec)
|
|
1193
|
+
|
|
1194
|
+
def __lshift__(self, n):
|
|
1195
|
+
"""
|
|
1196
|
+
Left-shift this power series by `n`, i.e., multiply by `t^n`.
|
|
1197
|
+
|
|
1198
|
+
EXAMPLES::
|
|
1199
|
+
|
|
1200
|
+
sage: # needs sage.libs.pari
|
|
1201
|
+
sage: R.<x> = PowerSeriesRing(QQ, implementation='pari')
|
|
1202
|
+
sage: f = exp(x) + O(x^7); f
|
|
1203
|
+
1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7)
|
|
1204
|
+
sage: f << 2
|
|
1205
|
+
x^2 + x^3 + 1/2*x^4 + 1/6*x^5 + 1/24*x^6 + 1/120*x^7 + 1/720*x^8 + O(x^9)
|
|
1206
|
+
sage: (f << 99) >> 99
|
|
1207
|
+
1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7)
|
|
1208
|
+
"""
|
|
1209
|
+
return self.shift(n)
|
|
1210
|
+
|
|
1211
|
+
def __rshift__(self, n):
|
|
1212
|
+
"""
|
|
1213
|
+
Right-shift this power series by `n`, i.e., divide by `t^n`.
|
|
1214
|
+
|
|
1215
|
+
Terms below `t^n` are discarded.
|
|
1216
|
+
|
|
1217
|
+
EXAMPLES::
|
|
1218
|
+
|
|
1219
|
+
sage: # needs sage.libs.pari
|
|
1220
|
+
sage: R.<x> = PowerSeriesRing(QQ, implementation='pari')
|
|
1221
|
+
sage: f = exp(x) + O(x^7)
|
|
1222
|
+
sage: f >> 3
|
|
1223
|
+
1/6 + 1/24*x + 1/120*x^2 + 1/720*x^3 + O(x^4)
|
|
1224
|
+
sage: f >> 7
|
|
1225
|
+
O(x^0)
|
|
1226
|
+
sage: f >> 99
|
|
1227
|
+
O(x^0)
|
|
1228
|
+
sage: (f >> 99) << 99
|
|
1229
|
+
O(x^99)
|
|
1230
|
+
"""
|
|
1231
|
+
return self.shift(-n)
|
|
1232
|
+
|
|
1233
|
+
def is_monomial(self):
|
|
1234
|
+
"""
|
|
1235
|
+
Return ``True`` if this element is a monomial. That is, if ``self`` is
|
|
1236
|
+
`x^n` for some nonnegative integer `n`.
|
|
1237
|
+
|
|
1238
|
+
EXAMPLES::
|
|
1239
|
+
|
|
1240
|
+
sage: k.<z> = PowerSeriesRing(QQ, 'z')
|
|
1241
|
+
sage: z.is_monomial()
|
|
1242
|
+
True
|
|
1243
|
+
sage: k(1).is_monomial()
|
|
1244
|
+
True
|
|
1245
|
+
sage: (z+1).is_monomial()
|
|
1246
|
+
False
|
|
1247
|
+
sage: (z^2909).is_monomial()
|
|
1248
|
+
True
|
|
1249
|
+
sage: (3*z^2909).is_monomial()
|
|
1250
|
+
False
|
|
1251
|
+
"""
|
|
1252
|
+
|
|
1253
|
+
return self.polynomial().is_monomial()
|
|
1254
|
+
|
|
1255
|
+
def map_coefficients(self, f, new_base_ring=None):
|
|
1256
|
+
r"""
|
|
1257
|
+
Return the series obtained by applying ``f`` to the nonzero
|
|
1258
|
+
coefficients of ``self``.
|
|
1259
|
+
|
|
1260
|
+
If ``f`` is a :class:`sage.categories.map.Map`, then the resulting
|
|
1261
|
+
series will be defined over the codomain of ``f``. Otherwise, the
|
|
1262
|
+
resulting polynomial will be over the same ring as ``self``. Set
|
|
1263
|
+
``new_base_ring`` to override this behaviour.
|
|
1264
|
+
|
|
1265
|
+
INPUT:
|
|
1266
|
+
|
|
1267
|
+
- ``f`` -- a callable that will be applied to the coefficients of ``self``
|
|
1268
|
+
|
|
1269
|
+
- ``new_base_ring`` -- (optional) if given, the resulting polynomial
|
|
1270
|
+
will be defined over this ring
|
|
1271
|
+
|
|
1272
|
+
EXAMPLES::
|
|
1273
|
+
|
|
1274
|
+
sage: R.<x> = SR[[]] # needs sage.symbolic
|
|
1275
|
+
sage: f = (1+I)*x^2 + 3*x - I # needs sage.symbolic
|
|
1276
|
+
sage: f.map_coefficients(lambda z: z.conjugate()) # needs sage.symbolic
|
|
1277
|
+
I + 3*x + (-I + 1)*x^2
|
|
1278
|
+
sage: R.<x> = ZZ[[]]
|
|
1279
|
+
sage: f = x^2 + 2
|
|
1280
|
+
sage: f.map_coefficients(lambda a: a + 42)
|
|
1281
|
+
44 + 43*x^2
|
|
1282
|
+
|
|
1283
|
+
Examples with different base ring::
|
|
1284
|
+
|
|
1285
|
+
sage: R.<x> = ZZ[[]]
|
|
1286
|
+
sage: k = GF(2)
|
|
1287
|
+
sage: residue = lambda x: k(x)
|
|
1288
|
+
sage: f = 4*x^2+x+3
|
|
1289
|
+
sage: g = f.map_coefficients(residue); g
|
|
1290
|
+
1 + x
|
|
1291
|
+
sage: g.parent()
|
|
1292
|
+
Power Series Ring in x over Integer Ring
|
|
1293
|
+
sage: g = f.map_coefficients(residue, new_base_ring=k); g
|
|
1294
|
+
1 + x
|
|
1295
|
+
sage: g.parent()
|
|
1296
|
+
Power Series Ring in x over Finite Field of size 2
|
|
1297
|
+
sage: residue = k.coerce_map_from(ZZ)
|
|
1298
|
+
sage: g = f.map_coefficients(residue); g
|
|
1299
|
+
1 + x
|
|
1300
|
+
sage: g.parent()
|
|
1301
|
+
Power Series Ring in x over Finite Field of size 2
|
|
1302
|
+
|
|
1303
|
+
Tests other implementations::
|
|
1304
|
+
|
|
1305
|
+
sage: # needs sage.libs.pari
|
|
1306
|
+
sage: R.<q> = PowerSeriesRing(GF(11), implementation='pari')
|
|
1307
|
+
sage: f = q - q^3 + O(q^10)
|
|
1308
|
+
sage: f.map_coefficients(lambda c: c - 2)
|
|
1309
|
+
10*q + 8*q^3 + O(q^10)
|
|
1310
|
+
"""
|
|
1311
|
+
pol = self.polynomial()
|
|
1312
|
+
res = pol.map_coefficients(f, new_base_ring)
|
|
1313
|
+
if res.base_ring() != pol.base_ring():
|
|
1314
|
+
return self.parent().change_ring(res.base_ring())(res, self.prec())
|
|
1315
|
+
else:
|
|
1316
|
+
return self.parent()(res, self.prec())
|
|
1317
|
+
|
|
1318
|
+
def jacobi_continued_fraction(self):
|
|
1319
|
+
r"""
|
|
1320
|
+
Return the Jacobi continued fraction of ``self``.
|
|
1321
|
+
|
|
1322
|
+
The J-fraction or Jacobi continued fraction of a power series
|
|
1323
|
+
is a continued fraction expansion with steps of size two. We use
|
|
1324
|
+
the following convention
|
|
1325
|
+
|
|
1326
|
+
.. MATH::
|
|
1327
|
+
|
|
1328
|
+
1 / (1 + A_0 t + B_0 t^2 / (1 + A_1 t + B_1 t^2 / (1 + \cdots)))
|
|
1329
|
+
|
|
1330
|
+
OUTPUT:
|
|
1331
|
+
|
|
1332
|
+
tuple of pairs `(A_n, B_n)` for `n \geq 0`
|
|
1333
|
+
|
|
1334
|
+
The expansion is done as long as possible given the precision.
|
|
1335
|
+
Whenever the expansion is not well-defined, because it would
|
|
1336
|
+
require to divide by zero, an exception is raised.
|
|
1337
|
+
|
|
1338
|
+
See section 2.7 of [Kra1999det]_ for the close relationship
|
|
1339
|
+
of this kind of expansion with Hankel determinants and
|
|
1340
|
+
orthogonal polynomials.
|
|
1341
|
+
|
|
1342
|
+
EXAMPLES::
|
|
1343
|
+
|
|
1344
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
1345
|
+
sage: s = sum(factorial(k) * t**k for k in range(12)).O(12)
|
|
1346
|
+
sage: s.jacobi_continued_fraction()
|
|
1347
|
+
((-1, -1), (-3, -4), (-5, -9), (-7, -16), (-9, -25))
|
|
1348
|
+
|
|
1349
|
+
Another example::
|
|
1350
|
+
|
|
1351
|
+
sage: (log(1+t)/t).jacobi_continued_fraction()
|
|
1352
|
+
((1/2, -1/12),
|
|
1353
|
+
(1/2, -1/15),
|
|
1354
|
+
(1/2, -9/140),
|
|
1355
|
+
(1/2, -4/63),
|
|
1356
|
+
(1/2, -25/396),
|
|
1357
|
+
(1/2, -9/143),
|
|
1358
|
+
(1/2, -49/780),
|
|
1359
|
+
(1/2, -16/255),
|
|
1360
|
+
(1/2, -81/1292))
|
|
1361
|
+
|
|
1362
|
+
TESTS::
|
|
1363
|
+
|
|
1364
|
+
sage: (t).jacobi_continued_fraction()
|
|
1365
|
+
Traceback (most recent call last):
|
|
1366
|
+
...
|
|
1367
|
+
ValueError: vanishing constant term, no expansion
|
|
1368
|
+
sage: (1/(1+3*t)).jacobi_continued_fraction()
|
|
1369
|
+
Traceback (most recent call last):
|
|
1370
|
+
...
|
|
1371
|
+
ValueError: vanishing term, no further expansion
|
|
1372
|
+
"""
|
|
1373
|
+
t = self.parent().gen()
|
|
1374
|
+
if self[0] == 0:
|
|
1375
|
+
raise ValueError('vanishing constant term, no expansion')
|
|
1376
|
+
serie = self / self[0]
|
|
1377
|
+
resu = []
|
|
1378
|
+
while serie.prec() >= 3:
|
|
1379
|
+
u = serie.inverse()
|
|
1380
|
+
A, B = u[1], u[2]
|
|
1381
|
+
resu.append((A, B))
|
|
1382
|
+
if B == 0:
|
|
1383
|
+
raise ValueError('vanishing term, no further expansion')
|
|
1384
|
+
serie = (u - 1 - A * t) / (B * t ** 2)
|
|
1385
|
+
return tuple(resu)
|
|
1386
|
+
|
|
1387
|
+
def super_delta_fraction(self, delta):
|
|
1388
|
+
r"""
|
|
1389
|
+
Return the super delta continued fraction of ``self``.
|
|
1390
|
+
|
|
1391
|
+
This is a continued fraction of the following shape:
|
|
1392
|
+
|
|
1393
|
+
.. MATH::
|
|
1394
|
+
|
|
1395
|
+
\cfrac{v_0 x^{k_0}} {U_1(x) -
|
|
1396
|
+
\cfrac{v_1 x^{k_0 + k_1 + \delta}} {U_2(x) -
|
|
1397
|
+
\cfrac{v_2 x^{k_0 + k_1 + k_2 + \delta}} {U_3(x) - \cdots} } }
|
|
1398
|
+
|
|
1399
|
+
where each `U_j(x) = 1 + u_j(x) x`.
|
|
1400
|
+
|
|
1401
|
+
INPUT:
|
|
1402
|
+
|
|
1403
|
+
- ``delta`` -- positive integer, usually 2
|
|
1404
|
+
|
|
1405
|
+
OUTPUT: list of `(v_j, k_j, U_{j+1}(x))_{j \geq 0}`
|
|
1406
|
+
|
|
1407
|
+
REFERENCES:
|
|
1408
|
+
|
|
1409
|
+
- [Han2016]_
|
|
1410
|
+
|
|
1411
|
+
EXAMPLES::
|
|
1412
|
+
|
|
1413
|
+
sage: deg = 30
|
|
1414
|
+
sage: PS = PowerSeriesRing(QQ, 'q', default_prec=deg+1)
|
|
1415
|
+
sage: q = PS.gen()
|
|
1416
|
+
sage: F = prod([(1+q**k).add_bigoh(deg+1) for k in range(1,deg)])
|
|
1417
|
+
sage: F.super_delta_fraction(2)
|
|
1418
|
+
[(1, 0, -q + 1),
|
|
1419
|
+
(1, 1, q + 1),
|
|
1420
|
+
(-1, 2, -q^3 + q^2 - q + 1),
|
|
1421
|
+
(1, 1, q^2 + q + 1),
|
|
1422
|
+
(-1, 0, -q + 1),
|
|
1423
|
+
(-1, 1, q^2 + q + 1),
|
|
1424
|
+
(-1, 0, -q + 1),
|
|
1425
|
+
(1, 1, 3*q^2 + 2*q + 1),
|
|
1426
|
+
(-4, 0, -q + 1)]
|
|
1427
|
+
|
|
1428
|
+
A Jacobi continued fraction::
|
|
1429
|
+
|
|
1430
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
1431
|
+
sage: s = sum(factorial(k) * t**k for k in range(12)).O(12)
|
|
1432
|
+
sage: s.super_delta_fraction(2)
|
|
1433
|
+
[(1, 0, -t + 1),
|
|
1434
|
+
(1, 0, -3*t + 1),
|
|
1435
|
+
(4, 0, -5*t + 1),
|
|
1436
|
+
(9, 0, -7*t + 1),
|
|
1437
|
+
(16, 0, -9*t + 1),
|
|
1438
|
+
(25, 0, -11*t + 1)]
|
|
1439
|
+
"""
|
|
1440
|
+
q = self.parent().gen()
|
|
1441
|
+
Gi, Gj = self.parent().one(), self
|
|
1442
|
+
deg = self.prec()
|
|
1443
|
+
|
|
1444
|
+
list_vkU = []
|
|
1445
|
+
di = Gi.valuation()
|
|
1446
|
+
ci = Gi[di]
|
|
1447
|
+
|
|
1448
|
+
while deg >= 0:
|
|
1449
|
+
dj = Gj.valuation()
|
|
1450
|
+
cj = Gj[dj]
|
|
1451
|
+
k, v = dj - di, cj / ci
|
|
1452
|
+
c = v * q**k
|
|
1453
|
+
gi = Gi.add_bigoh(dj + delta)
|
|
1454
|
+
gj = Gj.add_bigoh(k + dj + delta)
|
|
1455
|
+
U = (c * gi / gj).truncate()
|
|
1456
|
+
Gk = (U * Gj - Gi * c) >> (k + delta)
|
|
1457
|
+
deg -= 2 * k + delta
|
|
1458
|
+
if deg < 0:
|
|
1459
|
+
break
|
|
1460
|
+
list_vkU.append((v, k, U))
|
|
1461
|
+
if deg == 0 or Gk.degree() == -1:
|
|
1462
|
+
break
|
|
1463
|
+
di, ci, Gi, Gj = dj, cj, Gj, Gk
|
|
1464
|
+
|
|
1465
|
+
return list_vkU
|
|
1466
|
+
|
|
1467
|
+
def stieltjes_continued_fraction(self):
|
|
1468
|
+
r"""
|
|
1469
|
+
Return the Stieltjes continued fraction of ``self``.
|
|
1470
|
+
|
|
1471
|
+
The S-fraction or Stieltjes continued fraction of a power series
|
|
1472
|
+
is a continued fraction expansion with steps of size one. We use
|
|
1473
|
+
the following convention
|
|
1474
|
+
|
|
1475
|
+
.. MATH::
|
|
1476
|
+
|
|
1477
|
+
1 / (1 - A_1 t / (1 - A_2 t / (1 - A_3 t / (1 - \cdots))))
|
|
1478
|
+
|
|
1479
|
+
OUTPUT: `A_n` for `n \geq 1`
|
|
1480
|
+
|
|
1481
|
+
The expansion is done as long as possible given the precision.
|
|
1482
|
+
Whenever the expansion is not well-defined, because it would
|
|
1483
|
+
require to divide by zero, an exception is raised.
|
|
1484
|
+
|
|
1485
|
+
EXAMPLES::
|
|
1486
|
+
|
|
1487
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
1488
|
+
sage: s = sum(catalan_number(k) * t**k for k in range(12)).O(12)
|
|
1489
|
+
sage: s.stieltjes_continued_fraction()
|
|
1490
|
+
(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
|
|
1491
|
+
|
|
1492
|
+
Another example::
|
|
1493
|
+
|
|
1494
|
+
sage: (exp(t)).stieltjes_continued_fraction()
|
|
1495
|
+
(1,
|
|
1496
|
+
-1/2,
|
|
1497
|
+
1/6,
|
|
1498
|
+
-1/6,
|
|
1499
|
+
1/10,
|
|
1500
|
+
-1/10,
|
|
1501
|
+
1/14,
|
|
1502
|
+
-1/14,
|
|
1503
|
+
1/18,
|
|
1504
|
+
-1/18,
|
|
1505
|
+
1/22,
|
|
1506
|
+
-1/22,
|
|
1507
|
+
1/26,
|
|
1508
|
+
-1/26,
|
|
1509
|
+
1/30,
|
|
1510
|
+
-1/30,
|
|
1511
|
+
1/34,
|
|
1512
|
+
-1/34,
|
|
1513
|
+
1/38)
|
|
1514
|
+
|
|
1515
|
+
TESTS::
|
|
1516
|
+
|
|
1517
|
+
sage: (t).stieltjes_continued_fraction()
|
|
1518
|
+
Traceback (most recent call last):
|
|
1519
|
+
...
|
|
1520
|
+
ValueError: vanishing constant term, no expansion
|
|
1521
|
+
sage: (1/(1+3*t)).stieltjes_continued_fraction()
|
|
1522
|
+
Traceback (most recent call last):
|
|
1523
|
+
...
|
|
1524
|
+
ValueError: vanishing term, no further expansion
|
|
1525
|
+
"""
|
|
1526
|
+
t = self.parent().gen()
|
|
1527
|
+
if self[0] == 0:
|
|
1528
|
+
raise ValueError('vanishing constant term, no expansion')
|
|
1529
|
+
serie = self / self[0]
|
|
1530
|
+
resu = []
|
|
1531
|
+
while serie.prec() >= 2:
|
|
1532
|
+
u = serie.inverse()
|
|
1533
|
+
A = -u[1]
|
|
1534
|
+
resu.append(A)
|
|
1535
|
+
if A == 0:
|
|
1536
|
+
raise ValueError('vanishing term, no further expansion')
|
|
1537
|
+
serie = (u - 1) / (-A * t)
|
|
1538
|
+
return tuple(resu)
|
|
1539
|
+
|
|
1540
|
+
def is_square(self):
|
|
1541
|
+
"""
|
|
1542
|
+
Return ``True`` if this function has a square root in this ring, e.g.,
|
|
1543
|
+
there is an element `y` in ``self.parent()``
|
|
1544
|
+
such that `y^2` equals ``self``.
|
|
1545
|
+
|
|
1546
|
+
ALGORITHM: If the base ring is a field, this is true whenever the
|
|
1547
|
+
power series has even valuation and the leading coefficient is a
|
|
1548
|
+
perfect square.
|
|
1549
|
+
|
|
1550
|
+
For an integral domain, it attempts the square root in the
|
|
1551
|
+
fraction field and tests whether or not the result lies in the
|
|
1552
|
+
original ring.
|
|
1553
|
+
|
|
1554
|
+
EXAMPLES::
|
|
1555
|
+
|
|
1556
|
+
sage: K.<t> = PowerSeriesRing(QQ, 't', 5)
|
|
1557
|
+
sage: (1+t).is_square()
|
|
1558
|
+
True
|
|
1559
|
+
sage: (2+t).is_square()
|
|
1560
|
+
False
|
|
1561
|
+
sage: (2+t.change_ring(RR)).is_square()
|
|
1562
|
+
True
|
|
1563
|
+
sage: t.is_square()
|
|
1564
|
+
False
|
|
1565
|
+
sage: K.<t> = PowerSeriesRing(ZZ, 't', 5)
|
|
1566
|
+
sage: (1+t).is_square()
|
|
1567
|
+
False
|
|
1568
|
+
sage: f = (1+t)^100
|
|
1569
|
+
sage: f.is_square()
|
|
1570
|
+
True
|
|
1571
|
+
"""
|
|
1572
|
+
val = self.valuation()
|
|
1573
|
+
if val is not infinity and val % 2 == 1:
|
|
1574
|
+
return False
|
|
1575
|
+
elif not self[val].is_square():
|
|
1576
|
+
return False
|
|
1577
|
+
elif self.base_ring() in _Fields:
|
|
1578
|
+
return True
|
|
1579
|
+
else:
|
|
1580
|
+
try:
|
|
1581
|
+
self.parent()(self.sqrt())
|
|
1582
|
+
return True
|
|
1583
|
+
except TypeError:
|
|
1584
|
+
return False
|
|
1585
|
+
|
|
1586
|
+
def sqrt(self, prec=None, extend=False, all=False, name=None):
|
|
1587
|
+
r"""
|
|
1588
|
+
Return a square root of ``self``.
|
|
1589
|
+
|
|
1590
|
+
INPUT:
|
|
1591
|
+
|
|
1592
|
+
- ``prec`` -- integer (default: ``None``); if not ``None`` and the
|
|
1593
|
+
series has infinite precision, truncates series at precision ``prec``
|
|
1594
|
+
|
|
1595
|
+
- ``extend`` -- boolean (default: ``False``); if ``True``, return a
|
|
1596
|
+
square root in an extension ring, if necessary. Otherwise, raise
|
|
1597
|
+
a :exc:`ValueError` if the square root is not in the base power series
|
|
1598
|
+
ring. For example, if ``extend`` is ``True``, the square root of a
|
|
1599
|
+
power series with odd degree leading coefficient is
|
|
1600
|
+
defined as an element of a formal extension ring.
|
|
1601
|
+
|
|
1602
|
+
- ``name`` -- string; if ``extend`` is ``True``, you must also
|
|
1603
|
+
specify the print name of the formal square root
|
|
1604
|
+
|
|
1605
|
+
- ``all`` -- boolean (default: ``False``); if ``True``, return all
|
|
1606
|
+
square roots of ``self``, instead of just one
|
|
1607
|
+
|
|
1608
|
+
ALGORITHM: Newton's method
|
|
1609
|
+
|
|
1610
|
+
.. MATH::
|
|
1611
|
+
|
|
1612
|
+
x_{i+1} = \frac{1}{2}( x_i + \mathrm{self}/x_i )
|
|
1613
|
+
|
|
1614
|
+
EXAMPLES::
|
|
1615
|
+
|
|
1616
|
+
sage: K.<t> = PowerSeriesRing(QQ, 't', 5)
|
|
1617
|
+
sage: sqrt(t^2)
|
|
1618
|
+
t
|
|
1619
|
+
sage: sqrt(1 + t)
|
|
1620
|
+
1 + 1/2*t - 1/8*t^2 + 1/16*t^3 - 5/128*t^4 + O(t^5)
|
|
1621
|
+
sage: sqrt(4 + t)
|
|
1622
|
+
2 + 1/4*t - 1/64*t^2 + 1/512*t^3 - 5/16384*t^4 + O(t^5)
|
|
1623
|
+
|
|
1624
|
+
sage: # needs sage.libs.singular
|
|
1625
|
+
sage: u = sqrt(2 + t, prec=2, extend=True, name='alpha'); u
|
|
1626
|
+
alpha
|
|
1627
|
+
sage: u^2
|
|
1628
|
+
2 + t
|
|
1629
|
+
sage: u.parent()
|
|
1630
|
+
Univariate Quotient Polynomial Ring in alpha
|
|
1631
|
+
over Power Series Ring in t over Rational Field
|
|
1632
|
+
with modulus x^2 - 2 - t
|
|
1633
|
+
|
|
1634
|
+
sage: K.<t> = PowerSeriesRing(QQ, 't', 50)
|
|
1635
|
+
sage: sqrt(1 + 2*t + t^2)
|
|
1636
|
+
1 + t
|
|
1637
|
+
sage: sqrt(t^2 + 2*t^4 + t^6)
|
|
1638
|
+
t + t^3
|
|
1639
|
+
sage: sqrt(1 + t + t^2 + 7*t^3)^2
|
|
1640
|
+
1 + t + t^2 + 7*t^3 + O(t^50)
|
|
1641
|
+
sage: sqrt(K(0))
|
|
1642
|
+
0
|
|
1643
|
+
sage: sqrt(t^2)
|
|
1644
|
+
t
|
|
1645
|
+
|
|
1646
|
+
::
|
|
1647
|
+
|
|
1648
|
+
sage: # needs sage.rings.complex_double
|
|
1649
|
+
sage: K.<t> = PowerSeriesRing(CDF, 5)
|
|
1650
|
+
sage: v = sqrt(-1 + t + t^3, all=True); v
|
|
1651
|
+
[1.0*I - 0.5*I*t - 0.125*I*t^2 - 0.5625*I*t^3 - 0.2890625*I*t^4 + O(t^5),
|
|
1652
|
+
-1.0*I + 0.5*I*t + 0.125*I*t^2 + 0.5625*I*t^3 + 0.2890625*I*t^4 + O(t^5)]
|
|
1653
|
+
sage: [a^2 for a in v]
|
|
1654
|
+
[-1.0 + 1.0*t + 0.0*t^2 + 1.0*t^3 + O(t^5), -1.0 + 1.0*t + 0.0*t^2 + 1.0*t^3 + O(t^5)]
|
|
1655
|
+
|
|
1656
|
+
A formal square root::
|
|
1657
|
+
|
|
1658
|
+
sage: # needs sage.libs.singular
|
|
1659
|
+
sage: K.<t> = PowerSeriesRing(QQ, 5)
|
|
1660
|
+
sage: f = 2*t + t^3 + O(t^4)
|
|
1661
|
+
sage: s = f.sqrt(extend=True, name='sqrtf'); s
|
|
1662
|
+
sqrtf
|
|
1663
|
+
sage: s^2
|
|
1664
|
+
2*t + t^3 + O(t^4)
|
|
1665
|
+
sage: parent(s)
|
|
1666
|
+
Univariate Quotient Polynomial Ring in sqrtf
|
|
1667
|
+
over Power Series Ring in t over Rational Field
|
|
1668
|
+
with modulus x^2 - 2*t - t^3 + O(t^4)
|
|
1669
|
+
|
|
1670
|
+
TESTS::
|
|
1671
|
+
|
|
1672
|
+
sage: R.<x> = QQ[[]]
|
|
1673
|
+
sage: (x^10/2).sqrt()
|
|
1674
|
+
Traceback (most recent call last):
|
|
1675
|
+
...
|
|
1676
|
+
ValueError: unable to take the square root of 1/2
|
|
1677
|
+
|
|
1678
|
+
Check :issue:`30655`::
|
|
1679
|
+
|
|
1680
|
+
sage: t = polygen(QQ, 't')
|
|
1681
|
+
sage: x = t.parent()[['x']].0
|
|
1682
|
+
sage: W = (t*x + 1 - x).O(3)
|
|
1683
|
+
sage: W.sqrt()
|
|
1684
|
+
1 + (1/2*t - 1/2)*x + (-1/8*t^2 + 1/4*t - 1/8)*x^2 + O(x^3)
|
|
1685
|
+
|
|
1686
|
+
AUTHORS:
|
|
1687
|
+
|
|
1688
|
+
- Robert Bradshaw
|
|
1689
|
+
|
|
1690
|
+
- William Stein
|
|
1691
|
+
"""
|
|
1692
|
+
if self.is_zero():
|
|
1693
|
+
ans = self._parent(0).O(self.prec()/2)
|
|
1694
|
+
if all:
|
|
1695
|
+
return [ans]
|
|
1696
|
+
else:
|
|
1697
|
+
return ans
|
|
1698
|
+
|
|
1699
|
+
if all and not self.base_ring().is_integral_domain():
|
|
1700
|
+
raise NotImplementedError('all roots not implemented over a non-integral domain')
|
|
1701
|
+
|
|
1702
|
+
formal_sqrt = False
|
|
1703
|
+
u = self.valuation_zero_part()
|
|
1704
|
+
# TODO, fix underlying element sqrt()
|
|
1705
|
+
try:
|
|
1706
|
+
try:
|
|
1707
|
+
s = u[0].sqrt(extend=False)
|
|
1708
|
+
except TypeError:
|
|
1709
|
+
s = u[0].sqrt()
|
|
1710
|
+
except ValueError:
|
|
1711
|
+
formal_sqrt = True
|
|
1712
|
+
if self.degree() == 0:
|
|
1713
|
+
if not formal_sqrt:
|
|
1714
|
+
a = self.parent()([s], self.prec())
|
|
1715
|
+
if all:
|
|
1716
|
+
return [a, -a]
|
|
1717
|
+
else:
|
|
1718
|
+
return a
|
|
1719
|
+
|
|
1720
|
+
val = self.valuation()
|
|
1721
|
+
|
|
1722
|
+
if formal_sqrt or val % 2:
|
|
1723
|
+
if extend:
|
|
1724
|
+
if name is None:
|
|
1725
|
+
raise ValueError("the square root generates an extension, so you must specify the name of the square root")
|
|
1726
|
+
R = self._parent['x']
|
|
1727
|
+
S = R.quotient(R([-self, 0, 1]), names=name)
|
|
1728
|
+
a = S.gen()
|
|
1729
|
+
if all:
|
|
1730
|
+
if not self.base_ring().is_integral_domain():
|
|
1731
|
+
raise NotImplementedError('all roots not implemented over a non-integral domain')
|
|
1732
|
+
return [a, -a]
|
|
1733
|
+
else:
|
|
1734
|
+
return a
|
|
1735
|
+
elif formal_sqrt:
|
|
1736
|
+
raise ValueError("unable to take the square root of %s" % u[0])
|
|
1737
|
+
else:
|
|
1738
|
+
raise ValueError("power series does not have a square root since it has odd valuation.")
|
|
1739
|
+
|
|
1740
|
+
pr = self.prec()
|
|
1741
|
+
if pr == infinity:
|
|
1742
|
+
test_exact = True
|
|
1743
|
+
if prec is None:
|
|
1744
|
+
pr = self._parent.default_prec()
|
|
1745
|
+
else:
|
|
1746
|
+
pr = prec
|
|
1747
|
+
else:
|
|
1748
|
+
test_exact = False
|
|
1749
|
+
prec = pr
|
|
1750
|
+
|
|
1751
|
+
R = s.parent()
|
|
1752
|
+
a = self.valuation_zero_part()
|
|
1753
|
+
P = self._parent
|
|
1754
|
+
if not P.base_ring().has_coerce_map_from(R):
|
|
1755
|
+
a = a.change_ring(R)
|
|
1756
|
+
half = ~R(2)
|
|
1757
|
+
|
|
1758
|
+
from sage.misc.misc import newton_method_sizes
|
|
1759
|
+
|
|
1760
|
+
s = a.parent()([s])
|
|
1761
|
+
for cur_prec in newton_method_sizes(prec)[1:]:
|
|
1762
|
+
(<PowerSeries>s)._prec = cur_prec
|
|
1763
|
+
s = half * (s + a/s)
|
|
1764
|
+
|
|
1765
|
+
ans = s
|
|
1766
|
+
if val != 0:
|
|
1767
|
+
ans *= P.gen(0) ** (val // 2)
|
|
1768
|
+
if test_exact and ans.degree() < prec/2:
|
|
1769
|
+
if ans*ans == self:
|
|
1770
|
+
(<PowerSeries>ans)._prec = infinity
|
|
1771
|
+
|
|
1772
|
+
if all:
|
|
1773
|
+
return [ans, -ans] # since over an integral domain
|
|
1774
|
+
else:
|
|
1775
|
+
return ans
|
|
1776
|
+
|
|
1777
|
+
def square_root(self):
|
|
1778
|
+
"""
|
|
1779
|
+
Return the square root of ``self`` in this ring. If this cannot be done,
|
|
1780
|
+
then an error will be raised.
|
|
1781
|
+
|
|
1782
|
+
This function succeeds if and only if
|
|
1783
|
+
``self``. :meth:`.is_square`
|
|
1784
|
+
|
|
1785
|
+
EXAMPLES::
|
|
1786
|
+
|
|
1787
|
+
sage: K.<t> = PowerSeriesRing(QQ, 't', 5)
|
|
1788
|
+
sage: (1 + t).square_root()
|
|
1789
|
+
1 + 1/2*t - 1/8*t^2 + 1/16*t^3 - 5/128*t^4 + O(t^5)
|
|
1790
|
+
sage: (2 + t).square_root()
|
|
1791
|
+
Traceback (most recent call last):
|
|
1792
|
+
...
|
|
1793
|
+
ValueError: Square root does not live in this ring.
|
|
1794
|
+
sage: (2 + t.change_ring(RR)).square_root() # needs sage.rings.real_mpfr
|
|
1795
|
+
1.41421356237309 + 0.353553390593274*t - 0.0441941738241592*t^2
|
|
1796
|
+
+ 0.0110485434560398*t^3 - 0.00345266983001244*t^4 + O(t^5)
|
|
1797
|
+
sage: t.square_root()
|
|
1798
|
+
Traceback (most recent call last):
|
|
1799
|
+
...
|
|
1800
|
+
ValueError: Square root not defined for power series of odd valuation.
|
|
1801
|
+
sage: K.<t> = PowerSeriesRing(ZZ, 't', 5)
|
|
1802
|
+
sage: f = (1+t)^20
|
|
1803
|
+
sage: f.square_root()
|
|
1804
|
+
1 + 10*t + 45*t^2 + 120*t^3 + 210*t^4 + O(t^5)
|
|
1805
|
+
sage: f = 1 + t
|
|
1806
|
+
sage: f.square_root()
|
|
1807
|
+
Traceback (most recent call last):
|
|
1808
|
+
...
|
|
1809
|
+
ValueError: Square root does not live in this ring.
|
|
1810
|
+
|
|
1811
|
+
AUTHORS:
|
|
1812
|
+
|
|
1813
|
+
- Robert Bradshaw
|
|
1814
|
+
"""
|
|
1815
|
+
val = self.valuation()
|
|
1816
|
+
if val is not infinity and val % 2 == 1:
|
|
1817
|
+
raise ValueError("Square root not defined for power series of odd valuation.")
|
|
1818
|
+
elif not self[val].is_square():
|
|
1819
|
+
raise ValueError("Square root does not live in this ring.")
|
|
1820
|
+
elif self.base_ring() in _Fields:
|
|
1821
|
+
return self.sqrt()
|
|
1822
|
+
else:
|
|
1823
|
+
try:
|
|
1824
|
+
return self.parent()(self.sqrt())
|
|
1825
|
+
except TypeError:
|
|
1826
|
+
raise ValueError("Square root does not live in this ring.")
|
|
1827
|
+
|
|
1828
|
+
def nth_root(self, n, prec=None):
|
|
1829
|
+
r"""
|
|
1830
|
+
Return the ``n``-th root of this power series.
|
|
1831
|
+
|
|
1832
|
+
INPUT:
|
|
1833
|
+
|
|
1834
|
+
- ``n`` -- integer
|
|
1835
|
+
|
|
1836
|
+
- ``prec`` -- integer (optional); precision of the result. Though, if
|
|
1837
|
+
this series has finite precision, then the result cannot have larger
|
|
1838
|
+
precision.
|
|
1839
|
+
|
|
1840
|
+
EXAMPLES::
|
|
1841
|
+
|
|
1842
|
+
sage: R.<x> = QQ[[]]
|
|
1843
|
+
sage: (1+x).nth_root(5)
|
|
1844
|
+
1 + 1/5*x - 2/25*x^2 + ... + 12039376311816/2384185791015625*x^19 + O(x^20)
|
|
1845
|
+
|
|
1846
|
+
sage: (1 + x + O(x^5)).nth_root(5)
|
|
1847
|
+
1 + 1/5*x - 2/25*x^2 + 6/125*x^3 - 21/625*x^4 + O(x^5)
|
|
1848
|
+
|
|
1849
|
+
Check that the results are consistent with taking log and exponential::
|
|
1850
|
+
|
|
1851
|
+
sage: R.<x> = PowerSeriesRing(QQ, default_prec=100)
|
|
1852
|
+
sage: p = (1 + 2*x - x^4)**200
|
|
1853
|
+
sage: p1 = p.nth_root(1000, prec=100)
|
|
1854
|
+
sage: p2 = (p.log()/1000).exp()
|
|
1855
|
+
sage: p1.prec() == p2.prec() == 100
|
|
1856
|
+
True
|
|
1857
|
+
sage: p1.polynomial() == p2.polynomial()
|
|
1858
|
+
True
|
|
1859
|
+
|
|
1860
|
+
Positive characteristic::
|
|
1861
|
+
|
|
1862
|
+
sage: R.<u> = GF(3)[[]]
|
|
1863
|
+
sage: p = 1 + 2 * u^2
|
|
1864
|
+
sage: p.nth_root(4)
|
|
1865
|
+
1 + 2*u^2 + u^6 + 2*u^8 + u^12 + 2*u^14 + O(u^20)
|
|
1866
|
+
sage: p.nth_root(4)**4
|
|
1867
|
+
1 + 2*u^2 + O(u^20)
|
|
1868
|
+
|
|
1869
|
+
TESTS:
|
|
1870
|
+
|
|
1871
|
+
Check that exact roots show infinite precision::
|
|
1872
|
+
|
|
1873
|
+
sage: ((1+x)^5).nth_root(5)
|
|
1874
|
+
1 + x
|
|
1875
|
+
|
|
1876
|
+
Check precision on `O(x^r)`::
|
|
1877
|
+
|
|
1878
|
+
sage: O(x^4).nth_root(2)
|
|
1879
|
+
O(x^2)
|
|
1880
|
+
sage: O(x^4).nth_root(3)
|
|
1881
|
+
O(x^1)
|
|
1882
|
+
sage: O(x^4).nth_root(4)
|
|
1883
|
+
O(x^1)
|
|
1884
|
+
|
|
1885
|
+
Check precision on higher valuation series::
|
|
1886
|
+
|
|
1887
|
+
sage: (x^5+x^6+O(x^7)).nth_root(5)
|
|
1888
|
+
x + 1/5*x^2 + O(x^3)
|
|
1889
|
+
"""
|
|
1890
|
+
|
|
1891
|
+
val = self.valuation()
|
|
1892
|
+
|
|
1893
|
+
if self.is_zero():
|
|
1894
|
+
if val is infinity:
|
|
1895
|
+
return self
|
|
1896
|
+
else:
|
|
1897
|
+
return self.parent()(0).O(val // n)
|
|
1898
|
+
|
|
1899
|
+
if val is not infinity and val % n != 0:
|
|
1900
|
+
raise ValueError("power series valuation is not a multiple of %s" % n)
|
|
1901
|
+
|
|
1902
|
+
maxprec = (val // n) + self.precision_relative()
|
|
1903
|
+
|
|
1904
|
+
if prec is None:
|
|
1905
|
+
prec = maxprec
|
|
1906
|
+
if prec == infinity:
|
|
1907
|
+
prec = self.parent().default_prec()
|
|
1908
|
+
else:
|
|
1909
|
+
prec = min(maxprec, prec)
|
|
1910
|
+
|
|
1911
|
+
p = self.polynomial()
|
|
1912
|
+
q = p._nth_root_series(n, prec)
|
|
1913
|
+
ans = self.parent()(q)
|
|
1914
|
+
if not (self.prec() == infinity and q.degree() * n <= prec and q**n == p):
|
|
1915
|
+
ans = ans.add_bigoh(prec)
|
|
1916
|
+
return ans
|
|
1917
|
+
|
|
1918
|
+
def cos(self, prec=infinity):
|
|
1919
|
+
r"""
|
|
1920
|
+
Apply cos to the formal power series.
|
|
1921
|
+
|
|
1922
|
+
INPUT:
|
|
1923
|
+
|
|
1924
|
+
- ``prec`` -- integer or ``infinity``; the degree to truncate
|
|
1925
|
+
the result to
|
|
1926
|
+
|
|
1927
|
+
OUTPUT: a new power series
|
|
1928
|
+
|
|
1929
|
+
EXAMPLES:
|
|
1930
|
+
|
|
1931
|
+
For one variable::
|
|
1932
|
+
|
|
1933
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
1934
|
+
sage: f = (t + t**2).O(4)
|
|
1935
|
+
sage: cos(f)
|
|
1936
|
+
1 - 1/2*t^2 - t^3 + O(t^4)
|
|
1937
|
+
|
|
1938
|
+
For several variables::
|
|
1939
|
+
|
|
1940
|
+
sage: T.<a,b> = PowerSeriesRing(ZZ,2)
|
|
1941
|
+
sage: f = a + b + a*b + T.O(3)
|
|
1942
|
+
sage: cos(f)
|
|
1943
|
+
1 - 1/2*a^2 - a*b - 1/2*b^2 + O(a, b)^3
|
|
1944
|
+
sage: f.cos()
|
|
1945
|
+
1 - 1/2*a^2 - a*b - 1/2*b^2 + O(a, b)^3
|
|
1946
|
+
sage: f.cos(prec=2)
|
|
1947
|
+
1 + O(a, b)^2
|
|
1948
|
+
|
|
1949
|
+
If the power series has a nonzero constant coefficient `c`,
|
|
1950
|
+
one raises an error::
|
|
1951
|
+
|
|
1952
|
+
sage: g = 2+f
|
|
1953
|
+
sage: cos(g)
|
|
1954
|
+
Traceback (most recent call last):
|
|
1955
|
+
...
|
|
1956
|
+
ValueError: can only apply cos to formal power series with zero constant term
|
|
1957
|
+
|
|
1958
|
+
If no precision is specified, the default precision is used::
|
|
1959
|
+
|
|
1960
|
+
sage: T.default_prec()
|
|
1961
|
+
12
|
|
1962
|
+
sage: cos(a)
|
|
1963
|
+
1 - 1/2*a^2 + 1/24*a^4 - 1/720*a^6 + 1/40320*a^8 - 1/3628800*a^10 + O(a, b)^12
|
|
1964
|
+
sage: a.cos(prec=5)
|
|
1965
|
+
1 - 1/2*a^2 + 1/24*a^4 + O(a, b)^5
|
|
1966
|
+
sage: cos(a + T.O(5))
|
|
1967
|
+
1 - 1/2*a^2 + 1/24*a^4 + O(a, b)^5
|
|
1968
|
+
|
|
1969
|
+
TESTS::
|
|
1970
|
+
|
|
1971
|
+
sage: cos(a^2 + T.O(5))
|
|
1972
|
+
1 - 1/2*a^4 + O(a, b)^5
|
|
1973
|
+
"""
|
|
1974
|
+
R = self.parent()
|
|
1975
|
+
|
|
1976
|
+
c = self[0]
|
|
1977
|
+
if not c.is_zero():
|
|
1978
|
+
raise ValueError('can only apply cos to formal power '
|
|
1979
|
+
'series with zero constant term')
|
|
1980
|
+
x = self
|
|
1981
|
+
val = x.valuation()
|
|
1982
|
+
assert val >= 1
|
|
1983
|
+
|
|
1984
|
+
prec = min(prec, self.prec())
|
|
1985
|
+
if isinstance(prec, InfinityElement):
|
|
1986
|
+
prec = R.default_prec()
|
|
1987
|
+
n_inv_factorial = R.base_ring().one()
|
|
1988
|
+
x_pow_n = R.one()
|
|
1989
|
+
x2 = x ** 2
|
|
1990
|
+
cos_x = R.one().add_bigoh(prec)
|
|
1991
|
+
for n in range(2, prec // val + 1, 2):
|
|
1992
|
+
x_pow_n = (x_pow_n * x2).add_bigoh(prec)
|
|
1993
|
+
n_inv_factorial /= - n * (n - 1)
|
|
1994
|
+
cos_x += x_pow_n * n_inv_factorial
|
|
1995
|
+
result_bg = cos_x
|
|
1996
|
+
|
|
1997
|
+
if result_bg.base_ring() is not self.base_ring():
|
|
1998
|
+
R = R.change_ring(self.base_ring().fraction_field())
|
|
1999
|
+
return R(result_bg, prec=prec)
|
|
2000
|
+
|
|
2001
|
+
def sin(self, prec=infinity):
|
|
2002
|
+
r"""
|
|
2003
|
+
Apply sin to the formal power series.
|
|
2004
|
+
|
|
2005
|
+
INPUT:
|
|
2006
|
+
|
|
2007
|
+
- ``prec`` -- integer or ``infinity``; the degree to truncate
|
|
2008
|
+
the result to
|
|
2009
|
+
|
|
2010
|
+
OUTPUT: a new power series
|
|
2011
|
+
|
|
2012
|
+
EXAMPLES:
|
|
2013
|
+
|
|
2014
|
+
For one variable::
|
|
2015
|
+
|
|
2016
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
2017
|
+
sage: f = (t + t**2).O(4)
|
|
2018
|
+
sage: sin(f)
|
|
2019
|
+
t + t^2 - 1/6*t^3 + O(t^4)
|
|
2020
|
+
|
|
2021
|
+
For several variables::
|
|
2022
|
+
|
|
2023
|
+
sage: T.<a,b> = PowerSeriesRing(ZZ,2)
|
|
2024
|
+
sage: f = a + b + a*b + T.O(3)
|
|
2025
|
+
sage: sin(f)
|
|
2026
|
+
a + b + a*b + O(a, b)^3
|
|
2027
|
+
sage: f.sin()
|
|
2028
|
+
a + b + a*b + O(a, b)^3
|
|
2029
|
+
sage: f.sin(prec=2)
|
|
2030
|
+
a + b + O(a, b)^2
|
|
2031
|
+
|
|
2032
|
+
If the power series has a nonzero constant coefficient `c`,
|
|
2033
|
+
one raises an error::
|
|
2034
|
+
|
|
2035
|
+
sage: g = 2+f
|
|
2036
|
+
sage: sin(g)
|
|
2037
|
+
Traceback (most recent call last):
|
|
2038
|
+
...
|
|
2039
|
+
ValueError: can only apply sin to formal power series with zero constant term
|
|
2040
|
+
|
|
2041
|
+
If no precision is specified, the default precision is used::
|
|
2042
|
+
|
|
2043
|
+
sage: T.default_prec()
|
|
2044
|
+
12
|
|
2045
|
+
sage: sin(a)
|
|
2046
|
+
a - 1/6*a^3 + 1/120*a^5 - 1/5040*a^7 + 1/362880*a^9 - 1/39916800*a^11 + O(a, b)^12
|
|
2047
|
+
sage: a.sin(prec=5)
|
|
2048
|
+
a - 1/6*a^3 + O(a, b)^5
|
|
2049
|
+
sage: sin(a + T.O(5))
|
|
2050
|
+
a - 1/6*a^3 + O(a, b)^5
|
|
2051
|
+
|
|
2052
|
+
TESTS::
|
|
2053
|
+
|
|
2054
|
+
sage: sin(a^2 + T.O(5))
|
|
2055
|
+
a^2 + O(a, b)^5
|
|
2056
|
+
"""
|
|
2057
|
+
R = self.parent()
|
|
2058
|
+
|
|
2059
|
+
c = self[0]
|
|
2060
|
+
if not c.is_zero():
|
|
2061
|
+
raise ValueError('can only apply sin to formal power '
|
|
2062
|
+
'series with zero constant term')
|
|
2063
|
+
val = self.valuation()
|
|
2064
|
+
assert val >= 1
|
|
2065
|
+
|
|
2066
|
+
x = self
|
|
2067
|
+
|
|
2068
|
+
prec = min(prec, self.prec())
|
|
2069
|
+
if isinstance(prec, InfinityElement):
|
|
2070
|
+
prec = R.default_prec()
|
|
2071
|
+
n_inv_factorial = R.base_ring().one()
|
|
2072
|
+
x_pow_n = x
|
|
2073
|
+
x2 = x ** 2
|
|
2074
|
+
sin_x = x.add_bigoh(prec)
|
|
2075
|
+
for n in range(3, prec // val + 1, 2):
|
|
2076
|
+
x_pow_n = (x_pow_n * x2).add_bigoh(prec)
|
|
2077
|
+
n_inv_factorial /= - n * (n - 1)
|
|
2078
|
+
sin_x += x_pow_n * n_inv_factorial
|
|
2079
|
+
result_bg = sin_x
|
|
2080
|
+
|
|
2081
|
+
if result_bg.base_ring() is not self.base_ring():
|
|
2082
|
+
R = R.change_ring(self.base_ring().fraction_field())
|
|
2083
|
+
return R(result_bg, prec=prec)
|
|
2084
|
+
|
|
2085
|
+
def tan(self, prec=infinity):
|
|
2086
|
+
r"""
|
|
2087
|
+
Apply tan to the formal power series.
|
|
2088
|
+
|
|
2089
|
+
INPUT:
|
|
2090
|
+
|
|
2091
|
+
- ``prec`` -- integer or ``infinity``; the degree to truncate
|
|
2092
|
+
the result to
|
|
2093
|
+
|
|
2094
|
+
OUTPUT: a new power series
|
|
2095
|
+
|
|
2096
|
+
EXAMPLES:
|
|
2097
|
+
|
|
2098
|
+
For one variable::
|
|
2099
|
+
|
|
2100
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
2101
|
+
sage: f = (t + t**2).O(4)
|
|
2102
|
+
sage: tan(f)
|
|
2103
|
+
t + t^2 + 1/3*t^3 + O(t^4)
|
|
2104
|
+
|
|
2105
|
+
For several variables::
|
|
2106
|
+
|
|
2107
|
+
sage: T.<a,b> = PowerSeriesRing(ZZ,2)
|
|
2108
|
+
sage: f = a + b + a*b + T.O(3)
|
|
2109
|
+
sage: tan(f)
|
|
2110
|
+
a + b + a*b + O(a, b)^3
|
|
2111
|
+
sage: f.tan()
|
|
2112
|
+
a + b + a*b + O(a, b)^3
|
|
2113
|
+
sage: f.tan(prec=2)
|
|
2114
|
+
a + b + O(a, b)^2
|
|
2115
|
+
|
|
2116
|
+
If the power series has a nonzero constant coefficient `c`,
|
|
2117
|
+
one raises an error::
|
|
2118
|
+
|
|
2119
|
+
sage: g = 2 + f
|
|
2120
|
+
sage: tan(g)
|
|
2121
|
+
Traceback (most recent call last):
|
|
2122
|
+
...
|
|
2123
|
+
ValueError: can only apply tan to formal power series with zero constant term
|
|
2124
|
+
|
|
2125
|
+
If no precision is specified, the default precision is used::
|
|
2126
|
+
|
|
2127
|
+
sage: T.default_prec()
|
|
2128
|
+
12
|
|
2129
|
+
sage: tan(a)
|
|
2130
|
+
a + 1/3*a^3 + 2/15*a^5 + 17/315*a^7 + 62/2835*a^9 + 1382/155925*a^11 + O(a, b)^12
|
|
2131
|
+
sage: a.tan(prec=5)
|
|
2132
|
+
a + 1/3*a^3 + O(a, b)^5
|
|
2133
|
+
sage: tan(a + T.O(5))
|
|
2134
|
+
a + 1/3*a^3 + O(a, b)^5
|
|
2135
|
+
|
|
2136
|
+
TESTS::
|
|
2137
|
+
|
|
2138
|
+
sage: tan(a^2 + T.O(5))
|
|
2139
|
+
a^2 + O(a, b)^5
|
|
2140
|
+
"""
|
|
2141
|
+
if not self[0].is_zero():
|
|
2142
|
+
raise ValueError('can only apply tan to formal power '
|
|
2143
|
+
'series with zero constant term')
|
|
2144
|
+
assert self.valuation() >= 1
|
|
2145
|
+
return self.sin(prec) / self.cos(prec)
|
|
2146
|
+
|
|
2147
|
+
def sinh(self, prec=infinity):
|
|
2148
|
+
r"""
|
|
2149
|
+
Apply sinh to the formal power series.
|
|
2150
|
+
|
|
2151
|
+
INPUT:
|
|
2152
|
+
|
|
2153
|
+
- ``prec`` -- integer or ``infinity``; the degree to truncate
|
|
2154
|
+
the result to
|
|
2155
|
+
|
|
2156
|
+
OUTPUT: a new power series
|
|
2157
|
+
|
|
2158
|
+
EXAMPLES:
|
|
2159
|
+
|
|
2160
|
+
For one variable::
|
|
2161
|
+
|
|
2162
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
2163
|
+
sage: f = (t + t**2).O(4)
|
|
2164
|
+
sage: sinh(f)
|
|
2165
|
+
t + t^2 + 1/6*t^3 + O(t^4)
|
|
2166
|
+
|
|
2167
|
+
For several variables::
|
|
2168
|
+
|
|
2169
|
+
sage: T.<a,b> = PowerSeriesRing(ZZ,2)
|
|
2170
|
+
sage: f = a + b + a*b + T.O(3)
|
|
2171
|
+
sage: sinh(f)
|
|
2172
|
+
a + b + a*b + O(a, b)^3
|
|
2173
|
+
sage: f.sinh()
|
|
2174
|
+
a + b + a*b + O(a, b)^3
|
|
2175
|
+
sage: f.sinh(prec=2)
|
|
2176
|
+
a + b + O(a, b)^2
|
|
2177
|
+
|
|
2178
|
+
If the power series has a nonzero constant coefficient `c`,
|
|
2179
|
+
one raises an error::
|
|
2180
|
+
|
|
2181
|
+
sage: g = 2 + f
|
|
2182
|
+
sage: sinh(g)
|
|
2183
|
+
Traceback (most recent call last):
|
|
2184
|
+
...
|
|
2185
|
+
ValueError: can only apply sinh to formal power series with zero
|
|
2186
|
+
constant term
|
|
2187
|
+
|
|
2188
|
+
If no precision is specified, the default precision is used::
|
|
2189
|
+
|
|
2190
|
+
sage: T.default_prec()
|
|
2191
|
+
12
|
|
2192
|
+
sage: sinh(a)
|
|
2193
|
+
a + 1/6*a^3 + 1/120*a^5 + 1/5040*a^7 + 1/362880*a^9 +
|
|
2194
|
+
1/39916800*a^11 + O(a, b)^12
|
|
2195
|
+
sage: a.sinh(prec=5)
|
|
2196
|
+
a + 1/6*a^3 + O(a, b)^5
|
|
2197
|
+
sage: sinh(a + T.O(5))
|
|
2198
|
+
a + 1/6*a^3 + O(a, b)^5
|
|
2199
|
+
|
|
2200
|
+
TESTS::
|
|
2201
|
+
|
|
2202
|
+
sage: sinh(a^2 + T.O(5))
|
|
2203
|
+
a^2 + O(a, b)^5
|
|
2204
|
+
"""
|
|
2205
|
+
R = self.parent()
|
|
2206
|
+
|
|
2207
|
+
c = self[0]
|
|
2208
|
+
if not c.is_zero():
|
|
2209
|
+
raise ValueError('can only apply sinh to formal power '
|
|
2210
|
+
'series with zero constant term')
|
|
2211
|
+
val = self.valuation()
|
|
2212
|
+
assert val >= 1
|
|
2213
|
+
|
|
2214
|
+
x = self
|
|
2215
|
+
|
|
2216
|
+
prec = min(prec, self.prec())
|
|
2217
|
+
if isinstance(prec, InfinityElement):
|
|
2218
|
+
prec = R.default_prec()
|
|
2219
|
+
n_inv_factorial = R.base_ring().one()
|
|
2220
|
+
x_pow_n = x
|
|
2221
|
+
x2 = x ** 2
|
|
2222
|
+
sinh_x = x.add_bigoh(prec)
|
|
2223
|
+
for n in range(3, prec // val + 1, 2):
|
|
2224
|
+
x_pow_n = (x_pow_n * x2).add_bigoh(prec)
|
|
2225
|
+
n_inv_factorial /= n * (n - 1)
|
|
2226
|
+
sinh_x += x_pow_n * n_inv_factorial
|
|
2227
|
+
result_bg = sinh_x
|
|
2228
|
+
|
|
2229
|
+
if result_bg.base_ring() is not self.base_ring():
|
|
2230
|
+
R = R.change_ring(self.base_ring().fraction_field())
|
|
2231
|
+
return R(result_bg, prec=prec)
|
|
2232
|
+
|
|
2233
|
+
def cosh(self, prec=infinity):
|
|
2234
|
+
r"""
|
|
2235
|
+
Apply cosh to the formal power series.
|
|
2236
|
+
|
|
2237
|
+
INPUT:
|
|
2238
|
+
|
|
2239
|
+
- ``prec`` -- integer or ``infinity``; the degree to truncate
|
|
2240
|
+
the result to
|
|
2241
|
+
|
|
2242
|
+
OUTPUT: a new power series
|
|
2243
|
+
|
|
2244
|
+
EXAMPLES:
|
|
2245
|
+
|
|
2246
|
+
For one variable::
|
|
2247
|
+
|
|
2248
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
2249
|
+
sage: f = (t + t**2).O(4)
|
|
2250
|
+
sage: cosh(f)
|
|
2251
|
+
1 + 1/2*t^2 + t^3 + O(t^4)
|
|
2252
|
+
|
|
2253
|
+
For several variables::
|
|
2254
|
+
|
|
2255
|
+
sage: T.<a,b> = PowerSeriesRing(ZZ,2)
|
|
2256
|
+
sage: f = a + b + a*b + T.O(3)
|
|
2257
|
+
sage: cosh(f)
|
|
2258
|
+
1 + 1/2*a^2 + a*b + 1/2*b^2 + O(a, b)^3
|
|
2259
|
+
sage: f.cosh()
|
|
2260
|
+
1 + 1/2*a^2 + a*b + 1/2*b^2 + O(a, b)^3
|
|
2261
|
+
sage: f.cosh(prec=2)
|
|
2262
|
+
1 + O(a, b)^2
|
|
2263
|
+
|
|
2264
|
+
If the power series has a nonzero constant coefficient `c`,
|
|
2265
|
+
one raises an error::
|
|
2266
|
+
|
|
2267
|
+
sage: g = 2 + f
|
|
2268
|
+
sage: cosh(g)
|
|
2269
|
+
Traceback (most recent call last):
|
|
2270
|
+
...
|
|
2271
|
+
ValueError: can only apply cosh to formal power series with zero
|
|
2272
|
+
constant term
|
|
2273
|
+
|
|
2274
|
+
If no precision is specified, the default precision is used::
|
|
2275
|
+
|
|
2276
|
+
sage: T.default_prec()
|
|
2277
|
+
12
|
|
2278
|
+
sage: cosh(a)
|
|
2279
|
+
1 + 1/2*a^2 + 1/24*a^4 + 1/720*a^6 + 1/40320*a^8 + 1/3628800*a^10 +
|
|
2280
|
+
O(a, b)^12
|
|
2281
|
+
sage: a.cosh(prec=5)
|
|
2282
|
+
1 + 1/2*a^2 + 1/24*a^4 + O(a, b)^5
|
|
2283
|
+
sage: cosh(a + T.O(5))
|
|
2284
|
+
1 + 1/2*a^2 + 1/24*a^4 + O(a, b)^5
|
|
2285
|
+
|
|
2286
|
+
TESTS::
|
|
2287
|
+
|
|
2288
|
+
sage: cosh(a^2 + T.O(5))
|
|
2289
|
+
1 + 1/2*a^4 + O(a, b)^5
|
|
2290
|
+
"""
|
|
2291
|
+
R = self.parent()
|
|
2292
|
+
|
|
2293
|
+
c = self[0]
|
|
2294
|
+
if not c.is_zero():
|
|
2295
|
+
raise ValueError('can only apply cosh to formal power '
|
|
2296
|
+
'series with zero constant term')
|
|
2297
|
+
x = self
|
|
2298
|
+
val = x.valuation()
|
|
2299
|
+
assert val >= 1
|
|
2300
|
+
|
|
2301
|
+
prec = min(prec, self.prec())
|
|
2302
|
+
if isinstance(prec, InfinityElement):
|
|
2303
|
+
prec = R.default_prec()
|
|
2304
|
+
n_inv_factorial = R.base_ring().one()
|
|
2305
|
+
x_pow_n = R.one()
|
|
2306
|
+
x2 = x ** 2
|
|
2307
|
+
cosh_x = R.one().add_bigoh(prec)
|
|
2308
|
+
for n in range(2, prec // val + 1, 2):
|
|
2309
|
+
x_pow_n = (x_pow_n * x2).add_bigoh(prec)
|
|
2310
|
+
n_inv_factorial /= n * (n - 1)
|
|
2311
|
+
cosh_x += x_pow_n * n_inv_factorial
|
|
2312
|
+
result_bg = cosh_x
|
|
2313
|
+
|
|
2314
|
+
if result_bg.base_ring() is not self.base_ring():
|
|
2315
|
+
R = R.change_ring(self.base_ring().fraction_field())
|
|
2316
|
+
return R(result_bg, prec=prec)
|
|
2317
|
+
|
|
2318
|
+
def tanh(self, prec=infinity):
|
|
2319
|
+
r"""
|
|
2320
|
+
Apply tanh to the formal power series.
|
|
2321
|
+
|
|
2322
|
+
INPUT:
|
|
2323
|
+
|
|
2324
|
+
- ``prec`` -- integer or ``infinity``; the degree to truncate
|
|
2325
|
+
the result to
|
|
2326
|
+
|
|
2327
|
+
OUTPUT: a new power series
|
|
2328
|
+
|
|
2329
|
+
EXAMPLES:
|
|
2330
|
+
|
|
2331
|
+
For one variable::
|
|
2332
|
+
|
|
2333
|
+
sage: t = PowerSeriesRing(QQ, 't').gen()
|
|
2334
|
+
sage: f = (t + t**2).O(4)
|
|
2335
|
+
sage: tanh(f)
|
|
2336
|
+
t + t^2 - 1/3*t^3 + O(t^4)
|
|
2337
|
+
|
|
2338
|
+
For several variables::
|
|
2339
|
+
|
|
2340
|
+
sage: T.<a,b> = PowerSeriesRing(ZZ,2)
|
|
2341
|
+
sage: f = a + b + a*b + T.O(3)
|
|
2342
|
+
sage: tanh(f)
|
|
2343
|
+
a + b + a*b + O(a, b)^3
|
|
2344
|
+
sage: f.tanh()
|
|
2345
|
+
a + b + a*b + O(a, b)^3
|
|
2346
|
+
sage: f.tanh(prec=2)
|
|
2347
|
+
a + b + O(a, b)^2
|
|
2348
|
+
|
|
2349
|
+
If the power series has a nonzero constant coefficient `c`,
|
|
2350
|
+
one raises an error::
|
|
2351
|
+
|
|
2352
|
+
sage: g = 2 + f
|
|
2353
|
+
sage: tanh(g)
|
|
2354
|
+
Traceback (most recent call last):
|
|
2355
|
+
...
|
|
2356
|
+
ValueError: can only apply tanh to formal power series with zero
|
|
2357
|
+
constant term
|
|
2358
|
+
|
|
2359
|
+
If no precision is specified, the default precision is used::
|
|
2360
|
+
|
|
2361
|
+
sage: T.default_prec()
|
|
2362
|
+
12
|
|
2363
|
+
sage: tanh(a)
|
|
2364
|
+
a - 1/3*a^3 + 2/15*a^5 - 17/315*a^7 + 62/2835*a^9 -
|
|
2365
|
+
1382/155925*a^11 + O(a, b)^12
|
|
2366
|
+
sage: a.tanh(prec=5)
|
|
2367
|
+
a - 1/3*a^3 + O(a, b)^5
|
|
2368
|
+
sage: tanh(a + T.O(5))
|
|
2369
|
+
a - 1/3*a^3 + O(a, b)^5
|
|
2370
|
+
|
|
2371
|
+
TESTS::
|
|
2372
|
+
|
|
2373
|
+
sage: tanh(a^2 + T.O(5))
|
|
2374
|
+
a^2 + O(a, b)^5
|
|
2375
|
+
"""
|
|
2376
|
+
if not self[0].is_zero():
|
|
2377
|
+
raise ValueError('can only apply tanh to formal power '
|
|
2378
|
+
'series with zero constant term')
|
|
2379
|
+
assert self.valuation() >= 1
|
|
2380
|
+
return self.sinh(prec) / self.cosh(prec)
|
|
2381
|
+
|
|
2382
|
+
def O(self, prec):
|
|
2383
|
+
r"""
|
|
2384
|
+
Return this series plus `O(x^\text{prec})`. Does not change
|
|
2385
|
+
``self``.
|
|
2386
|
+
|
|
2387
|
+
EXAMPLES::
|
|
2388
|
+
|
|
2389
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
2390
|
+
sage: p = 1 + x^2 + x^10; p
|
|
2391
|
+
1 + x^2 + x^10
|
|
2392
|
+
sage: p.O(15)
|
|
2393
|
+
1 + x^2 + x^10 + O(x^15)
|
|
2394
|
+
sage: p.O(5)
|
|
2395
|
+
1 + x^2 + O(x^5)
|
|
2396
|
+
sage: p.O(-5)
|
|
2397
|
+
Traceback (most recent call last):
|
|
2398
|
+
...
|
|
2399
|
+
ValueError: prec (= -5) must be nonnegative
|
|
2400
|
+
"""
|
|
2401
|
+
if prec is infinity or prec >= self.prec():
|
|
2402
|
+
return self
|
|
2403
|
+
coeffs = self[:prec]
|
|
2404
|
+
return self._parent(coeffs, prec)
|
|
2405
|
+
|
|
2406
|
+
def solve_linear_de(self, prec=infinity, b=None, f0=None):
|
|
2407
|
+
r"""
|
|
2408
|
+
Obtain a power series solution to an inhomogeneous linear
|
|
2409
|
+
differential equation of the form:
|
|
2410
|
+
|
|
2411
|
+
.. MATH::
|
|
2412
|
+
|
|
2413
|
+
f'(t) = a(t) f(t) + b(t).
|
|
2414
|
+
|
|
2415
|
+
INPUT:
|
|
2416
|
+
|
|
2417
|
+
- ``self`` -- the power series `a(t)`
|
|
2418
|
+
|
|
2419
|
+
- ``b`` -- the power series `b(t)` (default: zero)
|
|
2420
|
+
|
|
2421
|
+
- ``f0`` -- the constant term of `f` ("initial condition")
|
|
2422
|
+
(default: 1)
|
|
2423
|
+
|
|
2424
|
+
- ``prec`` -- desired precision of result (this will be
|
|
2425
|
+
reduced if either a or b have less precision available)
|
|
2426
|
+
|
|
2427
|
+
OUTPUT: the power series `f`, to indicated precision
|
|
2428
|
+
|
|
2429
|
+
ALGORITHM: A divide-and-conquer strategy; see the source code.
|
|
2430
|
+
Running time is approximately `M(n) \log n`, where
|
|
2431
|
+
`M(n)` is the time required for a polynomial multiplication
|
|
2432
|
+
of length `n` over the coefficient ring. (If you're working
|
|
2433
|
+
over something like `\QQ`, running time analysis can be a
|
|
2434
|
+
little complicated because the coefficients tend to explode.)
|
|
2435
|
+
|
|
2436
|
+
.. NOTE::
|
|
2437
|
+
|
|
2438
|
+
- If the coefficient ring is a field of characteristic
|
|
2439
|
+
zero, then the solution will exist and is unique.
|
|
2440
|
+
|
|
2441
|
+
- For other coefficient rings, things are more
|
|
2442
|
+
complicated. A solution may not exist, and if it does it
|
|
2443
|
+
may not be unique. Generally, by the time the `n`-th term
|
|
2444
|
+
has been computed, the algorithm will have attempted
|
|
2445
|
+
divisions by `n!` in the coefficient ring. So if
|
|
2446
|
+
your coefficient ring has enough 'precision', and if your
|
|
2447
|
+
coefficient ring can perform divisions even when the
|
|
2448
|
+
answer is not unique, and if you know in advance that a
|
|
2449
|
+
solution exists, then this function will find a solution
|
|
2450
|
+
(otherwise it will probably crash).
|
|
2451
|
+
|
|
2452
|
+
AUTHORS:
|
|
2453
|
+
|
|
2454
|
+
- David Harvey (2006-09-11): factored functionality out from
|
|
2455
|
+
exp() function, cleaned up precision tests a bit
|
|
2456
|
+
|
|
2457
|
+
EXAMPLES::
|
|
2458
|
+
|
|
2459
|
+
sage: R.<t> = PowerSeriesRing(QQ, default_prec=10)
|
|
2460
|
+
|
|
2461
|
+
::
|
|
2462
|
+
|
|
2463
|
+
sage: a = 2 - 3*t + 4*t^2 + O(t^10)
|
|
2464
|
+
sage: b = 3 - 4*t^2 + O(t^7)
|
|
2465
|
+
sage: f = a.solve_linear_de(prec=5, b=b, f0=3/5)
|
|
2466
|
+
sage: f
|
|
2467
|
+
3/5 + 21/5*t + 33/10*t^2 - 38/15*t^3 + 11/24*t^4 + O(t^5)
|
|
2468
|
+
sage: f.derivative() - a*f - b
|
|
2469
|
+
O(t^4)
|
|
2470
|
+
|
|
2471
|
+
::
|
|
2472
|
+
|
|
2473
|
+
sage: a = 2 - 3*t + 4*t^2
|
|
2474
|
+
sage: b = b = 3 - 4*t^2
|
|
2475
|
+
sage: f = a.solve_linear_de(b=b, f0=3/5)
|
|
2476
|
+
Traceback (most recent call last):
|
|
2477
|
+
...
|
|
2478
|
+
ValueError: cannot solve differential equation to infinite precision
|
|
2479
|
+
|
|
2480
|
+
::
|
|
2481
|
+
|
|
2482
|
+
sage: a.solve_linear_de(prec=5, b=b, f0=3/5)
|
|
2483
|
+
3/5 + 21/5*t + 33/10*t^2 - 38/15*t^3 + 11/24*t^4 + O(t^5)
|
|
2484
|
+
"""
|
|
2485
|
+
if b is None:
|
|
2486
|
+
b = self._parent(0)
|
|
2487
|
+
|
|
2488
|
+
if f0 is None:
|
|
2489
|
+
f0 = 1
|
|
2490
|
+
f0 = self.base_ring()(f0)
|
|
2491
|
+
|
|
2492
|
+
# reduce precision to whatever is available from a and b
|
|
2493
|
+
prec = min(prec, self.prec() + 1, b.prec() + 1)
|
|
2494
|
+
if prec is infinity:
|
|
2495
|
+
raise ValueError("cannot solve differential equation to infinite precision")
|
|
2496
|
+
prec = int(prec)
|
|
2497
|
+
if prec == 0:
|
|
2498
|
+
return self._parent(0, 0)
|
|
2499
|
+
if prec < 0:
|
|
2500
|
+
raise ValueError("prec (=%s) must be a nonnegative integer" % prec)
|
|
2501
|
+
|
|
2502
|
+
base_ring = self._parent.base_ring()
|
|
2503
|
+
R = PolynomialRing(base_ring, self._parent.variable_name())
|
|
2504
|
+
|
|
2505
|
+
a_list = self.list()
|
|
2506
|
+
b_list = [base_ring(0)]
|
|
2507
|
+
b_list.extend(b.list())
|
|
2508
|
+
while len(b_list) < prec:
|
|
2509
|
+
b_list.append(base_ring(0))
|
|
2510
|
+
f = _solve_linear_de(R, 0, prec, a_list, b_list, f0)
|
|
2511
|
+
return self._parent(f, prec)
|
|
2512
|
+
|
|
2513
|
+
def exp(self, prec=None):
|
|
2514
|
+
r"""
|
|
2515
|
+
Return exp of this power series to the indicated precision.
|
|
2516
|
+
|
|
2517
|
+
INPUT:
|
|
2518
|
+
|
|
2519
|
+
- ``prec`` -- integer (default: ``self.parent().default_prec``)
|
|
2520
|
+
|
|
2521
|
+
ALGORITHM: See :meth:`.solve_linear_de`.
|
|
2522
|
+
|
|
2523
|
+
.. NOTE::
|
|
2524
|
+
|
|
2525
|
+
- Screwy things can happen if the coefficient ring is not a
|
|
2526
|
+
field of characteristic zero. See :meth:`.solve_linear_de`.
|
|
2527
|
+
|
|
2528
|
+
AUTHORS:
|
|
2529
|
+
|
|
2530
|
+
- David Harvey (2006-09-08): rewrote to use simplest possible "lazy" algorithm.
|
|
2531
|
+
|
|
2532
|
+
- David Harvey (2006-09-10): rewrote to use divide-and-conquer
|
|
2533
|
+
strategy.
|
|
2534
|
+
|
|
2535
|
+
- David Harvey (2006-09-11): factored functionality out to
|
|
2536
|
+
solve_linear_de().
|
|
2537
|
+
|
|
2538
|
+
- Sourav Sen Gupta, David Harvey (2008-11): handle constant
|
|
2539
|
+
term
|
|
2540
|
+
|
|
2541
|
+
EXAMPLES::
|
|
2542
|
+
|
|
2543
|
+
sage: R.<t> = PowerSeriesRing(QQ, default_prec=10)
|
|
2544
|
+
|
|
2545
|
+
Check that `\exp(t)` is, well, `\exp(t)`::
|
|
2546
|
+
|
|
2547
|
+
sage: (t + O(t^10)).exp()
|
|
2548
|
+
1 + t + 1/2*t^2 + 1/6*t^3 + 1/24*t^4 + 1/120*t^5 + 1/720*t^6
|
|
2549
|
+
+ 1/5040*t^7 + 1/40320*t^8 + 1/362880*t^9 + O(t^10)
|
|
2550
|
+
|
|
2551
|
+
Check that `\exp(\log(1+t))` is `1+t`::
|
|
2552
|
+
|
|
2553
|
+
sage: (sum([-(-t)^n/n for n in range(1, 10)]) + O(t^10)).exp()
|
|
2554
|
+
1 + t + O(t^10)
|
|
2555
|
+
|
|
2556
|
+
Check that `\exp(2t + t^2 - t^5)` is whatever it is::
|
|
2557
|
+
|
|
2558
|
+
sage: (2*t + t^2 - t^5 + O(t^10)).exp()
|
|
2559
|
+
1 + 2*t + 3*t^2 + 10/3*t^3 + 19/6*t^4 + 8/5*t^5 - 7/90*t^6
|
|
2560
|
+
- 538/315*t^7 - 425/168*t^8 - 30629/11340*t^9 + O(t^10)
|
|
2561
|
+
|
|
2562
|
+
Check requesting lower precision::
|
|
2563
|
+
|
|
2564
|
+
sage: (t + t^2 - t^5 + O(t^10)).exp(5)
|
|
2565
|
+
1 + t + 3/2*t^2 + 7/6*t^3 + 25/24*t^4 + O(t^5)
|
|
2566
|
+
|
|
2567
|
+
Can't get more precision than the input::
|
|
2568
|
+
|
|
2569
|
+
sage: (t + t^2 + O(t^3)).exp(10)
|
|
2570
|
+
1 + t + 3/2*t^2 + O(t^3)
|
|
2571
|
+
|
|
2572
|
+
Check some boundary cases::
|
|
2573
|
+
|
|
2574
|
+
sage: (t + O(t^2)).exp(1)
|
|
2575
|
+
1 + O(t)
|
|
2576
|
+
sage: (t + O(t^2)).exp(0)
|
|
2577
|
+
O(t^0)
|
|
2578
|
+
|
|
2579
|
+
Handle nonzero constant term (fixes :issue:`4477`)::
|
|
2580
|
+
|
|
2581
|
+
sage: # needs sage.rings.real_mpfr
|
|
2582
|
+
sage: R.<x> = PowerSeriesRing(RR)
|
|
2583
|
+
sage: (1 + x + x^2 + O(x^3)).exp()
|
|
2584
|
+
2.71828182845905 + 2.71828182845905*x + 4.07742274268857*x^2 + O(x^3)
|
|
2585
|
+
|
|
2586
|
+
::
|
|
2587
|
+
|
|
2588
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
2589
|
+
sage: (1 + x + O(x^2)).exp() # needs sage.symbolic
|
|
2590
|
+
Traceback (most recent call last):
|
|
2591
|
+
...
|
|
2592
|
+
ArithmeticError: exponential of constant term does not belong
|
|
2593
|
+
to coefficient ring (consider working in a larger ring)
|
|
2594
|
+
|
|
2595
|
+
::
|
|
2596
|
+
|
|
2597
|
+
sage: R.<x> = PowerSeriesRing(GF(5))
|
|
2598
|
+
sage: (1 + x + O(x^2)).exp()
|
|
2599
|
+
Traceback (most recent call last):
|
|
2600
|
+
...
|
|
2601
|
+
ArithmeticError: constant term of power series does not support exponentiation
|
|
2602
|
+
"""
|
|
2603
|
+
if prec is None:
|
|
2604
|
+
prec = self._parent.default_prec()
|
|
2605
|
+
|
|
2606
|
+
t = self.derivative().solve_linear_de(prec)
|
|
2607
|
+
|
|
2608
|
+
if not self[0].is_zero():
|
|
2609
|
+
try:
|
|
2610
|
+
C = self[0].exp()
|
|
2611
|
+
except AttributeError:
|
|
2612
|
+
raise ArithmeticError("constant term of power series does not support exponentiation")
|
|
2613
|
+
|
|
2614
|
+
if C.parent() is not self.base_ring():
|
|
2615
|
+
raise ArithmeticError("exponential of constant term does not belong to coefficient ring (consider working in a larger ring)")
|
|
2616
|
+
|
|
2617
|
+
t = C * t
|
|
2618
|
+
|
|
2619
|
+
return t
|
|
2620
|
+
|
|
2621
|
+
def log(self, prec=None):
|
|
2622
|
+
r"""
|
|
2623
|
+
Return log of this power series to the indicated precision.
|
|
2624
|
+
|
|
2625
|
+
This works only if the constant term of the power series is 1
|
|
2626
|
+
or the base ring can take the logarithm of the constant coefficient.
|
|
2627
|
+
|
|
2628
|
+
INPUT:
|
|
2629
|
+
|
|
2630
|
+
- ``prec`` -- integer (default: ``self.parent().default_prec()``)
|
|
2631
|
+
|
|
2632
|
+
ALGORITHM: See :meth:`solve_linear_de()`.
|
|
2633
|
+
|
|
2634
|
+
.. WARNING::
|
|
2635
|
+
|
|
2636
|
+
Screwy things can happen if the coefficient ring is not a
|
|
2637
|
+
field of characteristic zero. See :meth:`solve_linear_de()`.
|
|
2638
|
+
|
|
2639
|
+
EXAMPLES::
|
|
2640
|
+
|
|
2641
|
+
sage: R.<t> = PowerSeriesRing(QQ, default_prec=10)
|
|
2642
|
+
sage: (1 + t + O(t^10)).log()
|
|
2643
|
+
t - 1/2*t^2 + 1/3*t^3 - 1/4*t^4 + 1/5*t^5 - 1/6*t^6 + 1/7*t^7
|
|
2644
|
+
- 1/8*t^8 + 1/9*t^9 + O(t^10)
|
|
2645
|
+
|
|
2646
|
+
sage: t.exp().log()
|
|
2647
|
+
t + O(t^10)
|
|
2648
|
+
|
|
2649
|
+
sage: (1 + t).log().exp()
|
|
2650
|
+
1 + t + O(t^10)
|
|
2651
|
+
|
|
2652
|
+
sage: (-1 + t + O(t^10)).log()
|
|
2653
|
+
Traceback (most recent call last):
|
|
2654
|
+
...
|
|
2655
|
+
ArithmeticError: constant term of power series is not 1
|
|
2656
|
+
|
|
2657
|
+
sage: # needs sage.rings.real_mpfr
|
|
2658
|
+
sage: R.<t> = PowerSeriesRing(RR)
|
|
2659
|
+
sage: (2 + t).log().exp()
|
|
2660
|
+
2.00000000000000 + 1.00000000000000*t + O(t^20)
|
|
2661
|
+
"""
|
|
2662
|
+
if prec is None:
|
|
2663
|
+
prec = self._parent.default_prec()
|
|
2664
|
+
|
|
2665
|
+
zero = self.parent().zero()
|
|
2666
|
+
const_off = zero
|
|
2667
|
+
|
|
2668
|
+
if not self[0].is_one():
|
|
2669
|
+
if self.base_ring() in _Fields and self[0] > 0:
|
|
2670
|
+
const_off = self[0].log()
|
|
2671
|
+
else:
|
|
2672
|
+
raise ArithmeticError("constant term of power series is not 1")
|
|
2673
|
+
|
|
2674
|
+
t = zero.solve_linear_de(prec,b=self.derivative()/self,f0=0)
|
|
2675
|
+
return t + const_off
|
|
2676
|
+
|
|
2677
|
+
def V(self, n):
|
|
2678
|
+
r"""
|
|
2679
|
+
If `f = \sum a_m x^m`, then this function returns
|
|
2680
|
+
`\sum a_m x^{nm}`.
|
|
2681
|
+
|
|
2682
|
+
EXAMPLES::
|
|
2683
|
+
|
|
2684
|
+
sage: R.<x> = PowerSeriesRing(ZZ)
|
|
2685
|
+
sage: p = 1 + x^2 + x^10; p
|
|
2686
|
+
1 + x^2 + x^10
|
|
2687
|
+
sage: p.V(3)
|
|
2688
|
+
1 + x^6 + x^30
|
|
2689
|
+
sage: (p + O(x^20)).V(3)
|
|
2690
|
+
1 + x^6 + x^30 + O(x^60)
|
|
2691
|
+
"""
|
|
2692
|
+
v = self.list()
|
|
2693
|
+
m = 0
|
|
2694
|
+
w = []
|
|
2695
|
+
zero = self.base_ring().zero()
|
|
2696
|
+
for i in range(len(v) * n):
|
|
2697
|
+
if i % n != 0:
|
|
2698
|
+
w.append(zero)
|
|
2699
|
+
else:
|
|
2700
|
+
w.append(v[m])
|
|
2701
|
+
m += 1
|
|
2702
|
+
return self._parent(w, self.prec() * n)
|
|
2703
|
+
|
|
2704
|
+
def valuation(self):
|
|
2705
|
+
"""
|
|
2706
|
+
Return the valuation of this power series.
|
|
2707
|
+
|
|
2708
|
+
This is equal to the valuation of the underlying polynomial.
|
|
2709
|
+
|
|
2710
|
+
EXAMPLES:
|
|
2711
|
+
|
|
2712
|
+
Sparse examples::
|
|
2713
|
+
|
|
2714
|
+
sage: R.<t> = PowerSeriesRing(QQ, sparse=True)
|
|
2715
|
+
sage: f = t^100000 + O(t^10000000)
|
|
2716
|
+
sage: f.valuation()
|
|
2717
|
+
100000
|
|
2718
|
+
sage: R(0).valuation()
|
|
2719
|
+
+Infinity
|
|
2720
|
+
|
|
2721
|
+
Dense examples::
|
|
2722
|
+
|
|
2723
|
+
sage: R.<t> = PowerSeriesRing(ZZ)
|
|
2724
|
+
sage: f = 17*t^100 + O(t^110)
|
|
2725
|
+
sage: f.valuation()
|
|
2726
|
+
100
|
|
2727
|
+
sage: t.valuation()
|
|
2728
|
+
1
|
|
2729
|
+
"""
|
|
2730
|
+
return self.polynomial().valuation()
|
|
2731
|
+
|
|
2732
|
+
def variable(self):
|
|
2733
|
+
"""
|
|
2734
|
+
Return a string with the name of the variable
|
|
2735
|
+
of this power series.
|
|
2736
|
+
|
|
2737
|
+
EXAMPLES::
|
|
2738
|
+
|
|
2739
|
+
sage: R.<x> = PowerSeriesRing(Rationals())
|
|
2740
|
+
sage: f = x^2 + 3*x^4 + O(x^7)
|
|
2741
|
+
sage: f.variable()
|
|
2742
|
+
'x'
|
|
2743
|
+
|
|
2744
|
+
AUTHORS:
|
|
2745
|
+
|
|
2746
|
+
- David Harvey (2006-08-08)
|
|
2747
|
+
"""
|
|
2748
|
+
return self._parent.variable_name()
|
|
2749
|
+
|
|
2750
|
+
def degree(self):
|
|
2751
|
+
"""
|
|
2752
|
+
Return the degree of this power series, which is by definition the
|
|
2753
|
+
degree of the underlying polynomial.
|
|
2754
|
+
|
|
2755
|
+
EXAMPLES::
|
|
2756
|
+
|
|
2757
|
+
sage: R.<t> = PowerSeriesRing(QQ, sparse=True)
|
|
2758
|
+
sage: f = t^100000 + O(t^10000000)
|
|
2759
|
+
sage: f.degree()
|
|
2760
|
+
100000
|
|
2761
|
+
"""
|
|
2762
|
+
return self.polynomial().degree()
|
|
2763
|
+
|
|
2764
|
+
def derivative(self, *args):
|
|
2765
|
+
r"""
|
|
2766
|
+
The formal derivative of this power series, with respect to
|
|
2767
|
+
variables supplied in args.
|
|
2768
|
+
|
|
2769
|
+
Multiple variables and iteration counts may be supplied; see
|
|
2770
|
+
documentation for the global derivative() function for more
|
|
2771
|
+
details.
|
|
2772
|
+
|
|
2773
|
+
.. SEEALSO::
|
|
2774
|
+
|
|
2775
|
+
:meth:`_derivative`
|
|
2776
|
+
|
|
2777
|
+
EXAMPLES::
|
|
2778
|
+
|
|
2779
|
+
sage: R.<x> = PowerSeriesRing(QQ)
|
|
2780
|
+
sage: g = -x + x^2/2 - x^4 + O(x^6)
|
|
2781
|
+
sage: g.derivative()
|
|
2782
|
+
-1 + x - 4*x^3 + O(x^5)
|
|
2783
|
+
sage: g.derivative(x)
|
|
2784
|
+
-1 + x - 4*x^3 + O(x^5)
|
|
2785
|
+
sage: g.derivative(x, x)
|
|
2786
|
+
1 - 12*x^2 + O(x^4)
|
|
2787
|
+
sage: g.derivative(x, 2)
|
|
2788
|
+
1 - 12*x^2 + O(x^4)
|
|
2789
|
+
"""
|
|
2790
|
+
return multi_derivative(self, args)
|
|
2791
|
+
|
|
2792
|
+
def __setitem__(self, n, value):
|
|
2793
|
+
"""
|
|
2794
|
+
Called when an attempt is made to change a power series.
|
|
2795
|
+
|
|
2796
|
+
EXAMPLES::
|
|
2797
|
+
|
|
2798
|
+
sage: R.<t> = ZZ[[]]
|
|
2799
|
+
sage: f = 3 - t^3 + O(t^5)
|
|
2800
|
+
sage: f[1] = 5
|
|
2801
|
+
Traceback (most recent call last):
|
|
2802
|
+
...
|
|
2803
|
+
IndexError: power series are immutable
|
|
2804
|
+
"""
|
|
2805
|
+
raise IndexError("power series are immutable")
|
|
2806
|
+
|
|
2807
|
+
def laurent_series(self):
|
|
2808
|
+
"""
|
|
2809
|
+
Return the Laurent series associated to this power series, i.e.,
|
|
2810
|
+
this series considered as a Laurent series.
|
|
2811
|
+
|
|
2812
|
+
EXAMPLES::
|
|
2813
|
+
|
|
2814
|
+
sage: k.<w> = QQ[[]]
|
|
2815
|
+
sage: f = 1 + 17*w + 15*w^3 + O(w^5)
|
|
2816
|
+
sage: parent(f)
|
|
2817
|
+
Power Series Ring in w over Rational Field
|
|
2818
|
+
sage: g = f.laurent_series(); g
|
|
2819
|
+
1 + 17*w + 15*w^3 + O(w^5)
|
|
2820
|
+
"""
|
|
2821
|
+
return self._parent.laurent_series_ring()(self)
|
|
2822
|
+
|
|
2823
|
+
def egf_to_ogf(self):
|
|
2824
|
+
r"""
|
|
2825
|
+
Return the ordinary generating function power series,
|
|
2826
|
+
assuming ``self`` is an exponential generating function power series.
|
|
2827
|
+
|
|
2828
|
+
This is a formal Laplace transform.
|
|
2829
|
+
|
|
2830
|
+
This function is known as :pari:`serlaplace` in PARI/GP.
|
|
2831
|
+
|
|
2832
|
+
.. SEEALSO:: :meth:`ogf_to_egf` for the inverse method.
|
|
2833
|
+
|
|
2834
|
+
EXAMPLES::
|
|
2835
|
+
|
|
2836
|
+
sage: R.<t> = PowerSeriesRing(QQ)
|
|
2837
|
+
sage: f = t + t^2/factorial(2) + 2*t^3/factorial(3)
|
|
2838
|
+
sage: f.egf_to_ogf()
|
|
2839
|
+
t + t^2 + 2*t^3
|
|
2840
|
+
"""
|
|
2841
|
+
return self.parent()([self[i] * arith.factorial(i) for i in range(self.degree() + 1)])
|
|
2842
|
+
|
|
2843
|
+
def ogf_to_egf(self):
|
|
2844
|
+
r"""
|
|
2845
|
+
Return the exponential generating function power series,
|
|
2846
|
+
assuming ``self`` is an ordinary generating function power series.
|
|
2847
|
+
|
|
2848
|
+
This is a formal Borel transform.
|
|
2849
|
+
|
|
2850
|
+
This can also be computed as ``serconvol(f,exp(t))`` in PARI/GP.
|
|
2851
|
+
|
|
2852
|
+
.. SEEALSO:: :meth:`egf_to_ogf` for the inverse method.
|
|
2853
|
+
|
|
2854
|
+
EXAMPLES::
|
|
2855
|
+
|
|
2856
|
+
sage: R.<t> = PowerSeriesRing(QQ)
|
|
2857
|
+
sage: f = t + t^2 + 2*t^3
|
|
2858
|
+
sage: f.ogf_to_egf()
|
|
2859
|
+
t + 1/2*t^2 + 1/3*t^3
|
|
2860
|
+
"""
|
|
2861
|
+
return self.parent()([self[i] / arith.factorial(i) for i in range(self.degree() + 1)])
|
|
2862
|
+
|
|
2863
|
+
def __pari__(self):
|
|
2864
|
+
"""
|
|
2865
|
+
Return a PARI representation of this series.
|
|
2866
|
+
|
|
2867
|
+
There are currently limits to the possible base rings over which this
|
|
2868
|
+
function works. See the documentation for
|
|
2869
|
+
:meth:`~sage.rings.polynomial.polynomial_element.Polynomial.__pari__`
|
|
2870
|
+
|
|
2871
|
+
EXAMPLES::
|
|
2872
|
+
|
|
2873
|
+
sage: k.<w> = QQ[[]]
|
|
2874
|
+
sage: f = 1 + 17*w + 15*w^3 + O(w^5)
|
|
2875
|
+
sage: pari(f) # indirect doctest # needs sage.libs.pari
|
|
2876
|
+
1 + 17*w + 15*w^3 + O(w^5)
|
|
2877
|
+
sage: pari(1 - 19*w + w^5) # indirect doctest # needs sage.libs.pari
|
|
2878
|
+
w^5 - 19*w + 1
|
|
2879
|
+
sage: R.<x> = Zmod(6)[[]]
|
|
2880
|
+
sage: pari(1 + x + 8*x^3 + O(x^8)) # indirect doctest # needs sage.libs.pari
|
|
2881
|
+
Mod(1, 6) + Mod(1, 6)*x + Mod(2, 6)*x^3 + O(x^8)
|
|
2882
|
+
|
|
2883
|
+
TESTS::
|
|
2884
|
+
|
|
2885
|
+
sage: pari(1 + O(x^1)) # needs sage.libs.pari
|
|
2886
|
+
Mod(1, 6) + O(x)
|
|
2887
|
+
sage: pari(O(x^1)) # needs sage.libs.pari
|
|
2888
|
+
O(x)
|
|
2889
|
+
sage: pari(O(x^0)) # needs sage.libs.pari
|
|
2890
|
+
O(x^0)
|
|
2891
|
+
"""
|
|
2892
|
+
n = self.prec()
|
|
2893
|
+
s = self.truncate().__pari__() # PARI polynomial
|
|
2894
|
+
if n is not infinity:
|
|
2895
|
+
v = s.variable()
|
|
2896
|
+
s = s.Ser(v, n - s.valuation(v) if s else n)
|
|
2897
|
+
return s
|
|
2898
|
+
|
|
2899
|
+
|
|
2900
|
+
def _solve_linear_de(R, N, L, a, b, f0):
|
|
2901
|
+
r"""
|
|
2902
|
+
Internal function used by ``PowerSeries.solve_linear_de()``.
|
|
2903
|
+
|
|
2904
|
+
INPUT:
|
|
2905
|
+
|
|
2906
|
+
- ``R`` -- a PolynomialRing
|
|
2907
|
+
|
|
2908
|
+
- ``N`` -- integer >= 0
|
|
2909
|
+
|
|
2910
|
+
- ``L`` -- integer >= 1
|
|
2911
|
+
|
|
2912
|
+
- ``a`` -- list of coefficients of `a`, any length, all coefficients should
|
|
2913
|
+
belong to base ring of `R`
|
|
2914
|
+
|
|
2915
|
+
- ``b`` -- list of coefficients of `b`, length at least `L` (only first `L`
|
|
2916
|
+
coefficients are used), all coefficients should belong to base ring of `R`
|
|
2917
|
+
|
|
2918
|
+
- ``f0`` -- constant term of `f` (only used if ``N == 0``), should belong
|
|
2919
|
+
to base ring of `R`
|
|
2920
|
+
|
|
2921
|
+
OUTPUT: list of coefficients of `f` (length exactly `L`), where `f` is a
|
|
2922
|
+
solution to the linear inhomogeneous differential equation:
|
|
2923
|
+
|
|
2924
|
+
.. MATH::
|
|
2925
|
+
|
|
2926
|
+
(t^N f)' = a t^N f + t^{N-1} b + O(t^{N+L-1}).
|
|
2927
|
+
|
|
2928
|
+
|
|
2929
|
+
The constant term of `f` is taken to be f0 if `N == 0`, and otherwise is
|
|
2930
|
+
determined by `N f_0 = b_0`.
|
|
2931
|
+
|
|
2932
|
+
ALGORITHM: The algorithm implemented here is inspired by the "fast
|
|
2933
|
+
lazy multiplication algorithm" described in the paper "Lazy
|
|
2934
|
+
multiplication of formal power series" by J van der Hoeven (1997
|
|
2935
|
+
ISSAC conference).
|
|
2936
|
+
|
|
2937
|
+
Our situation is a bit simpler than the one described there,
|
|
2938
|
+
because only one of the series being multiplied needs the lazy
|
|
2939
|
+
treatment; the other one is known fully in advance. I have
|
|
2940
|
+
reformulated the algorithm as an explicit divide-and-conquer
|
|
2941
|
+
recursion. Possibly it is slower than the one described by van der
|
|
2942
|
+
Hoeven, by a constant factor, but it seems easier to implement.
|
|
2943
|
+
Also, because we repeatedly split in half starting at the top
|
|
2944
|
+
level, instead of repeatedly doubling in size from the bottom
|
|
2945
|
+
level, it's easier to avoid problems with "overshooting" in the
|
|
2946
|
+
last iteration.
|
|
2947
|
+
|
|
2948
|
+
The idea is to split the problem into two instances with
|
|
2949
|
+
`L` about half the size. Take `L'` to be the
|
|
2950
|
+
ceiling of `(L/2)`. First recursively find `g`
|
|
2951
|
+
modulo `t^{L'}` such that
|
|
2952
|
+
|
|
2953
|
+
.. MATH::
|
|
2954
|
+
|
|
2955
|
+
(t^N g)' = a t^N g + t^{N-1} b + O(t^{N+L'-1}).
|
|
2956
|
+
|
|
2957
|
+
Next we want to find `h` modulo `t^{L-L'}` such
|
|
2958
|
+
that `f = g + t^{L'} h` is a solution of the original
|
|
2959
|
+
equation. We can find a suitable `h` by recursively solving
|
|
2960
|
+
another differential equation of the same form, namely
|
|
2961
|
+
|
|
2962
|
+
.. MATH::
|
|
2963
|
+
|
|
2964
|
+
(t^{N+L'} h)' = a t^{N+L'} h + c t^{N+L'-1} + O(t^{N+L'-1}),
|
|
2965
|
+
|
|
2966
|
+
|
|
2967
|
+
where `c` is determined by
|
|
2968
|
+
|
|
2969
|
+
.. MATH::
|
|
2970
|
+
|
|
2971
|
+
(t^N g)' - a t^N g - t^{N-1} b = -c t^{N+L'-1} + O(t^{N+L-1}).
|
|
2972
|
+
|
|
2973
|
+
|
|
2974
|
+
Once `g` is known, `c` can be recovered from this
|
|
2975
|
+
relation by computing the coefficients of `t^j` of the
|
|
2976
|
+
product `a g` for `j` in the range
|
|
2977
|
+
`L'-1 \leq j < L-1`.
|
|
2978
|
+
|
|
2979
|
+
At the bottom of the recursion we have `L = 1`, in which
|
|
2980
|
+
case the solution is simply given by `f_0 = b_0/N` (or by
|
|
2981
|
+
the supplied initial condition `f_0` when
|
|
2982
|
+
`N == 0`).
|
|
2983
|
+
|
|
2984
|
+
The algorithm has to do one multiplication of length `N`,
|
|
2985
|
+
two of length `N/2`, four of length `N/4`, etc,
|
|
2986
|
+
hence giving runtime `O(M(N) \log N)`.
|
|
2987
|
+
|
|
2988
|
+
AUTHORS:
|
|
2989
|
+
|
|
2990
|
+
- David Harvey (2006-09-11): factored out of PowerSeries.exp().
|
|
2991
|
+
"""
|
|
2992
|
+
if L == 1:
|
|
2993
|
+
# base case
|
|
2994
|
+
if N == 0:
|
|
2995
|
+
return [f0]
|
|
2996
|
+
else:
|
|
2997
|
+
return [b[0] / N]
|
|
2998
|
+
|
|
2999
|
+
L2 = (L + 1) >> 1 # ceil(L/2)
|
|
3000
|
+
|
|
3001
|
+
g = _solve_linear_de(R, N, L2, a, b, f0)
|
|
3002
|
+
|
|
3003
|
+
term1 = R(g) # we must not have check=False, since otherwise [..., 0, 0] is not stripped
|
|
3004
|
+
term2 = R(a[:L]) # , check=False)
|
|
3005
|
+
product = (term1 * term2).list()
|
|
3006
|
+
|
|
3007
|
+
# todo: perhaps next loop could be made more efficient
|
|
3008
|
+
c = b[L2:L]
|
|
3009
|
+
for j in range(L2 - 1, min(L-1, len(product))):
|
|
3010
|
+
c[j - (L2-1)] = c[j - (L2-1)] + product[j]
|
|
3011
|
+
|
|
3012
|
+
h = _solve_linear_de(R, N + L2, L - L2, a, c, f0)
|
|
3013
|
+
|
|
3014
|
+
g.extend(h)
|
|
3015
|
+
return g
|
|
3016
|
+
|
|
3017
|
+
|
|
3018
|
+
def make_powerseries_poly_v0(parent, f, prec, is_gen):
|
|
3019
|
+
# This is only used to unpickle old pickles. The new pickling
|
|
3020
|
+
# works differently!
|
|
3021
|
+
from sage.rings import power_series_poly
|
|
3022
|
+
return power_series_poly.PowerSeries_poly(parent, f, prec, 0, is_gen)
|
|
3023
|
+
|
|
3024
|
+
|
|
3025
|
+
def make_element_from_parent_v0(parent, *args):
|
|
3026
|
+
# This is only used to unpickle old pickles. The new pickling
|
|
3027
|
+
# works differently!
|
|
3028
|
+
return parent(*args)
|