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,1768 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Elements of Infinite Polynomial Rings
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- Simon King <simon.king@nuigalway.ie>
|
|
8
|
+
- Mike Hansen <mhansen@gmail.com>
|
|
9
|
+
|
|
10
|
+
An Infinite Polynomial Ring has generators `x_\ast, y_\ast,...`, so
|
|
11
|
+
that the variables are of the form `x_0, x_1, x_2, ..., y_0, y_1,
|
|
12
|
+
y_2,...,...` (see :mod:`~sage.rings.polynomial.infinite_polynomial_ring`).
|
|
13
|
+
Using the generators, we can create elements as follows::
|
|
14
|
+
|
|
15
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
16
|
+
sage: a = x[3]
|
|
17
|
+
sage: b = y[4]
|
|
18
|
+
sage: a
|
|
19
|
+
x_3
|
|
20
|
+
sage: b
|
|
21
|
+
y_4
|
|
22
|
+
sage: c = a*b + a^3 - 2*b^4
|
|
23
|
+
sage: c
|
|
24
|
+
x_3^3 + x_3*y_4 - 2*y_4^4
|
|
25
|
+
|
|
26
|
+
Any Infinite Polynomial Ring ``X`` is equipped with a monomial ordering.
|
|
27
|
+
We only consider monomial orderings in which:
|
|
28
|
+
|
|
29
|
+
``X.gen(i)[m] > X.gen(j)[n]`` `\iff` ``i<j``, or ``i==j`` and ``m>n``
|
|
30
|
+
|
|
31
|
+
Under this restriction, the monomial ordering can be lexicographic
|
|
32
|
+
(default), degree lexicographic, or degree reverse lexicographic.
|
|
33
|
+
Here, the ordering is lexicographic, and elements can be compared
|
|
34
|
+
as usual::
|
|
35
|
+
|
|
36
|
+
sage: X._order
|
|
37
|
+
'lex'
|
|
38
|
+
sage: a > b
|
|
39
|
+
True
|
|
40
|
+
|
|
41
|
+
Note that, when a method is called that is not directly implemented
|
|
42
|
+
for 'InfinitePolynomial', it is tried to call this method for the
|
|
43
|
+
underlying *classical* polynomial. This holds, e.g., when applying the
|
|
44
|
+
``latex`` function::
|
|
45
|
+
|
|
46
|
+
sage: latex(c)
|
|
47
|
+
x_{3}^{3} + x_{3} y_{4} - 2 y_{4}^{4}
|
|
48
|
+
|
|
49
|
+
There is a permutation action on Infinite Polynomial Rings by
|
|
50
|
+
permuting the indices of the variables::
|
|
51
|
+
|
|
52
|
+
sage: P = Permutation(((4,5),(2,3)))
|
|
53
|
+
sage: c^P
|
|
54
|
+
x_2^3 + x_2*y_5 - 2*y_5^4
|
|
55
|
+
|
|
56
|
+
Note that ``P(0)==0``, and thus variables of index zero are invariant
|
|
57
|
+
under the permutation action. More generally, if ``P`` is any
|
|
58
|
+
callable object that accepts nonnegative integers as input and
|
|
59
|
+
returns nonnegative integers, then ``c^P`` means to apply ``P`` to
|
|
60
|
+
the variable indices occurring in ``c``.
|
|
61
|
+
|
|
62
|
+
If you want to substitute variables you can use the standard polynomial
|
|
63
|
+
methods, such as
|
|
64
|
+
:meth:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse.subs`::
|
|
65
|
+
|
|
66
|
+
sage: R.<x,y> = InfinitePolynomialRing(QQ)
|
|
67
|
+
sage: f = x[1] + x[1]*x[2]*x[3]
|
|
68
|
+
sage: f.subs({x[1]: x[0]})
|
|
69
|
+
x_3*x_2*x_0 + x_0
|
|
70
|
+
sage: g = x[0] + x[1] + y[0]
|
|
71
|
+
sage: g.subs({x[0]: y[0]})
|
|
72
|
+
x_1 + 2*y_0
|
|
73
|
+
|
|
74
|
+
TESTS:
|
|
75
|
+
|
|
76
|
+
We test whether coercion works, even in complicated cases in which
|
|
77
|
+
finite polynomial rings are merged with infinite polynomial rings::
|
|
78
|
+
|
|
79
|
+
sage: A.<a> = InfinitePolynomialRing(ZZ,implementation='sparse',order='degrevlex')
|
|
80
|
+
sage: B.<b_2,b_1> = A[]
|
|
81
|
+
sage: C.<b,c> = InfinitePolynomialRing(B,order='degrevlex')
|
|
82
|
+
sage: C
|
|
83
|
+
Infinite polynomial ring in b, c over Infinite polynomial ring in a over Integer Ring
|
|
84
|
+
sage: 1/2*b_1*a[4] + c[3]
|
|
85
|
+
1/2*a_4*b_1 + c_3
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
# ****************************************************************************
|
|
89
|
+
# Copyright (C) 2009 Simon King <king@mathematik.nuigalway.ie>
|
|
90
|
+
# and Mike Hansen <mhansen@gmail.com>,
|
|
91
|
+
#
|
|
92
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
93
|
+
#
|
|
94
|
+
# This code is distributed in the hope that it will be useful,
|
|
95
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
96
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
97
|
+
# General Public License for more details.
|
|
98
|
+
#
|
|
99
|
+
# The full text of the GPL is available at:
|
|
100
|
+
#
|
|
101
|
+
# https://www.gnu.org/licenses/
|
|
102
|
+
# ****************************************************************************
|
|
103
|
+
|
|
104
|
+
from sage.rings.integer_ring import ZZ
|
|
105
|
+
from sage.rings.integer import Integer
|
|
106
|
+
from sage.structure.richcmp import richcmp
|
|
107
|
+
from sage.misc.cachefunc import cached_method
|
|
108
|
+
from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
|
|
109
|
+
from sage.structure.element import RingElement
|
|
110
|
+
from .commutative_polynomial import CommutativePolynomial
|
|
111
|
+
from .multi_polynomial import MPolynomial
|
|
112
|
+
import copy
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class InfinitePolynomial(CommutativePolynomial, metaclass=InheritComparisonClasscallMetaclass):
|
|
116
|
+
"""
|
|
117
|
+
Create an element of a Polynomial Ring with a Countably Infinite Number of Variables.
|
|
118
|
+
|
|
119
|
+
Usually, an InfinitePolynomial is obtained by using the generators
|
|
120
|
+
of an Infinite Polynomial Ring (see :mod:`~sage.rings.polynomial.infinite_polynomial_ring`)
|
|
121
|
+
or by conversion.
|
|
122
|
+
|
|
123
|
+
INPUT:
|
|
124
|
+
|
|
125
|
+
- ``A`` -- an Infinite Polynomial Ring
|
|
126
|
+
- ``p`` -- a *classical* polynomial that can be interpreted in ``A``
|
|
127
|
+
|
|
128
|
+
ASSUMPTIONS:
|
|
129
|
+
|
|
130
|
+
In the dense implementation, it must be ensured that the argument
|
|
131
|
+
``p`` coerces into ``A._P`` by a name preserving conversion map.
|
|
132
|
+
|
|
133
|
+
In the sparse implementation, in the direct construction of an
|
|
134
|
+
infinite polynomial, it is *not* tested whether the argument ``p``
|
|
135
|
+
makes sense in ``A``.
|
|
136
|
+
|
|
137
|
+
EXAMPLES::
|
|
138
|
+
|
|
139
|
+
sage: from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial
|
|
140
|
+
sage: X.<alpha> = InfinitePolynomialRing(ZZ)
|
|
141
|
+
sage: P.<alpha_1,alpha_2> = ZZ[]
|
|
142
|
+
|
|
143
|
+
Currently, ``P`` and ``X._P`` (the underlying polynomial ring of
|
|
144
|
+
``X``) both have two variables::
|
|
145
|
+
|
|
146
|
+
sage: X._P
|
|
147
|
+
Multivariate Polynomial Ring in alpha_1, alpha_0 over Integer Ring
|
|
148
|
+
|
|
149
|
+
By default, a coercion from ``P`` to ``X._P`` would not be name preserving.
|
|
150
|
+
However, this is taken care for; a name preserving conversion is impossible,
|
|
151
|
+
and by consequence an error is raised::
|
|
152
|
+
|
|
153
|
+
sage: InfinitePolynomial(X, (alpha_1+alpha_2)^2)
|
|
154
|
+
Traceback (most recent call last):
|
|
155
|
+
...
|
|
156
|
+
TypeError: Could not find a mapping of the passed element to this ring.
|
|
157
|
+
|
|
158
|
+
When extending the underlying polynomial ring, the construction of
|
|
159
|
+
an infinite polynomial works::
|
|
160
|
+
|
|
161
|
+
sage: alpha[2]
|
|
162
|
+
alpha_2
|
|
163
|
+
sage: InfinitePolynomial(X, (alpha_1+alpha_2)^2)
|
|
164
|
+
alpha_2^2 + 2*alpha_2*alpha_1 + alpha_1^2
|
|
165
|
+
|
|
166
|
+
In the sparse implementation, it is not checked whether the
|
|
167
|
+
polynomial really belongs to the parent, and when it does not,
|
|
168
|
+
the results may be unexpected due to coercions::
|
|
169
|
+
|
|
170
|
+
sage: Y.<alpha,beta> = InfinitePolynomialRing(GF(2), implementation='sparse')
|
|
171
|
+
sage: a = (alpha_1+alpha_2)^2
|
|
172
|
+
sage: InfinitePolynomial(Y, a)
|
|
173
|
+
alpha_0^2 + beta_0^2
|
|
174
|
+
|
|
175
|
+
However, it is checked when doing a conversion::
|
|
176
|
+
|
|
177
|
+
sage: Y(a)
|
|
178
|
+
alpha_2^2 + alpha_1^2
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
@staticmethod
|
|
182
|
+
def __classcall_private__(cls, A, p):
|
|
183
|
+
r"""
|
|
184
|
+
TESTS::
|
|
185
|
+
|
|
186
|
+
sage: from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial
|
|
187
|
+
sage: X.<x,y> = InfinitePolynomialRing(ZZ, implementation='sparse')
|
|
188
|
+
sage: xy = (x[0] + y[0]).polynomial()
|
|
189
|
+
sage: xy.parent()
|
|
190
|
+
Multivariate Polynomial Ring in x_1, x_0, y_1, y_0 over Integer Ring
|
|
191
|
+
sage: sparse_xy = InfinitePolynomial(X, xy); sparse_xy
|
|
192
|
+
x_0 + y_0
|
|
193
|
+
sage: isinstance(sparse_xy, InfinitePolynomial)
|
|
194
|
+
True
|
|
195
|
+
sage: type(sparse_xy)
|
|
196
|
+
<class 'sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse'>
|
|
197
|
+
sage: X.<x,y> = InfinitePolynomialRing(ZZ, implementation='dense')
|
|
198
|
+
sage: dense_xy = InfinitePolynomial(X, xy); dense_xy
|
|
199
|
+
x_0 + y_0
|
|
200
|
+
sage: isinstance(dense_xy, InfinitePolynomial)
|
|
201
|
+
True
|
|
202
|
+
sage: type(dense_xy)
|
|
203
|
+
<class 'sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense'>
|
|
204
|
+
"""
|
|
205
|
+
from sage.structure.element import parent
|
|
206
|
+
if hasattr(A, '_P'):
|
|
207
|
+
if parent(p) is A._P or (A._P.base_ring().has_coerce_map_from(parent(p))):
|
|
208
|
+
return InfinitePolynomial_dense(A, p)
|
|
209
|
+
# MPolynomialRing_polydict is crab. So, in that case, use sage_eval
|
|
210
|
+
from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict
|
|
211
|
+
if isinstance(A._P, MPolynomialRing_polydict):
|
|
212
|
+
from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering
|
|
213
|
+
from sage.misc.sage_eval import sage_eval
|
|
214
|
+
p = sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict()))
|
|
215
|
+
return InfinitePolynomial_dense(A, p)
|
|
216
|
+
else:
|
|
217
|
+
# Now there remains to fight the oddities and bugs of libsingular.
|
|
218
|
+
PP = p.parent()
|
|
219
|
+
if A._P.has_coerce_map_from(PP):
|
|
220
|
+
if A._P.ngens() == PP.ngens(): # coercion is sometimes by position!
|
|
221
|
+
f = PP.hom(PP.variable_names(), A._P)
|
|
222
|
+
try:
|
|
223
|
+
return InfinitePolynomial_dense(A, f(p))
|
|
224
|
+
except (ValueError, TypeError):
|
|
225
|
+
# last desperate attempt: String conversion
|
|
226
|
+
from sage.misc.sage_eval import sage_eval
|
|
227
|
+
from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering
|
|
228
|
+
# the base ring may be a function field, therefore
|
|
229
|
+
# we need GenDictWithBasering
|
|
230
|
+
return InfinitePolynomial_dense(A, sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict())))
|
|
231
|
+
return InfinitePolynomial_dense(A, A._P(p))
|
|
232
|
+
# there is no coercion, so, we set up a name-preserving map.
|
|
233
|
+
SV = set(repr(x) for x in p.variables())
|
|
234
|
+
f = PP.hom([x if x in SV else 0 for x in PP.variable_names()], A._P)
|
|
235
|
+
try:
|
|
236
|
+
return InfinitePolynomial_dense(A, f(p))
|
|
237
|
+
except (ValueError, TypeError):
|
|
238
|
+
# last desperate attempt: String conversion
|
|
239
|
+
from sage.misc.sage_eval import sage_eval
|
|
240
|
+
from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering
|
|
241
|
+
# the base ring may be a function field, therefore
|
|
242
|
+
# we need GenDictWithBasering
|
|
243
|
+
return InfinitePolynomial_dense(A, sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict())))
|
|
244
|
+
return InfinitePolynomial_sparse(A, p)
|
|
245
|
+
|
|
246
|
+
# Construction and other basic methods
|
|
247
|
+
# We assume that p is good input. Type checking etc. is now done
|
|
248
|
+
# in the _element_constructor_ of the parent.
|
|
249
|
+
def __init__(self, A, p):
|
|
250
|
+
"""
|
|
251
|
+
TESTS::
|
|
252
|
+
|
|
253
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
254
|
+
sage: a = x[1] + x[2]
|
|
255
|
+
sage: a == loads(dumps(a))
|
|
256
|
+
True
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
# Despite the above comment, it can still happen that p is in
|
|
260
|
+
# the wrong ring and we get here without going through
|
|
261
|
+
# _element_constructor_. See trac 22514 for examples.
|
|
262
|
+
# So a little extra checking is done here.
|
|
263
|
+
if not isinstance(p, MPolynomial) or p.base_ring() is not A.base_ring():
|
|
264
|
+
# coerce to a convenient multivariate polynomial ring
|
|
265
|
+
p = A._minP(p)
|
|
266
|
+
|
|
267
|
+
self._has_footprint = False
|
|
268
|
+
self._footprint = {}
|
|
269
|
+
self._p = p
|
|
270
|
+
RingElement.__init__(self, A)
|
|
271
|
+
|
|
272
|
+
def _repr_(self):
|
|
273
|
+
"""
|
|
274
|
+
TESTS::
|
|
275
|
+
|
|
276
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
277
|
+
sage: str(x[1] + x[2]) # indirect doctest
|
|
278
|
+
'x_2 + x_1'
|
|
279
|
+
"""
|
|
280
|
+
return repr(self._p)
|
|
281
|
+
|
|
282
|
+
def __hash__(self):
|
|
283
|
+
"""
|
|
284
|
+
TESTS::
|
|
285
|
+
|
|
286
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
287
|
+
sage: a = x[0] + x[1]
|
|
288
|
+
sage: b = 1 + 4*x[1]
|
|
289
|
+
sage: hash(a) != hash(b)
|
|
290
|
+
True
|
|
291
|
+
"""
|
|
292
|
+
return hash(self._p)
|
|
293
|
+
|
|
294
|
+
def polynomial(self):
|
|
295
|
+
"""
|
|
296
|
+
Return the underlying polynomial.
|
|
297
|
+
|
|
298
|
+
EXAMPLES::
|
|
299
|
+
|
|
300
|
+
sage: X.<x,y> = InfinitePolynomialRing(GF(7))
|
|
301
|
+
sage: p = x[2]*y[1] + 3*y[0]
|
|
302
|
+
sage: p
|
|
303
|
+
x_2*y_1 + 3*y_0
|
|
304
|
+
sage: p.polynomial()
|
|
305
|
+
x_2*y_1 + 3*y_0
|
|
306
|
+
sage: p.polynomial().parent()
|
|
307
|
+
Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0
|
|
308
|
+
over Finite Field of size 7
|
|
309
|
+
sage: p.parent()
|
|
310
|
+
Infinite polynomial ring in x, y over Finite Field of size 7
|
|
311
|
+
"""
|
|
312
|
+
return self._p
|
|
313
|
+
|
|
314
|
+
def _getAttributeNames(self):
|
|
315
|
+
"""
|
|
316
|
+
This method implements tab completion, see :issue:`6854`.
|
|
317
|
+
|
|
318
|
+
EXAMPLES::
|
|
319
|
+
|
|
320
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
321
|
+
sage: import sage.interfaces.tab_completion as s
|
|
322
|
+
sage: p = x[3]*x[2]
|
|
323
|
+
sage: s.completions('p.co',globals()) # indirect doctest
|
|
324
|
+
['p.coefficient',
|
|
325
|
+
'p.coefficients',
|
|
326
|
+
'p.constant_coefficient',
|
|
327
|
+
'p.content',
|
|
328
|
+
'p.content_ideal']
|
|
329
|
+
"""
|
|
330
|
+
return dir(self._p)
|
|
331
|
+
|
|
332
|
+
def __dir__(self):
|
|
333
|
+
"""
|
|
334
|
+
This method implements tab completion, see :issue:`6854`.
|
|
335
|
+
|
|
336
|
+
TESTS::
|
|
337
|
+
|
|
338
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
339
|
+
sage: import sage.interfaces.tab_completion as s
|
|
340
|
+
sage: p = x[3]*x[2]
|
|
341
|
+
sage: s.completions('p.co',globals()) # indirect doc test
|
|
342
|
+
['p.coefficient',
|
|
343
|
+
'p.coefficients',
|
|
344
|
+
'p.constant_coefficient',
|
|
345
|
+
'p.content',
|
|
346
|
+
'p.content_ideal']
|
|
347
|
+
sage: 'constant_coefficient' in dir(p) # indirect doctest
|
|
348
|
+
True
|
|
349
|
+
"""
|
|
350
|
+
return dir(self._p)
|
|
351
|
+
|
|
352
|
+
def __getattr__(self, s):
|
|
353
|
+
"""
|
|
354
|
+
NOTE:
|
|
355
|
+
|
|
356
|
+
This method will only be called if an attribute of ``self``
|
|
357
|
+
is requested that is not known to Python. In that case,
|
|
358
|
+
the corresponding attribute of the underlying polynomial
|
|
359
|
+
of ``self`` is returned.
|
|
360
|
+
|
|
361
|
+
EXAMPLES:
|
|
362
|
+
|
|
363
|
+
Elements of Infinite Polynomial Rings have no genuine
|
|
364
|
+
``_latex_`` method. But the method inherited from the
|
|
365
|
+
underlying polynomial suffices::
|
|
366
|
+
|
|
367
|
+
sage: X.<alpha> = InfinitePolynomialRing(QQ)
|
|
368
|
+
sage: latex(alpha[3]*alpha[2]^2) # indirect doctest
|
|
369
|
+
\alpha_{3} \alpha_{2}^{2}
|
|
370
|
+
|
|
371
|
+
Related with issues :issue:`6854` and :issue:`7580`, the attribute
|
|
372
|
+
``__methods__`` is treated in a special way, which
|
|
373
|
+
makes introspection and tab completion work::
|
|
374
|
+
|
|
375
|
+
sage: import sage.interfaces.tab_completion as s
|
|
376
|
+
sage: p = alpha[3]*alpha[2]^2
|
|
377
|
+
sage: s.completions('p.co',globals()) # indirect doc test
|
|
378
|
+
['p.coefficient',
|
|
379
|
+
'p.coefficients',
|
|
380
|
+
'p.constant_coefficient',
|
|
381
|
+
'p.content',
|
|
382
|
+
'p.content_ideal']
|
|
383
|
+
sage: 'constant_coefficient' in dir(p) # indirect doctest
|
|
384
|
+
True
|
|
385
|
+
"""
|
|
386
|
+
if s == '__members__':
|
|
387
|
+
return dir(self._p)
|
|
388
|
+
if s == '__methods__':
|
|
389
|
+
return [X for X in dir(self._p) if hasattr(self._p, X)
|
|
390
|
+
and ('method' in str(type(getattr(self._p, X))))]
|
|
391
|
+
try:
|
|
392
|
+
return getattr(self._p, s)
|
|
393
|
+
except AttributeError:
|
|
394
|
+
raise AttributeError('%s has no attribute %s' % (self.__class__, s))
|
|
395
|
+
|
|
396
|
+
def subs(self, fixed=None, **kwargs):
|
|
397
|
+
"""
|
|
398
|
+
Substitute variables in ``self``.
|
|
399
|
+
|
|
400
|
+
INPUT:
|
|
401
|
+
|
|
402
|
+
- ``fixed`` -- (optional) ``dict`` with ``{variable: value}`` pairs
|
|
403
|
+
- ``**kwargs`` -- named parameters
|
|
404
|
+
|
|
405
|
+
OUTPUT: the resulting substitution
|
|
406
|
+
|
|
407
|
+
EXAMPLES::
|
|
408
|
+
|
|
409
|
+
sage: R.<x,y> = InfinitePolynomialRing(QQ)
|
|
410
|
+
sage: f = x[1] + x[1]*x[2]*x[3]
|
|
411
|
+
|
|
412
|
+
Passing ``fixed={x[1]: x[0]}``. Note that the keys may be given
|
|
413
|
+
using the generators of the infinite polynomial ring
|
|
414
|
+
or as a string::
|
|
415
|
+
|
|
416
|
+
sage: f.subs({x[1]: x[0]})
|
|
417
|
+
x_3*x_2*x_0 + x_0
|
|
418
|
+
sage: f.subs({'x_1': x[0]})
|
|
419
|
+
x_3*x_2*x_0 + x_0
|
|
420
|
+
|
|
421
|
+
Passing the variables as names parameters::
|
|
422
|
+
|
|
423
|
+
sage: f.subs(x_1=y[1])
|
|
424
|
+
x_3*x_2*y_1 + y_1
|
|
425
|
+
sage: f.subs(x_1=y[1], x_2=2)
|
|
426
|
+
2*x_3*y_1 + y_1
|
|
427
|
+
|
|
428
|
+
The substitution returns the original polynomial if you try
|
|
429
|
+
to substitute a variable not present::
|
|
430
|
+
|
|
431
|
+
sage: g = x[0] + x[1]
|
|
432
|
+
sage: g.subs({y[0]: x[0]})
|
|
433
|
+
x_1 + x_0
|
|
434
|
+
|
|
435
|
+
The substitution can also handle matrices::
|
|
436
|
+
|
|
437
|
+
sage: # needs sage.modules
|
|
438
|
+
sage: M = matrix([[1,0], [0,2]])
|
|
439
|
+
sage: N = matrix([[0,3], [4,0]])
|
|
440
|
+
sage: g = x[0]^2 + 3*x[1]
|
|
441
|
+
sage: g.subs({'x_0': M})
|
|
442
|
+
[3*x_1 + 1 0]
|
|
443
|
+
[ 0 3*x_1 + 4]
|
|
444
|
+
sage: g.subs({x[0]: M, x[1]: N})
|
|
445
|
+
[ 1 9]
|
|
446
|
+
[12 4]
|
|
447
|
+
|
|
448
|
+
If you pass both ``fixed`` and ``kwargs``, any conflicts
|
|
449
|
+
will defer to ``fixed``::
|
|
450
|
+
|
|
451
|
+
sage: R.<x,y> = InfinitePolynomialRing(QQ)
|
|
452
|
+
sage: f = x[0]
|
|
453
|
+
sage: f.subs({x[0]: 1})
|
|
454
|
+
1
|
|
455
|
+
sage: f.subs(x_0=5)
|
|
456
|
+
5
|
|
457
|
+
sage: f.subs({x[0]: 1}, x_0=5)
|
|
458
|
+
1
|
|
459
|
+
|
|
460
|
+
TESTS::
|
|
461
|
+
|
|
462
|
+
sage: # needs sage.modules
|
|
463
|
+
sage: g.subs(fixed=x[0], x_1=N)
|
|
464
|
+
Traceback (most recent call last):
|
|
465
|
+
...
|
|
466
|
+
ValueError: fixed must be a dict
|
|
467
|
+
"""
|
|
468
|
+
if fixed:
|
|
469
|
+
if not isinstance(fixed, dict):
|
|
470
|
+
raise ValueError('fixed must be a dict')
|
|
471
|
+
kwargs.update(fixed)
|
|
472
|
+
try:
|
|
473
|
+
return self(**kwargs)
|
|
474
|
+
except TypeError:
|
|
475
|
+
str_kwargs = {str(k): v for k, v in kwargs.items()}
|
|
476
|
+
return self(**str_kwargs)
|
|
477
|
+
|
|
478
|
+
def ring(self):
|
|
479
|
+
"""
|
|
480
|
+
The ring which ``self`` belongs to.
|
|
481
|
+
|
|
482
|
+
This is the same as ``self.parent()``.
|
|
483
|
+
|
|
484
|
+
EXAMPLES::
|
|
485
|
+
|
|
486
|
+
sage: X.<x,y> = InfinitePolynomialRing(ZZ,implementation='sparse')
|
|
487
|
+
sage: p = x[100]*y[1]^3*x[1]^2 + 2*x[10]*y[30]
|
|
488
|
+
sage: p.ring()
|
|
489
|
+
Infinite polynomial ring in x, y over Integer Ring
|
|
490
|
+
"""
|
|
491
|
+
return self.parent()
|
|
492
|
+
|
|
493
|
+
def is_unit(self):
|
|
494
|
+
r"""
|
|
495
|
+
Answer whether ``self`` is a unit.
|
|
496
|
+
|
|
497
|
+
EXAMPLES::
|
|
498
|
+
|
|
499
|
+
sage: R1.<x,y> = InfinitePolynomialRing(ZZ)
|
|
500
|
+
sage: R2.<a,b> = InfinitePolynomialRing(QQ)
|
|
501
|
+
sage: (1 + x[2]).is_unit()
|
|
502
|
+
False
|
|
503
|
+
sage: R1(1).is_unit()
|
|
504
|
+
True
|
|
505
|
+
sage: R1(2).is_unit()
|
|
506
|
+
False
|
|
507
|
+
sage: R2(2).is_unit()
|
|
508
|
+
True
|
|
509
|
+
sage: (1 + a[2]).is_unit()
|
|
510
|
+
False
|
|
511
|
+
|
|
512
|
+
Check that :issue:`22454` is fixed::
|
|
513
|
+
|
|
514
|
+
sage: _.<x> = InfinitePolynomialRing(Zmod(4))
|
|
515
|
+
sage: (1 + 2*x[0]).is_unit()
|
|
516
|
+
True
|
|
517
|
+
sage: (x[0]*x[1]).is_unit()
|
|
518
|
+
False
|
|
519
|
+
sage: _.<x> = InfinitePolynomialRing(Zmod(900))
|
|
520
|
+
sage: (7+150*x[0] + 30*x[1] + 120*x[1]*x[100]).is_unit()
|
|
521
|
+
True
|
|
522
|
+
|
|
523
|
+
TESTS::
|
|
524
|
+
|
|
525
|
+
sage: R.<x> = InfinitePolynomialRing(ZZ.quotient_ring(8))
|
|
526
|
+
sage: [R(i).is_unit() for i in range(8)]
|
|
527
|
+
[False, True, False, True, False, True, False, True]
|
|
528
|
+
"""
|
|
529
|
+
return self._p.is_unit()
|
|
530
|
+
|
|
531
|
+
def is_nilpotent(self):
|
|
532
|
+
r"""
|
|
533
|
+
Return ``True`` if ``self`` is nilpotent, i.e., some power of ``self``
|
|
534
|
+
is 0.
|
|
535
|
+
|
|
536
|
+
EXAMPLES::
|
|
537
|
+
|
|
538
|
+
sage: R.<x> = InfinitePolynomialRing(QQbar) # needs sage.rings.number_field
|
|
539
|
+
sage: (x[0] + x[1]).is_nilpotent() # needs sage.rings.number_field
|
|
540
|
+
False
|
|
541
|
+
sage: R(0).is_nilpotent() # needs sage.rings.number_field
|
|
542
|
+
True
|
|
543
|
+
sage: _.<x> = InfinitePolynomialRing(Zmod(4))
|
|
544
|
+
sage: (2*x[0]).is_nilpotent()
|
|
545
|
+
True
|
|
546
|
+
sage: (2+x[4]*x[7]).is_nilpotent()
|
|
547
|
+
False
|
|
548
|
+
sage: _.<y> = InfinitePolynomialRing(Zmod(100))
|
|
549
|
+
sage: (5+2*y[0] + 10*(y[0]^2+y[1]^2)).is_nilpotent()
|
|
550
|
+
False
|
|
551
|
+
sage: (10*y[2] + 20*y[5] - 30*y[2]*y[5] + 70*(y[2]^2+y[5]^2)).is_nilpotent()
|
|
552
|
+
True
|
|
553
|
+
"""
|
|
554
|
+
return self._p.is_nilpotent()
|
|
555
|
+
|
|
556
|
+
def numerator(self):
|
|
557
|
+
r"""
|
|
558
|
+
Return a numerator of ``self``, computed as ``self * self.denominator()``.
|
|
559
|
+
|
|
560
|
+
.. WARNING::
|
|
561
|
+
|
|
562
|
+
This is not the numerator of the rational function
|
|
563
|
+
defined by ``self``, which would always be ``self`` since it is a
|
|
564
|
+
polynomial.
|
|
565
|
+
|
|
566
|
+
EXAMPLES::
|
|
567
|
+
|
|
568
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
569
|
+
sage: p = 2/3*x[1] + 4/9*x[2] - 2*x[1]*x[3]
|
|
570
|
+
sage: num = p.numerator(); num
|
|
571
|
+
-18*x_3*x_1 + 4*x_2 + 6*x_1
|
|
572
|
+
|
|
573
|
+
TESTS::
|
|
574
|
+
|
|
575
|
+
sage: num.parent()
|
|
576
|
+
Infinite polynomial ring in x over Rational Field
|
|
577
|
+
|
|
578
|
+
Check that :issue:`37756` is fixed::
|
|
579
|
+
|
|
580
|
+
sage: R.<a> = InfinitePolynomialRing(QQ)
|
|
581
|
+
sage: P.<x,y> = QQ[]
|
|
582
|
+
sage: FF = P.fraction_field()
|
|
583
|
+
sage: FF(a[0])
|
|
584
|
+
Traceback (most recent call last):
|
|
585
|
+
...
|
|
586
|
+
TypeError: Could not find a mapping of the passed element to this ring.
|
|
587
|
+
"""
|
|
588
|
+
P = self.parent()
|
|
589
|
+
return InfinitePolynomial(P, self._p.numerator())
|
|
590
|
+
|
|
591
|
+
@cached_method
|
|
592
|
+
def variables(self):
|
|
593
|
+
"""
|
|
594
|
+
Return the variables occurring in ``self`` (tuple of elements of some polynomial ring).
|
|
595
|
+
|
|
596
|
+
EXAMPLES::
|
|
597
|
+
|
|
598
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
599
|
+
sage: p = x[1] + x[2] - 2*x[1]*x[3]
|
|
600
|
+
sage: p.variables()
|
|
601
|
+
(x_3, x_2, x_1)
|
|
602
|
+
sage: x[1].variables()
|
|
603
|
+
(x_1,)
|
|
604
|
+
sage: X(1).variables()
|
|
605
|
+
()
|
|
606
|
+
"""
|
|
607
|
+
if hasattr(self._p, 'variables'):
|
|
608
|
+
P = self.parent()
|
|
609
|
+
return tuple(InfinitePolynomial(P, v) for v in self._p.variables())
|
|
610
|
+
return ()
|
|
611
|
+
|
|
612
|
+
def monomials(self):
|
|
613
|
+
"""
|
|
614
|
+
Return the list of monomials in ``self``.
|
|
615
|
+
|
|
616
|
+
The returned list is decreasingly ordered by the term ordering of
|
|
617
|
+
``self.parent()``.
|
|
618
|
+
|
|
619
|
+
EXAMPLES::
|
|
620
|
+
|
|
621
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
622
|
+
sage: p = x[1]^3 + x[2] - 2*x[1]*x[3]
|
|
623
|
+
sage: p.monomials()
|
|
624
|
+
[x_3*x_1, x_2, x_1^3]
|
|
625
|
+
|
|
626
|
+
sage: X.<x> = InfinitePolynomialRing(QQ, order='deglex')
|
|
627
|
+
sage: p = x[1]^3 + x[2] - 2*x[1]*x[3]
|
|
628
|
+
sage: p.monomials()
|
|
629
|
+
[x_1^3, x_3*x_1, x_2]
|
|
630
|
+
"""
|
|
631
|
+
P = self.parent()
|
|
632
|
+
return [InfinitePolynomial(P, m) for m in self._p.monomials()]
|
|
633
|
+
|
|
634
|
+
def monomial_coefficient(self, mon):
|
|
635
|
+
"""
|
|
636
|
+
Return the base ring element that is the coefficient of ``mon``
|
|
637
|
+
in ``self``.
|
|
638
|
+
|
|
639
|
+
This function contrasts with the function :meth:`coefficient`,
|
|
640
|
+
which returns the coefficient of a monomial viewing this
|
|
641
|
+
polynomial in a polynomial ring over a base ring having fewer
|
|
642
|
+
variables.
|
|
643
|
+
|
|
644
|
+
INPUT:
|
|
645
|
+
|
|
646
|
+
- ``mon`` -- a monomial in the parent of ``self``
|
|
647
|
+
|
|
648
|
+
OUTPUT: coefficient in base ring
|
|
649
|
+
|
|
650
|
+
.. SEEALSO::
|
|
651
|
+
|
|
652
|
+
For coefficients in a base ring of fewer variables,
|
|
653
|
+
look at :meth:`coefficient`.
|
|
654
|
+
|
|
655
|
+
EXAMPLES::
|
|
656
|
+
|
|
657
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
658
|
+
sage: f = 2*x[0]*x[2] + 3*x[1]^2
|
|
659
|
+
sage: c = f.monomial_coefficient(x[1]^2); c
|
|
660
|
+
3
|
|
661
|
+
sage: c.parent()
|
|
662
|
+
Rational Field
|
|
663
|
+
|
|
664
|
+
sage: c = f.coefficient(x[2]); c
|
|
665
|
+
2*x_0
|
|
666
|
+
sage: c.parent()
|
|
667
|
+
Infinite polynomial ring in x over Rational Field
|
|
668
|
+
"""
|
|
669
|
+
return self._p.monomial_coefficient(mon._p)
|
|
670
|
+
|
|
671
|
+
@cached_method
|
|
672
|
+
def max_index(self):
|
|
673
|
+
r"""
|
|
674
|
+
Return the maximal index of a variable occurring in ``self``, or -1 if ``self`` is scalar.
|
|
675
|
+
|
|
676
|
+
EXAMPLES::
|
|
677
|
+
|
|
678
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
679
|
+
sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4]
|
|
680
|
+
sage: p.max_index()
|
|
681
|
+
4
|
|
682
|
+
sage: x[0].max_index()
|
|
683
|
+
0
|
|
684
|
+
sage: X(10).max_index()
|
|
685
|
+
-1
|
|
686
|
+
"""
|
|
687
|
+
return max([Integer(str(X).split('_')[1]) for X in self.variables()]+[-1])
|
|
688
|
+
|
|
689
|
+
def _rmul_(self, left):
|
|
690
|
+
"""
|
|
691
|
+
TESTS::
|
|
692
|
+
|
|
693
|
+
sage: R.<alpha,beta> = InfinitePolynomialRing(QQ, implementation='sparse')
|
|
694
|
+
sage: R.from_base_ring(4) # indirect doctest
|
|
695
|
+
4
|
|
696
|
+
"""
|
|
697
|
+
return type(self)(self.parent(), left * self._p)
|
|
698
|
+
|
|
699
|
+
def _lmul_(self, right):
|
|
700
|
+
"""
|
|
701
|
+
TESTS::
|
|
702
|
+
|
|
703
|
+
sage: R.<alpha,beta> = InfinitePolynomialRing(QQ, implementation='sparse')
|
|
704
|
+
sage: alpha[3]*4 # indirect doctest
|
|
705
|
+
4*alpha_3
|
|
706
|
+
"""
|
|
707
|
+
return type(self)(self.parent(), self._p * right)
|
|
708
|
+
|
|
709
|
+
def _div_(self, x):
|
|
710
|
+
r"""
|
|
711
|
+
Division of Infinite Polynomials.
|
|
712
|
+
|
|
713
|
+
EXAMPLES:
|
|
714
|
+
|
|
715
|
+
Division by a rational over `\QQ`::
|
|
716
|
+
|
|
717
|
+
sage: X.<x> = InfinitePolynomialRing(QQ, implementation='sparse')
|
|
718
|
+
sage: x[0]/2
|
|
719
|
+
1/2*x_0
|
|
720
|
+
|
|
721
|
+
Division by an integer over `\ZZ`::
|
|
722
|
+
|
|
723
|
+
sage: R.<x> = InfinitePolynomialRing(ZZ, implementation='sparse')
|
|
724
|
+
sage: p = x[3] + x[2]
|
|
725
|
+
sage: q = p/2
|
|
726
|
+
sage: q
|
|
727
|
+
1/2*x_3 + 1/2*x_2
|
|
728
|
+
sage: q.parent()
|
|
729
|
+
Infinite polynomial ring in x over Rational Field
|
|
730
|
+
|
|
731
|
+
Division by a nonzero element::
|
|
732
|
+
|
|
733
|
+
sage: R.<x> = InfinitePolynomialRing(QQ, implementation='sparse')
|
|
734
|
+
sage: 1/x[1]
|
|
735
|
+
1/x_1
|
|
736
|
+
sage: (x[0]/x[0])
|
|
737
|
+
x_0/x_0
|
|
738
|
+
sage: qt = 1/x[2] + 2/x[1]; qt
|
|
739
|
+
(2*x_2 + x_1)/(x_2*x_1)
|
|
740
|
+
sage: qt.parent()
|
|
741
|
+
Fraction Field of Infinite polynomial ring in x over Rational Field
|
|
742
|
+
|
|
743
|
+
sage: z = 1/(x[2]*(x[1]+x[2]))+1/(x[1]*(x[1]+x[2]))
|
|
744
|
+
sage: z.parent()
|
|
745
|
+
Fraction Field of Infinite polynomial ring in x over Rational Field
|
|
746
|
+
sage: factor(z) # needs sage.libs.singular
|
|
747
|
+
x_1^-1 * x_2^-1
|
|
748
|
+
"""
|
|
749
|
+
if not x.variables():
|
|
750
|
+
p = self.base_ring()(x._p)
|
|
751
|
+
divisor = self.base_ring().one() / p # use induction
|
|
752
|
+
OUTP = self.parent().tensor_with_ring(divisor.base_ring())
|
|
753
|
+
return OUTP(self) * OUTP(divisor)
|
|
754
|
+
else:
|
|
755
|
+
from sage.rings.fraction_field_element import FractionFieldElement
|
|
756
|
+
field = self.parent().fraction_field()
|
|
757
|
+
# there remains a problem in reduction
|
|
758
|
+
return FractionFieldElement(field, self, x, reduce=False)
|
|
759
|
+
|
|
760
|
+
def _floordiv_(self, x):
|
|
761
|
+
"""
|
|
762
|
+
EXAMPLES::
|
|
763
|
+
|
|
764
|
+
sage: X.<x> = InfinitePolynomialRing(ZZ)
|
|
765
|
+
sage: x[2]//x[2] # indirect doctest
|
|
766
|
+
1
|
|
767
|
+
"""
|
|
768
|
+
try:
|
|
769
|
+
return InfinitePolynomial_sparse(self.parent(), self._p // x._p)
|
|
770
|
+
except Exception:
|
|
771
|
+
pass
|
|
772
|
+
# We can now assume that self._p and x._p actually are polynomials,
|
|
773
|
+
# hence, their parent is not just the underlying ring.
|
|
774
|
+
VarList = list(set(self._p.parent().variable_names()).union(set(x._p.parent().variable_names())))
|
|
775
|
+
VarList.sort(key=self.parent().varname_key, reverse=True)
|
|
776
|
+
if VarList:
|
|
777
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
778
|
+
R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)
|
|
779
|
+
else:
|
|
780
|
+
R = self._p.base_ring()
|
|
781
|
+
return InfinitePolynomial_sparse(self.parent(), R(self._p) // R(x._p))
|
|
782
|
+
|
|
783
|
+
@cached_method
|
|
784
|
+
def lm(self):
|
|
785
|
+
"""
|
|
786
|
+
The leading monomial of ``self``.
|
|
787
|
+
|
|
788
|
+
EXAMPLES::
|
|
789
|
+
|
|
790
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
791
|
+
sage: p = 2*x[10]*y[30] + x[10]*y[1]^3*x[1]^2
|
|
792
|
+
sage: p.lm()
|
|
793
|
+
x_10*x_1^2*y_1^3
|
|
794
|
+
"""
|
|
795
|
+
if hasattr(self._p, 'lm'):
|
|
796
|
+
return InfinitePolynomial(self.parent(), self._p.lm())
|
|
797
|
+
if self._p == 0:
|
|
798
|
+
return self
|
|
799
|
+
if hasattr(self._p, 'variable_name'): # if it is univariate
|
|
800
|
+
return InfinitePolynomial(self.parent(),
|
|
801
|
+
self._p.parent().gen() ** max(self._p.exponents()))
|
|
802
|
+
return self # if it is scalar
|
|
803
|
+
|
|
804
|
+
@cached_method
|
|
805
|
+
def lc(self):
|
|
806
|
+
"""
|
|
807
|
+
The coefficient of the leading term of ``self``.
|
|
808
|
+
|
|
809
|
+
EXAMPLES::
|
|
810
|
+
|
|
811
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
812
|
+
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
|
|
813
|
+
sage: p.lc()
|
|
814
|
+
3
|
|
815
|
+
"""
|
|
816
|
+
if hasattr(self._p, 'lc'):
|
|
817
|
+
return self._p.lc()
|
|
818
|
+
if hasattr(self._p, 'variable_name'): # univariate case
|
|
819
|
+
return self._p.leading_coefficient()
|
|
820
|
+
# scalar case
|
|
821
|
+
return self._p
|
|
822
|
+
|
|
823
|
+
@cached_method
|
|
824
|
+
def lt(self):
|
|
825
|
+
"""
|
|
826
|
+
The leading term (= product of coefficient and monomial) of ``self``.
|
|
827
|
+
|
|
828
|
+
EXAMPLES::
|
|
829
|
+
|
|
830
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
831
|
+
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
|
|
832
|
+
sage: p.lt()
|
|
833
|
+
3*x_10*x_1^2*y_1^3
|
|
834
|
+
"""
|
|
835
|
+
if hasattr(self._p, 'lt'):
|
|
836
|
+
return InfinitePolynomial(self.parent(), self._p.lt())
|
|
837
|
+
if self._p == 0:
|
|
838
|
+
return self
|
|
839
|
+
if hasattr(self._p, 'variable_name'): # if it is univariate
|
|
840
|
+
return InfinitePolynomial(self.parent(), self._p.leading_coefficient()*self._p.parent().gen()**max(self._p.exponents()))
|
|
841
|
+
return self # if it is scalar
|
|
842
|
+
|
|
843
|
+
def tail(self):
|
|
844
|
+
"""
|
|
845
|
+
The tail of ``self`` (this is ``self`` minus its leading term).
|
|
846
|
+
|
|
847
|
+
EXAMPLES::
|
|
848
|
+
|
|
849
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
850
|
+
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
|
|
851
|
+
sage: p.tail()
|
|
852
|
+
2*x_10*y_30
|
|
853
|
+
"""
|
|
854
|
+
return self-self.lt()
|
|
855
|
+
|
|
856
|
+
def squeezed(self):
|
|
857
|
+
"""
|
|
858
|
+
Reduce the variable indices occurring in ``self``.
|
|
859
|
+
|
|
860
|
+
OUTPUT:
|
|
861
|
+
|
|
862
|
+
Apply a permutation to ``self`` that does not change the order of
|
|
863
|
+
the variable indices of ``self`` but squeezes them into the range
|
|
864
|
+
1,2,...
|
|
865
|
+
|
|
866
|
+
EXAMPLES::
|
|
867
|
+
|
|
868
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ,implementation='sparse')
|
|
869
|
+
sage: p = x[1]*y[100] + x[50]*y[1000]
|
|
870
|
+
sage: p.squeezed()
|
|
871
|
+
x_2*y_4 + x_1*y_3
|
|
872
|
+
"""
|
|
873
|
+
Indices = set([0] + [Integer(str(Y).split('_')[1])
|
|
874
|
+
for Y in self.variables()])
|
|
875
|
+
Indices = sorted(Indices)
|
|
876
|
+
|
|
877
|
+
def P(n):
|
|
878
|
+
return Indices.index(n) if n in Indices else n
|
|
879
|
+
|
|
880
|
+
return self**P
|
|
881
|
+
|
|
882
|
+
def footprint(self):
|
|
883
|
+
"""
|
|
884
|
+
Leading exponents sorted by index and generator.
|
|
885
|
+
|
|
886
|
+
OUTPUT: ``D``; dictionary whose keys are the occurring variable indices
|
|
887
|
+
|
|
888
|
+
``D[s]`` is a list ``[i_1,...,i_n]``, where ``i_j`` gives the
|
|
889
|
+
exponent of ``self.parent().gen(j)[s]`` in the leading
|
|
890
|
+
term of ``self``.
|
|
891
|
+
|
|
892
|
+
EXAMPLES::
|
|
893
|
+
|
|
894
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
895
|
+
sage: p = x[30]*y[1]^3*x[1]^2 + 2*x[10]*y[30]
|
|
896
|
+
sage: sorted(p.footprint().items())
|
|
897
|
+
[(1, [2, 3]), (30, [1, 0])]
|
|
898
|
+
|
|
899
|
+
TESTS:
|
|
900
|
+
|
|
901
|
+
This is a test whether it also works when the underlying polynomial ring is
|
|
902
|
+
not implemented in libsingular::
|
|
903
|
+
|
|
904
|
+
sage: X.<x> = InfinitePolynomialRing(ZZ)
|
|
905
|
+
sage: Y.<y,z> = X[]
|
|
906
|
+
sage: Z.<a> = InfinitePolynomialRing(Y)
|
|
907
|
+
sage: Z
|
|
908
|
+
Infinite polynomial ring in a over Multivariate Polynomial Ring in y, z over Infinite polynomial ring in x over Integer Ring
|
|
909
|
+
sage: type(Z._P)
|
|
910
|
+
<class 'sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_with_category'>
|
|
911
|
+
sage: p = a[12]^3*a[2]^7*a[4] + a[4]*a[2]
|
|
912
|
+
sage: sorted(p.footprint().items())
|
|
913
|
+
[(2, [7]), (4, [1]), (12, [3])]
|
|
914
|
+
"""
|
|
915
|
+
if not self._has_footprint:
|
|
916
|
+
PARENT = self.parent()
|
|
917
|
+
l = len(self.parent()._names)
|
|
918
|
+
# get the pairs (shift,exponent) of the leading monomial, indexed by the variable names
|
|
919
|
+
Vars = self._p.parent().variable_names()
|
|
920
|
+
from sage.rings.polynomial.multi_polynomial import MPolynomial_libsingular
|
|
921
|
+
if isinstance(self._p, MPolynomial_libsingular):
|
|
922
|
+
L = [(Vars[i].split('_'), e) for i, e in enumerate(self._p.lm().exponents(as_ETuples=False)[0]) if e]
|
|
923
|
+
elif hasattr(self._p, 'lm'):
|
|
924
|
+
# self._p is multivariate, but not libsingular, hence,
|
|
925
|
+
# exponents is slow and does not accept the optional argument as_ETuples.
|
|
926
|
+
# Thus, fall back to regular expressions
|
|
927
|
+
L = PARENT._find_varpowers.findall(repr(self.lm()._p))
|
|
928
|
+
L = [((x[0:2]), int(x[2]) if x[2] else 1) for x in L]
|
|
929
|
+
else: # it is a univariate polynomial -- this should never happen, but just in case...
|
|
930
|
+
L = [(Vars[0].split('_'), self._p.degree())]
|
|
931
|
+
for t in L:
|
|
932
|
+
n = t[0][0] # the variable *n*ame
|
|
933
|
+
s = int(t[0][1]) # the variable *s*hift
|
|
934
|
+
if s not in self._footprint:
|
|
935
|
+
self._footprint[s] = [0]*l
|
|
936
|
+
self._footprint[s][self.parent()._name_dict[n]] = t[1] # the exponent
|
|
937
|
+
self._has_footprint = True
|
|
938
|
+
return self._footprint
|
|
939
|
+
|
|
940
|
+
def symmetric_cancellation_order(self, other):
|
|
941
|
+
"""
|
|
942
|
+
Comparison of leading terms by Symmetric Cancellation Order, `<_{sc}`.
|
|
943
|
+
|
|
944
|
+
INPUT:
|
|
945
|
+
|
|
946
|
+
- ``self``, ``other`` -- two Infinite Polynomials
|
|
947
|
+
|
|
948
|
+
ASSUMPTION:
|
|
949
|
+
|
|
950
|
+
Both Infinite Polynomials are nonzero.
|
|
951
|
+
|
|
952
|
+
OUTPUT:
|
|
953
|
+
|
|
954
|
+
``(c, sigma, w)``, where
|
|
955
|
+
|
|
956
|
+
* c = -1,0,1, or None if the leading monomial of ``self`` is smaller, equal,
|
|
957
|
+
greater, or incomparable with respect to ``other`` in the monomial
|
|
958
|
+
ordering of the Infinite Polynomial Ring
|
|
959
|
+
* sigma is a permutation witnessing
|
|
960
|
+
``self`` `<_{sc}` ``other`` (resp. ``self`` `>_{sc}` ``other``)
|
|
961
|
+
or is 1 if ``self.lm()==other.lm()``
|
|
962
|
+
* w is 1 or is a term so that
|
|
963
|
+
``w*self.lt()^sigma == other.lt()`` if `c\\le 0`, and
|
|
964
|
+
``w*other.lt()^sigma == self.lt()`` if `c=1`
|
|
965
|
+
|
|
966
|
+
THEORY:
|
|
967
|
+
|
|
968
|
+
If the Symmetric Cancellation Order is a well-quasi-ordering
|
|
969
|
+
then computation of Groebner bases always terminates. This is
|
|
970
|
+
the case, e.g., if the monomial order is lexicographic. For
|
|
971
|
+
that reason, lexicographic order is our default order.
|
|
972
|
+
|
|
973
|
+
EXAMPLES::
|
|
974
|
+
|
|
975
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
976
|
+
sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]^2)
|
|
977
|
+
(None, 1, 1)
|
|
978
|
+
sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])
|
|
979
|
+
(-1, [2, 3, 1], y_1)
|
|
980
|
+
sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])
|
|
981
|
+
(None, 1, 1)
|
|
982
|
+
sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2])
|
|
983
|
+
(-1, [2, 3, 1], 1)
|
|
984
|
+
"""
|
|
985
|
+
PARENT = self.parent()
|
|
986
|
+
other = PARENT(other)
|
|
987
|
+
slt = self.lt()
|
|
988
|
+
olt = other.lt()
|
|
989
|
+
if self.lm() == other.lm():
|
|
990
|
+
if olt == 0:
|
|
991
|
+
return (0, 1, 1)
|
|
992
|
+
return (0, 1, self.lc() / other.lc())
|
|
993
|
+
if self.lm() < other.lm():
|
|
994
|
+
rawcmp = -1
|
|
995
|
+
Fsmall = {k: list(v) for k, v in self.footprint().items()}
|
|
996
|
+
Fbig = {k: list(v) for k, v in other.footprint().items()}
|
|
997
|
+
ltsmall = slt
|
|
998
|
+
ltbig = olt
|
|
999
|
+
else:
|
|
1000
|
+
rawcmp = 1
|
|
1001
|
+
Fbig = {k: list(v) for k, v in self.footprint().items()}
|
|
1002
|
+
Fsmall = {k: list(v) for k, v in other.footprint().items()}
|
|
1003
|
+
ltbig = slt
|
|
1004
|
+
ltsmall = olt
|
|
1005
|
+
# Case 1: one of the Infinite Polynomials is scalar.
|
|
1006
|
+
if not Fsmall:
|
|
1007
|
+
return (rawcmp, 1, ltbig/ltsmall)
|
|
1008
|
+
# "not Fbig" is now impossible, because we only consider *global* monomial orderings.
|
|
1009
|
+
# These are the occurring shifts:
|
|
1010
|
+
Lsmall = sorted(Fsmall.keys())
|
|
1011
|
+
Lbig = sorted(Fbig.keys())
|
|
1012
|
+
P = list(range(Lbig[-1] + 1))
|
|
1013
|
+
gens = list(range(PARENT.ngens()))
|
|
1014
|
+
if Lsmall[0] == 0:
|
|
1015
|
+
if 0 not in Fbig:
|
|
1016
|
+
return (None, 1, 1)
|
|
1017
|
+
Lsmall.pop(0)
|
|
1018
|
+
Lbig.pop(0)
|
|
1019
|
+
ExpoSmall = Fsmall[0]
|
|
1020
|
+
ExpoBig = Fbig[0]
|
|
1021
|
+
for k in gens:
|
|
1022
|
+
if ExpoBig[k] < ExpoSmall[k]:
|
|
1023
|
+
return (None, 1, 1)
|
|
1024
|
+
ExpoBig[k] -= ExpoSmall[k]
|
|
1025
|
+
lenBig = len(Lbig)
|
|
1026
|
+
j = -1 # will have Lbig[j] -- a shift of the bigger polynomial
|
|
1027
|
+
for i in Lsmall: # i is a shift of the smaller polynomial
|
|
1028
|
+
j += 1
|
|
1029
|
+
ExpoSmall = Fsmall[i]
|
|
1030
|
+
while j < lenBig:
|
|
1031
|
+
found = False
|
|
1032
|
+
if Lbig[j] >= i:
|
|
1033
|
+
ExpoBigSave = list(Fbig[Lbig[j]])
|
|
1034
|
+
ExpoBig = Fbig[Lbig[j]]
|
|
1035
|
+
found = True
|
|
1036
|
+
for k in gens:
|
|
1037
|
+
if ExpoBig[k] < ExpoSmall[k]:
|
|
1038
|
+
found = False
|
|
1039
|
+
Fbig[Lbig[j]] = ExpoBigSave
|
|
1040
|
+
break
|
|
1041
|
+
ExpoBig[k] -= ExpoSmall[k]
|
|
1042
|
+
if found:
|
|
1043
|
+
break
|
|
1044
|
+
j += 1
|
|
1045
|
+
if j == lenBig:
|
|
1046
|
+
# no "increasing" permutation transforms
|
|
1047
|
+
# the smaller monomial into a factor of
|
|
1048
|
+
# the bigger monomial
|
|
1049
|
+
return (None, 1, 1)
|
|
1050
|
+
tmp = P[i]
|
|
1051
|
+
P[i] = Lbig[j]
|
|
1052
|
+
P[Lbig[j]] = tmp
|
|
1053
|
+
# now, P defines an 'up-shift' permutation, slt^P divides olt, and
|
|
1054
|
+
# Fbig contains the exponents for olt/slt^P.
|
|
1055
|
+
OUT = PARENT(PARENT._base(ltbig.lc() / ltsmall.lc()))
|
|
1056
|
+
for shift, Expo in Fbig.items():
|
|
1057
|
+
for g in gens:
|
|
1058
|
+
if Expo[g]:
|
|
1059
|
+
OUT *= PARENT.gen(g)[shift] ** Expo[g]
|
|
1060
|
+
from sage.combinat.permutation import Permutation
|
|
1061
|
+
return (rawcmp, Permutation(P[1:]), OUT)
|
|
1062
|
+
|
|
1063
|
+
def coefficient(self, monomial):
|
|
1064
|
+
"""
|
|
1065
|
+
Return the coefficient of a monomial in this polynomial.
|
|
1066
|
+
|
|
1067
|
+
INPUT:
|
|
1068
|
+
|
|
1069
|
+
- A monomial (element of the parent of self) or
|
|
1070
|
+
- a dictionary that describes a monomial (the keys
|
|
1071
|
+
are variables of the parent of self, the values
|
|
1072
|
+
are the corresponding exponents)
|
|
1073
|
+
|
|
1074
|
+
EXAMPLES:
|
|
1075
|
+
|
|
1076
|
+
We can get the coefficient in front of monomials::
|
|
1077
|
+
|
|
1078
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1079
|
+
sage: a = 2*x[0]*x[1] + x[1] + x[2]
|
|
1080
|
+
sage: a.coefficient(x[0])
|
|
1081
|
+
2*x_1
|
|
1082
|
+
sage: a.coefficient(x[1])
|
|
1083
|
+
2*x_0 + 1
|
|
1084
|
+
sage: a.coefficient(x[2])
|
|
1085
|
+
1
|
|
1086
|
+
sage: a.coefficient(x[0]*x[1])
|
|
1087
|
+
2
|
|
1088
|
+
|
|
1089
|
+
We can also pass in a dictionary::
|
|
1090
|
+
|
|
1091
|
+
sage: a.coefficient({x[0]:1, x[1]:1})
|
|
1092
|
+
2
|
|
1093
|
+
"""
|
|
1094
|
+
P = self.parent()
|
|
1095
|
+
if self._p == 0:
|
|
1096
|
+
return P.zero()
|
|
1097
|
+
if isinstance(monomial, self.__class__):
|
|
1098
|
+
if not P.has_coerce_map_from(monomial.parent()):
|
|
1099
|
+
return P.zero()
|
|
1100
|
+
if hasattr(self._p, 'variables'):
|
|
1101
|
+
VarList = [str(X) for X in self._p.variables()]
|
|
1102
|
+
else:
|
|
1103
|
+
VarList = []
|
|
1104
|
+
if hasattr(monomial._p, 'variables'):
|
|
1105
|
+
VarList.extend([str(X) for X in monomial._p.variables()])
|
|
1106
|
+
VarList = list(set(VarList))
|
|
1107
|
+
VarList.sort(key=P.varname_key, reverse=True)
|
|
1108
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1109
|
+
if len(VarList) == 1:
|
|
1110
|
+
# 'xx' is guaranteed to be no variable
|
|
1111
|
+
# name of monomial, since coercions
|
|
1112
|
+
# were tested before
|
|
1113
|
+
R = PolynomialRing(self._p.base_ring(), VarList + ['xx'], order=P._order)
|
|
1114
|
+
S = PolynomialRing(self._p.base_ring(), VarList, order=P._order)
|
|
1115
|
+
res = S(R(self._p).coefficient(R(monomial._p)))
|
|
1116
|
+
return InfinitePolynomial(P, res)
|
|
1117
|
+
|
|
1118
|
+
R = PolynomialRing(self._p.base_ring(), VarList, order=P._order)
|
|
1119
|
+
res = R(self._p).coefficient(R(monomial._p))
|
|
1120
|
+
return InfinitePolynomial(P, res)
|
|
1121
|
+
|
|
1122
|
+
if isinstance(monomial, dict):
|
|
1123
|
+
if monomial:
|
|
1124
|
+
I = iter(monomial)
|
|
1125
|
+
K = next(I)
|
|
1126
|
+
del monomial[K]
|
|
1127
|
+
return self.coefficient(K).coefficient(monomial)
|
|
1128
|
+
return self
|
|
1129
|
+
raise TypeError("Objects of type %s have no coefficients in InfinitePolynomials" % (type(monomial)))
|
|
1130
|
+
|
|
1131
|
+
# Essentials for Buchberger
|
|
1132
|
+
def reduce(self, I, tailreduce=False, report=None):
|
|
1133
|
+
r"""
|
|
1134
|
+
Symmetrical reduction of ``self`` with respect to a symmetric ideal (or list of Infinite Polynomials).
|
|
1135
|
+
|
|
1136
|
+
INPUT:
|
|
1137
|
+
|
|
1138
|
+
- ``I`` -- a :class:`~sage.rings.polynomial.symmetric_ideal.SymmetricIdeal` or a list
|
|
1139
|
+
of Infinite Polynomials
|
|
1140
|
+
- ``tailreduce`` -- boolean (default: ``False``); *tail reduction* is performed if this
|
|
1141
|
+
parameter is ``True``.
|
|
1142
|
+
- ``report`` -- object (default: ``None``); if not ``None``, some information on the
|
|
1143
|
+
progress of computation is printed, since reduction of huge polynomials may take
|
|
1144
|
+
a long time
|
|
1145
|
+
|
|
1146
|
+
OUTPUT: symmetrical reduction of ``self`` with respect to ``I``, possibly with tail reduction
|
|
1147
|
+
|
|
1148
|
+
THEORY:
|
|
1149
|
+
|
|
1150
|
+
Reducing an element `p` of an Infinite Polynomial Ring `X` by
|
|
1151
|
+
some other element `q` means the following:
|
|
1152
|
+
|
|
1153
|
+
1. Let `M` and `N` be the leading terms of `p` and `q`.
|
|
1154
|
+
2. Test whether there is a permutation `P` that does not does not diminish the variable
|
|
1155
|
+
indices occurring in `N` and preserves their order, so that there is some term `T\in X`
|
|
1156
|
+
with `TN^P = M`. If there is no such permutation, return `p`
|
|
1157
|
+
3. Replace `p` by `p-T q^P` and continue with step 1.
|
|
1158
|
+
|
|
1159
|
+
EXAMPLES::
|
|
1160
|
+
|
|
1161
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
1162
|
+
sage: p = y[1]^2*y[3] + y[2]*x[3]^3
|
|
1163
|
+
sage: p.reduce([y[2]*x[1]^2])
|
|
1164
|
+
x_3^3*y_2 + y_3*y_1^2
|
|
1165
|
+
|
|
1166
|
+
The preceding is correct: If a permutation turns
|
|
1167
|
+
``y[2]*x[1]^2`` into a factor of the leading monomial
|
|
1168
|
+
``y[2]*x[3]^3`` of ``p``, then it interchanges the variable
|
|
1169
|
+
indices 1 and 2; this is not allowed in a symmetric
|
|
1170
|
+
reduction. However, reduction by ``y[1]*x[2]^2`` works, since
|
|
1171
|
+
one can change variable index 1 into 2 and 2 into 3::
|
|
1172
|
+
|
|
1173
|
+
sage: p.reduce([y[1]*x[2]^2]) # needs sage.libs.singular
|
|
1174
|
+
y_3*y_1^2
|
|
1175
|
+
|
|
1176
|
+
The next example shows that tail reduction is not done, unless
|
|
1177
|
+
it is explicitly advised. The input can also be a Symmetric
|
|
1178
|
+
Ideal::
|
|
1179
|
+
|
|
1180
|
+
sage: I = (y[3])*X
|
|
1181
|
+
sage: p.reduce(I)
|
|
1182
|
+
x_3^3*y_2 + y_3*y_1^2
|
|
1183
|
+
sage: p.reduce(I, tailreduce=True) # needs sage.libs.singular
|
|
1184
|
+
x_3^3*y_2
|
|
1185
|
+
|
|
1186
|
+
Last, we demonstrate the ``report`` option::
|
|
1187
|
+
|
|
1188
|
+
sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4]
|
|
1189
|
+
sage: p.reduce(I, tailreduce=True, report=True) # needs sage.libs.singular
|
|
1190
|
+
:T[2]:>
|
|
1191
|
+
>
|
|
1192
|
+
x_1^2 + y_2^2
|
|
1193
|
+
|
|
1194
|
+
The output ':' means that there was one reduction of the
|
|
1195
|
+
leading monomial. 'T[2]' means that a tail reduction was
|
|
1196
|
+
performed on a polynomial with two terms. At '>', one round of
|
|
1197
|
+
the reduction process is finished (there could only be several
|
|
1198
|
+
non-trivial rounds if `I` was generated by more than one
|
|
1199
|
+
polynomial).
|
|
1200
|
+
"""
|
|
1201
|
+
from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
|
|
1202
|
+
if hasattr(I, 'gens'):
|
|
1203
|
+
I = I.gens()
|
|
1204
|
+
if (not I):
|
|
1205
|
+
return self
|
|
1206
|
+
I = list(I)
|
|
1207
|
+
S = SymmetricReductionStrategy(self.parent(), I, tailreduce)
|
|
1208
|
+
return S.reduce(self, report=report)
|
|
1209
|
+
|
|
1210
|
+
# Further methods
|
|
1211
|
+
def stretch(self, k):
|
|
1212
|
+
r"""
|
|
1213
|
+
Stretch ``self`` by a given factor.
|
|
1214
|
+
|
|
1215
|
+
INPUT:
|
|
1216
|
+
|
|
1217
|
+
- ``k`` -- integer
|
|
1218
|
+
|
|
1219
|
+
OUTPUT: replace `v_n` with `v_{n\cdot k}` for all generators `v_\ast`
|
|
1220
|
+
occurring in ``self``
|
|
1221
|
+
|
|
1222
|
+
EXAMPLES::
|
|
1223
|
+
|
|
1224
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1225
|
+
sage: a = x[0] + x[1] + x[2]
|
|
1226
|
+
sage: a.stretch(2)
|
|
1227
|
+
x_4 + x_2 + x_0
|
|
1228
|
+
|
|
1229
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
1230
|
+
sage: a = x[0] + x[1] + y[0]*y[1]; a
|
|
1231
|
+
x_1 + x_0 + y_1*y_0
|
|
1232
|
+
sage: a.stretch(2)
|
|
1233
|
+
x_2 + x_0 + y_2*y_0
|
|
1234
|
+
|
|
1235
|
+
TESTS:
|
|
1236
|
+
|
|
1237
|
+
The following would hardly work in a dense implementation,
|
|
1238
|
+
because an underlying polynomial ring with 6001 variables
|
|
1239
|
+
would be created. This is avoided in the sparse
|
|
1240
|
+
implementation::
|
|
1241
|
+
|
|
1242
|
+
sage: X.<x> = InfinitePolynomialRing(QQ, implementation='sparse')
|
|
1243
|
+
sage: a = x[2] + x[3]
|
|
1244
|
+
sage: a.stretch(2000)
|
|
1245
|
+
x_6000 + x_4000
|
|
1246
|
+
"""
|
|
1247
|
+
def P(n):
|
|
1248
|
+
return k*n
|
|
1249
|
+
return self ** P
|
|
1250
|
+
|
|
1251
|
+
def __iter__(self):
|
|
1252
|
+
"""
|
|
1253
|
+
Return an iterator over all pairs ``(coefficient, monomial)``
|
|
1254
|
+
of this polynomial.
|
|
1255
|
+
|
|
1256
|
+
EXAMPLES::
|
|
1257
|
+
|
|
1258
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
1259
|
+
sage: a = x[0] + 2*x[1] + y[0]*y[1]
|
|
1260
|
+
sage: list(a)
|
|
1261
|
+
[(2, x_1), (1, x_0), (1, y_1*y_0)]
|
|
1262
|
+
"""
|
|
1263
|
+
return iter((coefficient,
|
|
1264
|
+
self.__class__(self.parent(), monomial))
|
|
1265
|
+
for coefficient, monomial in self._p)
|
|
1266
|
+
|
|
1267
|
+
def gcd(self, x):
|
|
1268
|
+
"""
|
|
1269
|
+
Compute the greatest common divisor.
|
|
1270
|
+
|
|
1271
|
+
EXAMPLES::
|
|
1272
|
+
|
|
1273
|
+
sage: R.<x> = InfinitePolynomialRing(QQ)
|
|
1274
|
+
sage: p1 = x[0] + x[1]^2
|
|
1275
|
+
sage: gcd(p1, p1 + 3)
|
|
1276
|
+
1
|
|
1277
|
+
sage: gcd(p1, p1) == p1
|
|
1278
|
+
True
|
|
1279
|
+
"""
|
|
1280
|
+
P = self.parent()
|
|
1281
|
+
self._p = P._P(self._p)
|
|
1282
|
+
x._p = P._P(x._p)
|
|
1283
|
+
g = self._p.gcd(x._p)
|
|
1284
|
+
return self.__class__.__base__(P, g)
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
class InfinitePolynomial_sparse(InfinitePolynomial):
|
|
1288
|
+
"""
|
|
1289
|
+
Element of a sparse Polynomial Ring with a Countably Infinite Number of Variables.
|
|
1290
|
+
|
|
1291
|
+
INPUT:
|
|
1292
|
+
|
|
1293
|
+
- ``A`` -- an Infinite Polynomial Ring in sparse implementation
|
|
1294
|
+
- ``p`` -- a *classical* polynomial that can be interpreted in ``A``
|
|
1295
|
+
|
|
1296
|
+
Of course, one should not directly invoke this class, but rather
|
|
1297
|
+
construct elements of ``A`` in the usual way.
|
|
1298
|
+
|
|
1299
|
+
EXAMPLES::
|
|
1300
|
+
|
|
1301
|
+
sage: A.<a> = QQ[]
|
|
1302
|
+
sage: B.<b,c> = InfinitePolynomialRing(A,implementation='sparse')
|
|
1303
|
+
sage: p = a*b[100] + 1/2*c[4]
|
|
1304
|
+
sage: p
|
|
1305
|
+
a*b_100 + 1/2*c_4
|
|
1306
|
+
sage: p.parent()
|
|
1307
|
+
Infinite polynomial ring in b, c
|
|
1308
|
+
over Univariate Polynomial Ring in a over Rational Field
|
|
1309
|
+
sage: p.polynomial().parent()
|
|
1310
|
+
Multivariate Polynomial Ring in b_100, b_0, c_4, c_0
|
|
1311
|
+
over Univariate Polynomial Ring in a over Rational Field
|
|
1312
|
+
"""
|
|
1313
|
+
|
|
1314
|
+
def __call__(self, *args, **kwargs):
|
|
1315
|
+
"""
|
|
1316
|
+
EXAMPLES::
|
|
1317
|
+
|
|
1318
|
+
sage: X.<x> = InfinitePolynomialRing(QQ,implementation='sparse')
|
|
1319
|
+
sage: a = x[0] + x[1]
|
|
1320
|
+
sage: a(x_0=2,x_1=x[1])
|
|
1321
|
+
x_1 + 2
|
|
1322
|
+
sage: _.parent()
|
|
1323
|
+
Infinite polynomial ring in x over Rational Field
|
|
1324
|
+
sage: a(x_1=3)
|
|
1325
|
+
x_0 + 3
|
|
1326
|
+
sage: _.parent()
|
|
1327
|
+
Infinite polynomial ring in x over Rational Field
|
|
1328
|
+
sage: a(x_1=x[100])
|
|
1329
|
+
x_100 + x_0
|
|
1330
|
+
|
|
1331
|
+
sage: M = matrix([[1,1], [2,0]]) # needs sage.modules
|
|
1332
|
+
sage: a(x_1=M) # needs sage.modules
|
|
1333
|
+
[x_0 + 1 1]
|
|
1334
|
+
[ 2 x_0]
|
|
1335
|
+
"""
|
|
1336
|
+
# Replace any InfinitePolynomials by their underlying polynomials
|
|
1337
|
+
if hasattr(self._p, 'variables'):
|
|
1338
|
+
V = [str(x) for x in self._p.variables()]
|
|
1339
|
+
else:
|
|
1340
|
+
V = []
|
|
1341
|
+
for kw in kwargs:
|
|
1342
|
+
value = kwargs[kw]
|
|
1343
|
+
if isinstance(value, InfinitePolynomial):
|
|
1344
|
+
kwargs[kw] = value._p
|
|
1345
|
+
V.append(kw)
|
|
1346
|
+
if hasattr(value._p, 'variables'):
|
|
1347
|
+
V.extend([str(x) for x in value._p.variables()])
|
|
1348
|
+
args = list(args)
|
|
1349
|
+
for i, arg in enumerate(args):
|
|
1350
|
+
if isinstance(arg, InfinitePolynomial):
|
|
1351
|
+
args[i] = arg._p
|
|
1352
|
+
if hasattr(arg._p, 'variables'):
|
|
1353
|
+
V.extend([str(x) for x in arg._p.variables()])
|
|
1354
|
+
V = list(set(V))
|
|
1355
|
+
V.sort(key=self.parent().varname_key, reverse=True)
|
|
1356
|
+
if V:
|
|
1357
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1358
|
+
R = PolynomialRing(self._p.base_ring(), V, order=self.parent()._order)
|
|
1359
|
+
else:
|
|
1360
|
+
return self
|
|
1361
|
+
res = R(self._p)(*args, **kwargs)
|
|
1362
|
+
try:
|
|
1363
|
+
from sage.misc.sage_eval import sage_eval
|
|
1364
|
+
return sage_eval(repr(res), self.parent().gens_dict())
|
|
1365
|
+
except Exception:
|
|
1366
|
+
return res
|
|
1367
|
+
|
|
1368
|
+
# Basic arithmetics
|
|
1369
|
+
def _add_(self, x):
|
|
1370
|
+
"""
|
|
1371
|
+
EXAMPLES::
|
|
1372
|
+
|
|
1373
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1374
|
+
sage: x[1] + x[2] # indirect doctest
|
|
1375
|
+
x_2 + x_1
|
|
1376
|
+
|
|
1377
|
+
Check adding from a different parent::
|
|
1378
|
+
|
|
1379
|
+
sage: Y.<x_0> = PolynomialRing(QQ)
|
|
1380
|
+
sage: x[0] - x_0
|
|
1381
|
+
0
|
|
1382
|
+
"""
|
|
1383
|
+
# One may need a new parent for self._p and x._p
|
|
1384
|
+
try:
|
|
1385
|
+
return InfinitePolynomial_sparse(self.parent(), self._p + x._p)
|
|
1386
|
+
except Exception:
|
|
1387
|
+
pass
|
|
1388
|
+
# We can now assume that self._p and x._p actually are polynomials,
|
|
1389
|
+
# hence, their parent is not simply the underlying ring.
|
|
1390
|
+
VarList = list(set(self._p.parent().variable_names()).union(set(x._p.parent().variable_names())))
|
|
1391
|
+
VarList.sort(key=self.parent().varname_key, reverse=True)
|
|
1392
|
+
if VarList:
|
|
1393
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1394
|
+
R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)
|
|
1395
|
+
else:
|
|
1396
|
+
R = self._p.base_ring()
|
|
1397
|
+
return InfinitePolynomial_sparse(self.parent(), R(self._p) + R(x._p))
|
|
1398
|
+
|
|
1399
|
+
def _mul_(self, x):
|
|
1400
|
+
"""
|
|
1401
|
+
EXAMPLES::
|
|
1402
|
+
|
|
1403
|
+
sage: X.<x> = InfinitePolynomialRing(ZZ)
|
|
1404
|
+
sage: x[2]*x[1] # indirect doctest
|
|
1405
|
+
x_2*x_1
|
|
1406
|
+
"""
|
|
1407
|
+
try:
|
|
1408
|
+
return InfinitePolynomial_sparse(self.parent(), self._p * x._p)
|
|
1409
|
+
except Exception:
|
|
1410
|
+
pass
|
|
1411
|
+
# We can now assume that self._p and x._p actually are polynomials,
|
|
1412
|
+
# hence, their parent is not just the underlying ring.
|
|
1413
|
+
VarList = list(set(self._p.parent().variable_names()).union(set(x._p.parent().variable_names())))
|
|
1414
|
+
VarList.sort(key=self.parent().varname_key, reverse=True)
|
|
1415
|
+
if VarList:
|
|
1416
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1417
|
+
R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)
|
|
1418
|
+
else:
|
|
1419
|
+
R = self._p.base_ring()
|
|
1420
|
+
return InfinitePolynomial_sparse(self.parent(), R(self._p) * R(x._p))
|
|
1421
|
+
|
|
1422
|
+
def _sub_(self, x):
|
|
1423
|
+
"""
|
|
1424
|
+
EXAMPLES::
|
|
1425
|
+
|
|
1426
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1427
|
+
sage: x[2] - x[1] # indirect doctest
|
|
1428
|
+
x_2 - x_1
|
|
1429
|
+
"""
|
|
1430
|
+
try:
|
|
1431
|
+
return InfinitePolynomial_sparse(self.parent(), self._p - x._p)
|
|
1432
|
+
except Exception:
|
|
1433
|
+
pass
|
|
1434
|
+
# We can now assume that self._p and x._p actually are polynomials,
|
|
1435
|
+
# hence, their parent is not just the underlying ring.
|
|
1436
|
+
VarList = list(set(self._p.parent().variable_names()).union(x._p.parent().variable_names()))
|
|
1437
|
+
VarList.sort(key=self.parent().varname_key, reverse=True)
|
|
1438
|
+
if VarList:
|
|
1439
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1440
|
+
R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)
|
|
1441
|
+
else:
|
|
1442
|
+
R = self._p.base_ring()
|
|
1443
|
+
return InfinitePolynomial_sparse(self.parent(), R(self._p) - R(x._p))
|
|
1444
|
+
|
|
1445
|
+
def __pow__(self, n):
|
|
1446
|
+
"""
|
|
1447
|
+
Exponentiation by an integer, or action by a callable object.
|
|
1448
|
+
|
|
1449
|
+
NOTE:
|
|
1450
|
+
|
|
1451
|
+
The callable object must accept nonnegative integers as input
|
|
1452
|
+
and return nonnegative integers. Typical use case is a
|
|
1453
|
+
permutation, that will result in the corresponding permutation
|
|
1454
|
+
of variables.
|
|
1455
|
+
|
|
1456
|
+
EXAMPLES::
|
|
1457
|
+
|
|
1458
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse')
|
|
1459
|
+
sage: p = x[10]*y[2] + 2*x[1]*y[3]
|
|
1460
|
+
sage: P = Permutation(((1,2),(3,4,5)))
|
|
1461
|
+
sage: p^P # indirect doctest
|
|
1462
|
+
x_10*y_1 + 2*x_2*y_4
|
|
1463
|
+
"""
|
|
1464
|
+
P = self.parent()
|
|
1465
|
+
if callable(n):
|
|
1466
|
+
if (self._p.parent() == self._p.base_ring()):
|
|
1467
|
+
return self
|
|
1468
|
+
if not (hasattr(self._p, 'variables') and self._p.variables()):
|
|
1469
|
+
return self
|
|
1470
|
+
if hasattr(n, 'to_cycles') and hasattr(n, '__len__'): # duck typing Permutation
|
|
1471
|
+
# auxiliary function, necessary since n(m) raises an error if m>len(n)
|
|
1472
|
+
l = len(n)
|
|
1473
|
+
|
|
1474
|
+
def p(m):
|
|
1475
|
+
return n(m) if 0 < m <= l else m
|
|
1476
|
+
else: # Permutation group element
|
|
1477
|
+
p = n
|
|
1478
|
+
|
|
1479
|
+
def q(s):
|
|
1480
|
+
return s[0] + '_' + str(p(ZZ(s[1])))
|
|
1481
|
+
|
|
1482
|
+
newVars = [q(X.split('_')) for X in self._p.parent().variable_names()]
|
|
1483
|
+
if not newVars:
|
|
1484
|
+
return self
|
|
1485
|
+
copyVars = copy.copy(newVars)
|
|
1486
|
+
newVars = list(set(list(self._p.parent().variable_names())+newVars))
|
|
1487
|
+
newVars.sort(key=self.parent().varname_key, reverse=True)
|
|
1488
|
+
if newVars == list(self._p.parent().variable_names()):
|
|
1489
|
+
newR = self._p.parent()
|
|
1490
|
+
else:
|
|
1491
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1492
|
+
newR = PolynomialRing(self._p.base_ring(), newVars, order=P._order)
|
|
1493
|
+
mapR = self._p.parent().hom(copyVars, newR)
|
|
1494
|
+
return InfinitePolynomial_sparse(self.parent(), mapR(self._p))
|
|
1495
|
+
return InfinitePolynomial_sparse(self.parent(), self._p**n)
|
|
1496
|
+
|
|
1497
|
+
# Basic tools for Buchberger algorithm:
|
|
1498
|
+
# order, leading term/monomial, symmetric cancellation order
|
|
1499
|
+
|
|
1500
|
+
def _richcmp_(self, x, op):
|
|
1501
|
+
r"""
|
|
1502
|
+
Comparison of Infinite Polynomials.
|
|
1503
|
+
|
|
1504
|
+
NOTE:
|
|
1505
|
+
|
|
1506
|
+
Let x and y be generators of the parent of ``self``. We only consider
|
|
1507
|
+
monomial orderings in which x[m] > y[n] iff x appears earlier in the
|
|
1508
|
+
list of generators than y, or x==y and m>n
|
|
1509
|
+
|
|
1510
|
+
Under this restriction, the monomial ordering can be 'lex' (default),
|
|
1511
|
+
'degrevlex' or 'deglex'.
|
|
1512
|
+
|
|
1513
|
+
EXAMPLES::
|
|
1514
|
+
|
|
1515
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse')
|
|
1516
|
+
sage: a = x[10]^3
|
|
1517
|
+
sage: b = x[1] + x[2]
|
|
1518
|
+
sage: c = x[1] + x[2]
|
|
1519
|
+
sage: d = y[1] + x[2]
|
|
1520
|
+
sage: a == a # indirect doctest
|
|
1521
|
+
True
|
|
1522
|
+
sage: b == c # indirect doctest
|
|
1523
|
+
True
|
|
1524
|
+
sage: a == b # indirect doctest
|
|
1525
|
+
False
|
|
1526
|
+
sage: c > d # indirect doctest
|
|
1527
|
+
True
|
|
1528
|
+
|
|
1529
|
+
TESTS:
|
|
1530
|
+
|
|
1531
|
+
A classical and an infinite sparse polynomial ring. Note that
|
|
1532
|
+
the Sage coercion system allows comparison only if a common
|
|
1533
|
+
parent for the two rings can be constructed. This is why we
|
|
1534
|
+
have to have the order 'degrevlex'::
|
|
1535
|
+
|
|
1536
|
+
sage: X.<x,y> = InfinitePolynomialRing(ZZ,order='degrevlex', implementation='sparse')
|
|
1537
|
+
sage: Y.<z,x_3,x_1> = QQ[]
|
|
1538
|
+
sage: x[3] == x_3 # indirect doctest
|
|
1539
|
+
True
|
|
1540
|
+
|
|
1541
|
+
Two infinite polynomial rings in different implementation and
|
|
1542
|
+
order::
|
|
1543
|
+
|
|
1544
|
+
sage: Y = InfinitePolynomialRing(QQ,['x','y'],order='deglex', implementation='dense')
|
|
1545
|
+
sage: x[2] == Y(x[2]) # indirect doctest
|
|
1546
|
+
True
|
|
1547
|
+
|
|
1548
|
+
An example in which a previous version had failed::
|
|
1549
|
+
|
|
1550
|
+
sage: X.<x,y> = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='sparse')
|
|
1551
|
+
sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0')
|
|
1552
|
+
sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0')
|
|
1553
|
+
sage: p < q
|
|
1554
|
+
False
|
|
1555
|
+
"""
|
|
1556
|
+
# We can assume that self.parent() is x.parent(),
|
|
1557
|
+
# but of course the underlying polynomial rings
|
|
1558
|
+
# may be widely different, and the sage coercion
|
|
1559
|
+
# system can't guess what order we want.
|
|
1560
|
+
from sage.structure.element import parent
|
|
1561
|
+
R1 = parent(self._p)
|
|
1562
|
+
R2 = parent(x._p)
|
|
1563
|
+
if (hasattr(R1, 'has_coerce_map_from') and R1.has_coerce_map_from(R2)) or (hasattr(R2, 'has_coerce_map_from') and R2.has_coerce_map_from(R1)):
|
|
1564
|
+
return richcmp(self._p, x._p, op)
|
|
1565
|
+
VarList = list(set(self._p.parent().variable_names()).union(x._p.parent().variable_names()))
|
|
1566
|
+
VarList.sort(key=self.parent().varname_key, reverse=True)
|
|
1567
|
+
if VarList:
|
|
1568
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1569
|
+
R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)
|
|
1570
|
+
else:
|
|
1571
|
+
R = self._p.base_ring()
|
|
1572
|
+
if (self._p.parent() is self._p.base_ring()) or not self._p.parent().gens():
|
|
1573
|
+
fself = self._p.base_ring()
|
|
1574
|
+
else:
|
|
1575
|
+
fself = self._p.parent().hom(self._p.parent().variable_names(), R)
|
|
1576
|
+
if (x._p.parent() is x._p.base_ring()) or not x._p.parent().gens():
|
|
1577
|
+
fx = x._p.base_ring()
|
|
1578
|
+
else:
|
|
1579
|
+
fx = x._p.parent().hom(x._p.parent().variable_names(), R)
|
|
1580
|
+
return richcmp(fself(self._p), fx(x._p), op)
|
|
1581
|
+
|
|
1582
|
+
|
|
1583
|
+
class InfinitePolynomial_dense(InfinitePolynomial):
|
|
1584
|
+
"""
|
|
1585
|
+
Element of a dense Polynomial Ring with a Countably Infinite Number of Variables.
|
|
1586
|
+
|
|
1587
|
+
INPUT:
|
|
1588
|
+
|
|
1589
|
+
- ``A`` -- an Infinite Polynomial Ring in dense implementation
|
|
1590
|
+
- ``p`` -- a *classical* polynomial that can be interpreted in ``A``
|
|
1591
|
+
|
|
1592
|
+
Of course, one should not directly invoke this class, but rather
|
|
1593
|
+
construct elements of ``A`` in the usual way.
|
|
1594
|
+
"""
|
|
1595
|
+
|
|
1596
|
+
def __call__(self, *args, **kwargs):
|
|
1597
|
+
"""
|
|
1598
|
+
EXAMPLES::
|
|
1599
|
+
|
|
1600
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1601
|
+
sage: a = x[0] + x[1]
|
|
1602
|
+
sage: a(x_0=2, x_1=x[1])
|
|
1603
|
+
x_1 + 2
|
|
1604
|
+
sage: _.parent()
|
|
1605
|
+
Infinite polynomial ring in x over Rational Field
|
|
1606
|
+
sage: a(x_1=3)
|
|
1607
|
+
x_0 + 3
|
|
1608
|
+
sage: _.parent()
|
|
1609
|
+
Infinite polynomial ring in x over Rational Field
|
|
1610
|
+
|
|
1611
|
+
sage: a(x_1=x[100])
|
|
1612
|
+
x_100 + x_0
|
|
1613
|
+
"""
|
|
1614
|
+
# Replace any InfinitePolynomials by their underlying polynomials
|
|
1615
|
+
for kw in kwargs:
|
|
1616
|
+
value = kwargs[kw]
|
|
1617
|
+
if isinstance(value, InfinitePolynomial):
|
|
1618
|
+
kwargs[kw] = value._p
|
|
1619
|
+
args = list(args)
|
|
1620
|
+
for i, arg in enumerate(args):
|
|
1621
|
+
if isinstance(arg, InfinitePolynomial):
|
|
1622
|
+
args[i] = arg._p
|
|
1623
|
+
self._p = self.parent().polynomial_ring()(self._p)
|
|
1624
|
+
res = self._p(*args, **kwargs)
|
|
1625
|
+
try:
|
|
1626
|
+
return self.parent()(res)
|
|
1627
|
+
except ValueError:
|
|
1628
|
+
return res
|
|
1629
|
+
|
|
1630
|
+
def _richcmp_(self, x, op):
|
|
1631
|
+
r"""
|
|
1632
|
+
TESTS:
|
|
1633
|
+
|
|
1634
|
+
A classical and an infinite polynomial ring::
|
|
1635
|
+
|
|
1636
|
+
sage: X.<x,y> = InfinitePolynomialRing(ZZ, order='degrevlex')
|
|
1637
|
+
sage: Y.<z,x_3,x_1> = QQ[]
|
|
1638
|
+
sage: x[3] == x_3
|
|
1639
|
+
True
|
|
1640
|
+
|
|
1641
|
+
Two infinite polynomial rings with different order and
|
|
1642
|
+
implementation::
|
|
1643
|
+
|
|
1644
|
+
sage: Y = InfinitePolynomialRing(QQ,['x','y'], order='deglex', implementation='sparse')
|
|
1645
|
+
sage: x[2] == Y(x[2])
|
|
1646
|
+
True
|
|
1647
|
+
|
|
1648
|
+
An example in which a previous version had failed::
|
|
1649
|
+
|
|
1650
|
+
sage: X.<x,y> = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='dense')
|
|
1651
|
+
sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0')
|
|
1652
|
+
sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0')
|
|
1653
|
+
sage: p < q
|
|
1654
|
+
False
|
|
1655
|
+
"""
|
|
1656
|
+
# We can assume that self and x belong to the same ring.
|
|
1657
|
+
# We can not assume yet that self._p and
|
|
1658
|
+
# x._p are already defined over self.parent()._P
|
|
1659
|
+
# It won't hurt to change self in place.
|
|
1660
|
+
# But, to be on the safe side...
|
|
1661
|
+
try:
|
|
1662
|
+
self._p = self.parent()._P(self._p)
|
|
1663
|
+
except Exception:
|
|
1664
|
+
pass
|
|
1665
|
+
try:
|
|
1666
|
+
x._p = x.parent()._P(x._p)
|
|
1667
|
+
except Exception:
|
|
1668
|
+
pass
|
|
1669
|
+
return richcmp(self._p, x._p, op)
|
|
1670
|
+
|
|
1671
|
+
# Basic arithmetics
|
|
1672
|
+
def _add_(self, x):
|
|
1673
|
+
"""
|
|
1674
|
+
EXAMPLES::
|
|
1675
|
+
|
|
1676
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1677
|
+
sage: x[1] + x[2] # indirect doctest
|
|
1678
|
+
x_2 + x_1
|
|
1679
|
+
"""
|
|
1680
|
+
P = self.parent()
|
|
1681
|
+
self._p = P._P(self._p)
|
|
1682
|
+
x._p = P._P(x._p)
|
|
1683
|
+
return InfinitePolynomial_dense(self.parent(), self._p + x._p)
|
|
1684
|
+
|
|
1685
|
+
def _mul_(self, x):
|
|
1686
|
+
"""
|
|
1687
|
+
EXAMPLES::
|
|
1688
|
+
|
|
1689
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1690
|
+
sage: x[2]*x[1] # indirect doctest
|
|
1691
|
+
x_2*x_1
|
|
1692
|
+
"""
|
|
1693
|
+
P = self.parent()
|
|
1694
|
+
self._p = P._P(self._p)
|
|
1695
|
+
x._p = P._P(x._p)
|
|
1696
|
+
return InfinitePolynomial_dense(self.parent(), self._p * x._p)
|
|
1697
|
+
|
|
1698
|
+
def _sub_(self, x):
|
|
1699
|
+
"""
|
|
1700
|
+
EXAMPLES::
|
|
1701
|
+
|
|
1702
|
+
sage: X.<x> = InfinitePolynomialRing(QQ)
|
|
1703
|
+
sage: x[2] - x[1] # indirect doctest
|
|
1704
|
+
x_2 - x_1
|
|
1705
|
+
"""
|
|
1706
|
+
P = self.parent()
|
|
1707
|
+
self._p = P._P(self._p)
|
|
1708
|
+
x._p = P._P(x._p)
|
|
1709
|
+
return InfinitePolynomial_dense(self.parent(), self._p - x._p)
|
|
1710
|
+
|
|
1711
|
+
def __pow__(self, n):
|
|
1712
|
+
"""
|
|
1713
|
+
Exponentiation by an integer, or action by a callable object.
|
|
1714
|
+
|
|
1715
|
+
NOTE:
|
|
1716
|
+
|
|
1717
|
+
The callable object must accept nonnegative integers as input
|
|
1718
|
+
and return nonnegative integers. Typical use case is a
|
|
1719
|
+
permutation, that will result in the corresponding permutation
|
|
1720
|
+
of variables.
|
|
1721
|
+
|
|
1722
|
+
EXAMPLES::
|
|
1723
|
+
|
|
1724
|
+
sage: X.<x,y> = InfinitePolynomialRing(QQ)
|
|
1725
|
+
sage: x[10]^3
|
|
1726
|
+
x_10^3
|
|
1727
|
+
sage: p = x[10]*y[2] + 2*x[1]*y[3]
|
|
1728
|
+
sage: P = Permutation(((1,2),(3,4,5)))
|
|
1729
|
+
sage: p^P
|
|
1730
|
+
x_10*y_1 + 2*x_2*y_4
|
|
1731
|
+
"""
|
|
1732
|
+
P = self.parent()
|
|
1733
|
+
if callable(n):
|
|
1734
|
+
if (self._p.parent() == self._p.base_ring()):
|
|
1735
|
+
return self
|
|
1736
|
+
if not (hasattr(self._p, 'variables') and self._p.variables()):
|
|
1737
|
+
return self
|
|
1738
|
+
if hasattr(n, 'to_cycles') and hasattr(n, '__len__'): # duck typing Permutation
|
|
1739
|
+
# auxiliary function, necessary since n(m) raises an error if m>len(n)
|
|
1740
|
+
l = len(n)
|
|
1741
|
+
|
|
1742
|
+
def p(m):
|
|
1743
|
+
return n(m) if 0 < m <= l else m
|
|
1744
|
+
else: # Permutation group element
|
|
1745
|
+
p = n
|
|
1746
|
+
|
|
1747
|
+
# determine whether the maximal index must be raised
|
|
1748
|
+
oldMax = P._max
|
|
1749
|
+
newMax = max([p(X) for X in range(oldMax+1)]+[oldMax])
|
|
1750
|
+
if newMax > P._max:
|
|
1751
|
+
P.gen()[newMax]
|
|
1752
|
+
self._p = P._P(self._p)
|
|
1753
|
+
# next, determine the images of variable names
|
|
1754
|
+
PP = P._P
|
|
1755
|
+
PPgens = PP.gens()
|
|
1756
|
+
|
|
1757
|
+
newVars = []
|
|
1758
|
+
sh = PP.ngens() // P.ngens() - 1
|
|
1759
|
+
blocklength = sh
|
|
1760
|
+
nM = sh + 1
|
|
1761
|
+
for i in range(P.ngens()):
|
|
1762
|
+
newVars.extend([PPgens[sh-p(j)] for j in range(blocklength, -1, -1)])
|
|
1763
|
+
sh += nM
|
|
1764
|
+
mapR = PP.hom(newVars, PP)
|
|
1765
|
+
return InfinitePolynomial_dense(self.parent(), mapR(self._p))
|
|
1766
|
+
|
|
1767
|
+
# else, n is supposed to be an integer
|
|
1768
|
+
return InfinitePolynomial_dense(self.parent(), self._p**n)
|