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,1855 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Base class for multivariate polynomial rings
|
|
4
|
+
"""
|
|
5
|
+
import itertools
|
|
6
|
+
from collections.abc import Iterable
|
|
7
|
+
|
|
8
|
+
import sage.misc.latex
|
|
9
|
+
from sage.misc.cachefunc import cached_method
|
|
10
|
+
from sage.misc.misc_c import prod
|
|
11
|
+
|
|
12
|
+
from sage.structure.element cimport parent
|
|
13
|
+
from sage.structure.parent cimport Parent
|
|
14
|
+
from sage.structure.richcmp cimport rich_to_bool, richcmp
|
|
15
|
+
from cpython.object cimport Py_NE
|
|
16
|
+
|
|
17
|
+
import sage.categories as categories
|
|
18
|
+
from sage.categories.morphism import IdentityMorphism
|
|
19
|
+
from sage.categories.commutative_rings import CommutativeRings
|
|
20
|
+
_CommutativeRings = CommutativeRings()
|
|
21
|
+
|
|
22
|
+
from sage.arith.misc import binomial
|
|
23
|
+
|
|
24
|
+
from sage.rings.integer_ring import ZZ
|
|
25
|
+
|
|
26
|
+
from sage.rings.polynomial import polynomial_ring
|
|
27
|
+
from sage.rings.polynomial.term_order import TermOrder
|
|
28
|
+
from sage.rings.polynomial.polynomial_ring_constructor import (PolynomialRing,
|
|
29
|
+
polynomial_default_category)
|
|
30
|
+
from sage.rings.polynomial.polydict cimport ETuple
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def is_MPolynomialRing(x):
|
|
34
|
+
from sage.misc.superseded import deprecation_cython
|
|
35
|
+
deprecation_cython(38266,
|
|
36
|
+
"The function is_MPolynomialRing is deprecated; "
|
|
37
|
+
"use 'isinstance(..., MPolynomialRing_base)' instead.")
|
|
38
|
+
return isinstance(x, MPolynomialRing_base)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
cdef class MPolynomialRing_base(CommutativeRing):
|
|
42
|
+
def __init__(self, base_ring, n, names, order):
|
|
43
|
+
"""
|
|
44
|
+
Create a polynomial ring in several variables over a commutative ring.
|
|
45
|
+
|
|
46
|
+
EXAMPLES::
|
|
47
|
+
|
|
48
|
+
sage: R.<x,y> = ZZ['x,y']; R
|
|
49
|
+
Multivariate Polynomial Ring in x, y over Integer Ring
|
|
50
|
+
sage: cat = Rings().Commutative()
|
|
51
|
+
sage: class CR(Parent):
|
|
52
|
+
....: def __init__(self):
|
|
53
|
+
....: Parent.__init__(self, self, category=cat)
|
|
54
|
+
....: def __call__(self, x):
|
|
55
|
+
....: return None
|
|
56
|
+
sage: cr = CR()
|
|
57
|
+
sage: cr.is_commutative()
|
|
58
|
+
True
|
|
59
|
+
sage: cr['x,y']
|
|
60
|
+
Multivariate Polynomial Ring in x, y over
|
|
61
|
+
<__main__.CR_with_category object at ...>
|
|
62
|
+
|
|
63
|
+
TESTS:
|
|
64
|
+
|
|
65
|
+
Check that containment works correctly (:issue:`10355`)::
|
|
66
|
+
|
|
67
|
+
sage: A1.<a> = PolynomialRing(QQ)
|
|
68
|
+
sage: A2.<a,b> = PolynomialRing(QQ)
|
|
69
|
+
sage: 3 in A2
|
|
70
|
+
True
|
|
71
|
+
sage: A1(a) in A2
|
|
72
|
+
True
|
|
73
|
+
|
|
74
|
+
Check that :issue:`26958` is fixed::
|
|
75
|
+
|
|
76
|
+
sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular # needs sage.libs.singular
|
|
77
|
+
sage: class Foo(MPolynomialRing_libsingular): # needs sage.libs.singular
|
|
78
|
+
....: pass
|
|
79
|
+
sage: Foo(QQ, 2, ['x','y'], 'degrevlex') # needs sage.libs.singular
|
|
80
|
+
Multivariate Polynomial Ring in x, y over Rational Field
|
|
81
|
+
|
|
82
|
+
Check that :meth:`basis` works correctly::
|
|
83
|
+
|
|
84
|
+
sage: R = PolynomialRing(QQ, [])
|
|
85
|
+
sage: R.basis()
|
|
86
|
+
Lazy family (...monomial...(i))_{i in Integer vectors of length 0}
|
|
87
|
+
sage: [*R.basis()]
|
|
88
|
+
[1]
|
|
89
|
+
sage: R.<x,y> = QQ[]
|
|
90
|
+
sage: R.basis()
|
|
91
|
+
Lazy family (...monomial...(i))_{i in Integer vectors of length 2}
|
|
92
|
+
sage: import itertools
|
|
93
|
+
sage: list(itertools.islice(R.basis(), 16))
|
|
94
|
+
[1, x, y, x^2, x*y, y^2, x^3, x^2*y, x*y^2, y^3, x^4, x^3*y, x^2*y^2, x*y^3, y^4, x^5]
|
|
95
|
+
"""
|
|
96
|
+
if base_ring not in _CommutativeRings:
|
|
97
|
+
raise TypeError("The base ring %s is not a commutative ring" % base_ring)
|
|
98
|
+
|
|
99
|
+
n = int(n)
|
|
100
|
+
if n < 0:
|
|
101
|
+
raise ValueError("Multivariate Polynomial Rings must "
|
|
102
|
+
"have more than 0 variables.")
|
|
103
|
+
order = TermOrder(order, n)
|
|
104
|
+
self._ngens = n
|
|
105
|
+
self._term_order = order
|
|
106
|
+
self._has_singular = False # cannot convert to Singular by default
|
|
107
|
+
self._magma_cache = {}
|
|
108
|
+
if base_ring.is_zero():
|
|
109
|
+
category = categories.rings.Rings().Finite()
|
|
110
|
+
else:
|
|
111
|
+
category = polynomial_default_category(base_ring.category(), n)
|
|
112
|
+
# Ring.__init__ assigns the names.
|
|
113
|
+
Ring.__init__(self, base_ring, names, category=category)
|
|
114
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
115
|
+
self._indices = IntegerVectors(length=self._ngens)
|
|
116
|
+
|
|
117
|
+
def is_integral_domain(self, proof=True):
|
|
118
|
+
"""
|
|
119
|
+
EXAMPLES::
|
|
120
|
+
|
|
121
|
+
sage: ZZ['x,y'].is_integral_domain()
|
|
122
|
+
True
|
|
123
|
+
sage: Integers(8)['x,y'].is_integral_domain()
|
|
124
|
+
False
|
|
125
|
+
"""
|
|
126
|
+
return self.base_ring().is_integral_domain(proof)
|
|
127
|
+
|
|
128
|
+
def is_noetherian(self):
|
|
129
|
+
"""
|
|
130
|
+
EXAMPLES::
|
|
131
|
+
|
|
132
|
+
sage: ZZ['x,y'].is_noetherian()
|
|
133
|
+
True
|
|
134
|
+
sage: Integers(8)['x,y'].is_noetherian()
|
|
135
|
+
True
|
|
136
|
+
"""
|
|
137
|
+
return self.base_ring().is_noetherian()
|
|
138
|
+
|
|
139
|
+
@cached_method
|
|
140
|
+
def flattening_morphism(self):
|
|
141
|
+
r"""
|
|
142
|
+
Return the flattening morphism of this polynomial ring.
|
|
143
|
+
|
|
144
|
+
EXAMPLES::
|
|
145
|
+
|
|
146
|
+
sage: QQ['a','b']['x','y'].flattening_morphism()
|
|
147
|
+
Flattening morphism:
|
|
148
|
+
From: Multivariate Polynomial Ring in x, y
|
|
149
|
+
over Multivariate Polynomial Ring in a, b over Rational Field
|
|
150
|
+
To: Multivariate Polynomial Ring in a, b, x, y over Rational Field
|
|
151
|
+
|
|
152
|
+
sage: QQ['x,y'].flattening_morphism()
|
|
153
|
+
Identity endomorphism of
|
|
154
|
+
Multivariate Polynomial Ring in x, y over Rational Field
|
|
155
|
+
"""
|
|
156
|
+
base = self.base_ring()
|
|
157
|
+
if isinstance(base, (MPolynomialRing_base, polynomial_ring.PolynomialRing_generic)):
|
|
158
|
+
from sage.rings.polynomial.flatten import FlatteningMorphism
|
|
159
|
+
return FlatteningMorphism(self)
|
|
160
|
+
else:
|
|
161
|
+
return IdentityMorphism(self)
|
|
162
|
+
|
|
163
|
+
def construction(self):
|
|
164
|
+
"""
|
|
165
|
+
Return a functor ``F`` and base ring ``R`` such that ``F(R) == self``.
|
|
166
|
+
|
|
167
|
+
EXAMPLES::
|
|
168
|
+
|
|
169
|
+
sage: S = ZZ['x,y']
|
|
170
|
+
sage: F, R = S.construction(); R
|
|
171
|
+
Integer Ring
|
|
172
|
+
sage: F
|
|
173
|
+
MPoly[x,y]
|
|
174
|
+
sage: F(R) == S
|
|
175
|
+
True
|
|
176
|
+
sage: F(R) == ZZ['x']['y']
|
|
177
|
+
False
|
|
178
|
+
"""
|
|
179
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
180
|
+
from sage.categories.pushout import MultiPolynomialFunctor
|
|
181
|
+
return MultiPolynomialFunctor(self.variable_names(), self.term_order()), self.base_ring()
|
|
182
|
+
|
|
183
|
+
def irrelevant_ideal(self):
|
|
184
|
+
"""
|
|
185
|
+
Return the irrelevant ideal of this multivariate polynomial ring.
|
|
186
|
+
|
|
187
|
+
This is the ideal generated by all of the indeterminate
|
|
188
|
+
generators of this ring.
|
|
189
|
+
|
|
190
|
+
EXAMPLES::
|
|
191
|
+
|
|
192
|
+
sage: R.<x,y,z> = QQ[]
|
|
193
|
+
sage: R.irrelevant_ideal()
|
|
194
|
+
Ideal (x, y, z) of Multivariate Polynomial Ring in x, y, z over
|
|
195
|
+
Rational Field
|
|
196
|
+
"""
|
|
197
|
+
return self.ideal(self.gens(), check=False)
|
|
198
|
+
|
|
199
|
+
def completion(self, names=None, prec=20, extras={}, **kwds):
|
|
200
|
+
r"""
|
|
201
|
+
Return the completion of ``self`` with respect to the ideal
|
|
202
|
+
generated by the variable(s) ``names``.
|
|
203
|
+
|
|
204
|
+
INPUT:
|
|
205
|
+
|
|
206
|
+
- ``names`` -- (optional) variable or list/tuple of variables
|
|
207
|
+
(given either as elements of the polynomial ring or as strings);
|
|
208
|
+
the default is all variables of ``self``
|
|
209
|
+
- ``prec`` -- default precision of resulting power series ring,
|
|
210
|
+
possibly infinite
|
|
211
|
+
- ``extras`` -- passed as keywords to :class:`PowerSeriesRing`
|
|
212
|
+
or :class:`LazyPowerSeriesRing`; can also be keyword arguments
|
|
213
|
+
|
|
214
|
+
EXAMPLES::
|
|
215
|
+
|
|
216
|
+
sage: P.<x,y,z,w> = PolynomialRing(ZZ)
|
|
217
|
+
sage: P.completion('w')
|
|
218
|
+
Power Series Ring in w over Multivariate Polynomial Ring in
|
|
219
|
+
x, y, z over Integer Ring
|
|
220
|
+
sage: P.completion((w,x,y))
|
|
221
|
+
Multivariate Power Series Ring in w, x, y over
|
|
222
|
+
Univariate Polynomial Ring in z over Integer Ring
|
|
223
|
+
sage: Q.<w,x,y,z> = P.completion(); Q
|
|
224
|
+
Multivariate Power Series Ring in w, x, y, z over Integer Ring
|
|
225
|
+
|
|
226
|
+
sage: H = PolynomialRing(PolynomialRing(ZZ,3,'z'),4,'f'); H
|
|
227
|
+
Multivariate Polynomial Ring in f0, f1, f2, f3 over
|
|
228
|
+
Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring
|
|
229
|
+
|
|
230
|
+
sage: H.completion(H.gens())
|
|
231
|
+
Multivariate Power Series Ring in f0, f1, f2, f3 over
|
|
232
|
+
Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring
|
|
233
|
+
|
|
234
|
+
sage: H.completion(H.gens()[2])
|
|
235
|
+
Power Series Ring in f2 over
|
|
236
|
+
Multivariate Polynomial Ring in f0, f1, f3 over
|
|
237
|
+
Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring
|
|
238
|
+
|
|
239
|
+
sage: P.<x,y,z,w> = PolynomialRing(ZZ)
|
|
240
|
+
sage: P.completion(prec=oo) # needs sage.combinat
|
|
241
|
+
Multivariate Lazy Taylor Series Ring in x, y, z, w over Integer Ring
|
|
242
|
+
sage: P.completion((w,x,y), prec=oo) # needs sage.combinat
|
|
243
|
+
Multivariate Lazy Taylor Series Ring in w, x, y over
|
|
244
|
+
Univariate Polynomial Ring in z over Integer Ring
|
|
245
|
+
|
|
246
|
+
TESTS::
|
|
247
|
+
|
|
248
|
+
sage: P.<x,y> = PolynomialRing(ZZ)
|
|
249
|
+
sage: P.completion([]) is P
|
|
250
|
+
True
|
|
251
|
+
sage: P.completion(SR.var('x')) # needs sage.symbolic
|
|
252
|
+
Traceback (most recent call last):
|
|
253
|
+
...
|
|
254
|
+
TypeError: x is not an element of Multivariate Polynomial Ring
|
|
255
|
+
in x, y over Integer Ring
|
|
256
|
+
sage: P.completion(x + y)
|
|
257
|
+
Traceback (most recent call last):
|
|
258
|
+
...
|
|
259
|
+
ValueError: x + y is not a variable of Multivariate Polynomial
|
|
260
|
+
Ring in x, y over Integer Ring
|
|
261
|
+
sage: P.completion('q')
|
|
262
|
+
Traceback (most recent call last):
|
|
263
|
+
...
|
|
264
|
+
ValueError: q is not a variable of Multivariate Polynomial Ring
|
|
265
|
+
in x, y over Integer Ring
|
|
266
|
+
"""
|
|
267
|
+
if names is None:
|
|
268
|
+
names = self.variable_names()
|
|
269
|
+
elif not isinstance(names, (list, tuple)):
|
|
270
|
+
names = [names] # Single variable
|
|
271
|
+
elif not names:
|
|
272
|
+
return self # 0 variables => completion is self
|
|
273
|
+
|
|
274
|
+
vars = []
|
|
275
|
+
for v in names:
|
|
276
|
+
# Convert variable names to str and check that they really
|
|
277
|
+
# are variables of self
|
|
278
|
+
if isinstance(v, str):
|
|
279
|
+
pass
|
|
280
|
+
elif parent(v) is self:
|
|
281
|
+
v = str(v)
|
|
282
|
+
else:
|
|
283
|
+
raise TypeError(f"{v!r} is not an element of {self}")
|
|
284
|
+
if v not in self.variable_names():
|
|
285
|
+
raise ValueError(f"{v} is not a variable of {self}")
|
|
286
|
+
vars.append(v)
|
|
287
|
+
|
|
288
|
+
new_base = self.remove_var(*vars)
|
|
289
|
+
if prec == float('inf'):
|
|
290
|
+
from sage.rings.lazy_series_ring import LazyPowerSeriesRing
|
|
291
|
+
return LazyPowerSeriesRing(new_base, names=vars, **extras, **kwds)
|
|
292
|
+
from sage.rings.power_series_ring import PowerSeriesRing
|
|
293
|
+
return PowerSeriesRing(new_base, names=vars, default_prec=prec, **extras, **kwds)
|
|
294
|
+
|
|
295
|
+
def remove_var(self, *var, order=None):
|
|
296
|
+
"""
|
|
297
|
+
Remove a variable or sequence of variables from ``self``.
|
|
298
|
+
|
|
299
|
+
If ``order`` is not specified, then the subring inherits the
|
|
300
|
+
term order of the original ring, if possible.
|
|
301
|
+
|
|
302
|
+
EXAMPLES::
|
|
303
|
+
|
|
304
|
+
sage: P.<x,y,z,w> = PolynomialRing(ZZ)
|
|
305
|
+
sage: P.remove_var(z)
|
|
306
|
+
Multivariate Polynomial Ring in x, y, w over Integer Ring
|
|
307
|
+
sage: P.remove_var(z, x)
|
|
308
|
+
Multivariate Polynomial Ring in y, w over Integer Ring
|
|
309
|
+
sage: P.remove_var(y, z, x)
|
|
310
|
+
Univariate Polynomial Ring in w over Integer Ring
|
|
311
|
+
|
|
312
|
+
Removing all variables results in the base ring::
|
|
313
|
+
|
|
314
|
+
sage: P.remove_var(y, z, x, w)
|
|
315
|
+
Integer Ring
|
|
316
|
+
|
|
317
|
+
If possible, the term order is kept::
|
|
318
|
+
|
|
319
|
+
sage: R.<x,y,z,w> = PolynomialRing(ZZ, order='deglex')
|
|
320
|
+
sage: R.remove_var(y).term_order()
|
|
321
|
+
Degree lexicographic term order
|
|
322
|
+
|
|
323
|
+
sage: R.<x,y,z,w> = PolynomialRing(ZZ, order='lex')
|
|
324
|
+
sage: R.remove_var(y).term_order()
|
|
325
|
+
Lexicographic term order
|
|
326
|
+
|
|
327
|
+
Be careful with block orders when removing variables::
|
|
328
|
+
|
|
329
|
+
sage: R.<x,y,z,u,v> = PolynomialRing(ZZ, order='deglex(2),lex(3)')
|
|
330
|
+
sage: R.remove_var(x, y, z)
|
|
331
|
+
Traceback (most recent call last):
|
|
332
|
+
...
|
|
333
|
+
ValueError: impossible to use the original term order (most
|
|
334
|
+
likely because it was a block order). Please specify the term
|
|
335
|
+
order for the subring
|
|
336
|
+
sage: R.remove_var(x,y,z, order='degrevlex')
|
|
337
|
+
Multivariate Polynomial Ring in u, v over Integer Ring
|
|
338
|
+
"""
|
|
339
|
+
vars = list(self.variable_names())
|
|
340
|
+
for v in var:
|
|
341
|
+
vars.remove(str(v))
|
|
342
|
+
if len(vars) == 0:
|
|
343
|
+
return self.base_ring()
|
|
344
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
345
|
+
if order is None:
|
|
346
|
+
try:
|
|
347
|
+
return PolynomialRing(self.base_ring(), vars,
|
|
348
|
+
order=self.term_order())
|
|
349
|
+
except ValueError:
|
|
350
|
+
raise ValueError("impossible to use the original term order (most likely because it was a block order). Please specify the term order for the subring")
|
|
351
|
+
else:
|
|
352
|
+
return PolynomialRing(self.base_ring(), vars, order=order)
|
|
353
|
+
|
|
354
|
+
def univariate_ring(self, x):
|
|
355
|
+
"""
|
|
356
|
+
Return a univariate polynomial ring whose base ring comprises all
|
|
357
|
+
but one variables of ``self``.
|
|
358
|
+
|
|
359
|
+
INPUT:
|
|
360
|
+
|
|
361
|
+
- ``x`` -- a variable of ``self``
|
|
362
|
+
|
|
363
|
+
EXAMPLES::
|
|
364
|
+
|
|
365
|
+
sage: P.<x,y,z> = QQ[]
|
|
366
|
+
sage: P.univariate_ring(y)
|
|
367
|
+
Univariate Polynomial Ring in y
|
|
368
|
+
over Multivariate Polynomial Ring in x, z over Rational Field
|
|
369
|
+
"""
|
|
370
|
+
return self.remove_var(x)[str(x)]
|
|
371
|
+
|
|
372
|
+
def interpolation(self, bound, *args):
|
|
373
|
+
"""
|
|
374
|
+
Create a polynomial with specified evaluations.
|
|
375
|
+
|
|
376
|
+
CALL FORMATS:
|
|
377
|
+
|
|
378
|
+
This function can be called in two ways:
|
|
379
|
+
|
|
380
|
+
1. ``interpolation(bound, points, values)``
|
|
381
|
+
|
|
382
|
+
2. ``interpolation(bound, function)``
|
|
383
|
+
|
|
384
|
+
INPUT:
|
|
385
|
+
|
|
386
|
+
- ``bound`` -- either an integer bounding the total degree or a
|
|
387
|
+
list/tuple of integers bounding the degree of the variables
|
|
388
|
+
|
|
389
|
+
- ``points`` -- list/tuple containing the evaluation points
|
|
390
|
+
|
|
391
|
+
- ``values`` -- list/tuple containing the desired values at ``points``
|
|
392
|
+
|
|
393
|
+
- ``function`` -- evaluable function in `n` variables, where `n` is the
|
|
394
|
+
number of variables of the polynomial ring
|
|
395
|
+
|
|
396
|
+
OUTPUT:
|
|
397
|
+
|
|
398
|
+
1. A polynomial respecting the bounds and having ``values`` as values
|
|
399
|
+
when evaluated at ``points``.
|
|
400
|
+
|
|
401
|
+
2. A polynomial respecting the bounds and having the same values as
|
|
402
|
+
``function`` at exactly so many points so that the polynomial is
|
|
403
|
+
unique.
|
|
404
|
+
|
|
405
|
+
EXAMPLES::
|
|
406
|
+
|
|
407
|
+
sage: def F(a, b, c):
|
|
408
|
+
....: return a^3*b + b + c^2 + 25
|
|
409
|
+
....:
|
|
410
|
+
sage: R.<x,y,z> = PolynomialRing(QQ)
|
|
411
|
+
sage: R.interpolation(4, F) # needs sage.modules
|
|
412
|
+
x^3*y + z^2 + y + 25
|
|
413
|
+
|
|
414
|
+
sage: def F(a, b, c):
|
|
415
|
+
....: return a^3*b + b + c^2 + 25
|
|
416
|
+
....:
|
|
417
|
+
sage: R.<x,y,z> = PolynomialRing(QQ)
|
|
418
|
+
sage: R.interpolation([3,1,2], F) # needs sage.modules
|
|
419
|
+
x^3*y + z^2 + y + 25
|
|
420
|
+
|
|
421
|
+
sage: def F(a, b, c):
|
|
422
|
+
....: return a^3*b + b + c^2 + 25
|
|
423
|
+
....:
|
|
424
|
+
sage: R.<x,y,z> = PolynomialRing(QQ)
|
|
425
|
+
sage: points = [(5,1,1),(7,2,2),(8,5,-1),(2,5,3),(1,4,0),(5,9,0),
|
|
426
|
+
....: (2,7,0),(1,10,13),(0,0,1),(-1,1,0),(2,5,3),(1,1,1),(7,4,11),
|
|
427
|
+
....: (12,1,9),(1,1,3),(4,-1,2),(0,1,5),(5,1,3),(3,1,-2),(2,11,3),
|
|
428
|
+
....: (4,12,19),(3,1,1),(5,2,-3),(12,1,1),(2,3,4)]
|
|
429
|
+
sage: R.interpolation([3,1,2], points, [F(*x) for x in points]) # needs sage.modules
|
|
430
|
+
x^3*y + z^2 + y + 25
|
|
431
|
+
|
|
432
|
+
ALGORITHM:
|
|
433
|
+
|
|
434
|
+
Solves a linear system of equations with the linear algebra module. If
|
|
435
|
+
the points are not specified, it samples exactly as many points as
|
|
436
|
+
needed for a unique solution.
|
|
437
|
+
|
|
438
|
+
.. NOTE::
|
|
439
|
+
|
|
440
|
+
It will only run if the base ring is a field, even though it might
|
|
441
|
+
work otherwise as well. If your base ring is an integral domain,
|
|
442
|
+
let it run over the fraction field.
|
|
443
|
+
|
|
444
|
+
Also, if the solution is not unique, it spits out one solution,
|
|
445
|
+
without any notice that there are more.
|
|
446
|
+
|
|
447
|
+
For interpolation in the univariate case use
|
|
448
|
+
:meth:`~sage.rings.polynomial.polynomial_ring.PolynomialRing_field.lagrange_polynomial`.
|
|
449
|
+
|
|
450
|
+
.. WARNING::
|
|
451
|
+
|
|
452
|
+
If you don't provide point/value pairs but just a function, it
|
|
453
|
+
will only use as many points as needed for a unique solution with
|
|
454
|
+
the given bounds. In particular it will *not* notice or check
|
|
455
|
+
whether the result yields the correct evaluation for other points
|
|
456
|
+
as well. So if you give wrong bounds, you will get a wrong answer
|
|
457
|
+
without any warning. ::
|
|
458
|
+
|
|
459
|
+
sage: def F(a, b, c):
|
|
460
|
+
....: return a^3*b + b + c^2 + 25
|
|
461
|
+
....:
|
|
462
|
+
sage: R.<x,y,z> = PolynomialRing(QQ)
|
|
463
|
+
sage: R.interpolation(3, F) # needs sage.modules
|
|
464
|
+
1/2*x^3 + x*y + z^2 - 1/2*x + y + 25
|
|
465
|
+
|
|
466
|
+
.. SEEALSO::
|
|
467
|
+
|
|
468
|
+
:meth:`~sage.rings.polynomial.polynomial_ring.PolynomialRing_field.lagrange_polynomial`
|
|
469
|
+
"""
|
|
470
|
+
from sage.matrix.constructor import matrix
|
|
471
|
+
from sage.modules.free_module_element import vector
|
|
472
|
+
|
|
473
|
+
# get ring and number of variables
|
|
474
|
+
R = self.base_ring()
|
|
475
|
+
n = self.ngens()
|
|
476
|
+
|
|
477
|
+
# we only run the algorithm over fields
|
|
478
|
+
if not R.is_field():
|
|
479
|
+
raise TypeError(f'The base ring {R} is not a field.')
|
|
480
|
+
|
|
481
|
+
# helper function to sample "num_samples" elements from R
|
|
482
|
+
def sample_points(num_samples):
|
|
483
|
+
try:
|
|
484
|
+
samples = list(itertools.islice(R, num_samples))
|
|
485
|
+
if len(samples) < num_samples:
|
|
486
|
+
raise ValueError(f'Could not sample {num_samples} different elements of {R}.')
|
|
487
|
+
except NotImplementedError:
|
|
488
|
+
if R.characteristic() == 0 or R.characteristic() >= num_samples:
|
|
489
|
+
samples = [R(k) for k in range(num_samples)]
|
|
490
|
+
else:
|
|
491
|
+
raise NotImplementedError(f'Could not sample {num_samples} different elements of {R}.')
|
|
492
|
+
|
|
493
|
+
return samples
|
|
494
|
+
|
|
495
|
+
# set points and values
|
|
496
|
+
if len(args) == 2:
|
|
497
|
+
points, values = args
|
|
498
|
+
else:
|
|
499
|
+
F, = args
|
|
500
|
+
|
|
501
|
+
if isinstance(bound, Iterable):
|
|
502
|
+
R_points = sample_points(max(bound) + 1)
|
|
503
|
+
points = list(itertools.product(*[R_points[:bound[i] + 1] for i in range(n)]))
|
|
504
|
+
else:
|
|
505
|
+
points = list(itertools.combinations_with_replacement(sample_points(bound + 1), n))
|
|
506
|
+
|
|
507
|
+
values = [F(*x) for x in points]
|
|
508
|
+
|
|
509
|
+
# find all possibly appearing exponents
|
|
510
|
+
if isinstance(bound, Iterable):
|
|
511
|
+
exponents_space = list(itertools.product(*(range(bound[i] + 1) for i in range(n))))
|
|
512
|
+
else:
|
|
513
|
+
exponents_space = []
|
|
514
|
+
for entry in itertools.combinations_with_replacement(range(bound + 1), n):
|
|
515
|
+
exponents_space.append([entry[0]] + [entry[i] - entry[i - 1] for i in range(1, n)])
|
|
516
|
+
|
|
517
|
+
# build matrix
|
|
518
|
+
M = matrix.zero(R, 0, len(points))
|
|
519
|
+
for exponents in exponents_space:
|
|
520
|
+
M = M.stack(vector(R, [self.monomial(*exponents)(*x) for x in points]))
|
|
521
|
+
|
|
522
|
+
# solve for coefficients and construct polynomial
|
|
523
|
+
try:
|
|
524
|
+
coeff = M.solve_left(vector(R, values))
|
|
525
|
+
except ValueError:
|
|
526
|
+
raise ValueError('Could not find a solution.')
|
|
527
|
+
solution = sum(coeff[i] * self.monomial(*exponents_space[i]) for i in range(len(exponents_space)))
|
|
528
|
+
|
|
529
|
+
return solution
|
|
530
|
+
|
|
531
|
+
def _coerce_map_from_base_ring(self):
|
|
532
|
+
"""
|
|
533
|
+
Return a coercion map from the base ring of ``self``.
|
|
534
|
+
|
|
535
|
+
EXAMPLES::
|
|
536
|
+
|
|
537
|
+
sage: R.<x,y> = QQ[]
|
|
538
|
+
sage: R.coerce_map_from(QQ)
|
|
539
|
+
Polynomial base injection morphism:
|
|
540
|
+
From: Rational Field
|
|
541
|
+
To: Multivariate Polynomial Ring in x, y over Rational Field
|
|
542
|
+
sage: R.coerce_map_from(ZZ)
|
|
543
|
+
Composite map:
|
|
544
|
+
From: Integer Ring
|
|
545
|
+
To: Multivariate Polynomial Ring in x, y over Rational Field
|
|
546
|
+
Defn: Natural morphism:
|
|
547
|
+
From: Integer Ring
|
|
548
|
+
To: Rational Field
|
|
549
|
+
then
|
|
550
|
+
Polynomial base injection morphism:
|
|
551
|
+
From: Rational Field
|
|
552
|
+
To: Multivariate Polynomial Ring in x, y over Rational Field
|
|
553
|
+
|
|
554
|
+
sage: A = Zmod(6^12)
|
|
555
|
+
sage: S.<x,y> = A[]; S
|
|
556
|
+
Multivariate Polynomial Ring in x, y over Ring of integers modulo 2176782336
|
|
557
|
+
sage: S.coerce_map_from(A)
|
|
558
|
+
Polynomial base injection morphism:
|
|
559
|
+
From: Ring of integers modulo 2176782336
|
|
560
|
+
To: Multivariate Polynomial Ring in x, y over Ring of integers modulo 2176782336
|
|
561
|
+
|
|
562
|
+
sage: T = PolynomialRing(QQ, []); T
|
|
563
|
+
Multivariate Polynomial Ring in no variables over Rational Field
|
|
564
|
+
sage: T.coerce_map_from(QQ)
|
|
565
|
+
Call morphism:
|
|
566
|
+
From: Rational Field
|
|
567
|
+
To: Multivariate Polynomial Ring in no variables over Rational Field
|
|
568
|
+
"""
|
|
569
|
+
if self.ngens():
|
|
570
|
+
from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection
|
|
571
|
+
return PolynomialBaseringInjection(self.base_ring(), self)
|
|
572
|
+
else:
|
|
573
|
+
return self._generic_coerce_map(self.base_ring())
|
|
574
|
+
|
|
575
|
+
cpdef _coerce_map_from_(self, other):
|
|
576
|
+
"""
|
|
577
|
+
Return whether there is canonical coercion map
|
|
578
|
+
from the ring ``other`` to this multivariate polynomial ring `R`.
|
|
579
|
+
|
|
580
|
+
The rings that canonically coerce to the polynomial ring `R` are:
|
|
581
|
+
|
|
582
|
+
- the ring `R` itself,
|
|
583
|
+
|
|
584
|
+
- the base ring of `R`,
|
|
585
|
+
|
|
586
|
+
- any ring that canonically coerces to the base ring of `R`.
|
|
587
|
+
|
|
588
|
+
- polynomial rings in an initial subset of the variables of `R`
|
|
589
|
+
over any base ring that canonically coerces to the base ring of `R`,
|
|
590
|
+
|
|
591
|
+
- polynomial rings in one of the variables of `R`
|
|
592
|
+
over any base ring that canonically coerces to the base ring of `R`,
|
|
593
|
+
|
|
594
|
+
TESTS:
|
|
595
|
+
|
|
596
|
+
Fairly complicated code (from Michel Vandenbergh)::
|
|
597
|
+
|
|
598
|
+
sage: # needs sage.rings.number_field
|
|
599
|
+
sage: z = polygen(QQ, 'z')
|
|
600
|
+
sage: W.<s> = NumberField(z^2 + 1)
|
|
601
|
+
sage: Q.<u,v,w> = W[]
|
|
602
|
+
sage: W1 = FractionField(Q)
|
|
603
|
+
sage: S.<x,y,z> = W1[]
|
|
604
|
+
sage: u + x
|
|
605
|
+
x + u
|
|
606
|
+
sage: x + 1/u
|
|
607
|
+
x + 1/u
|
|
608
|
+
"""
|
|
609
|
+
base_ring = self.base_ring()
|
|
610
|
+
if other is base_ring:
|
|
611
|
+
# Because this parent class is a Cython class, the method
|
|
612
|
+
# UnitalAlgebras.ParentMethods.__init_extra__(), which normally
|
|
613
|
+
# registers the coercion map from the base ring, is called only
|
|
614
|
+
# when inheriting from this class in Python (cf. Issue #26958).
|
|
615
|
+
return self._coerce_map_from_base_ring()
|
|
616
|
+
|
|
617
|
+
f = self._coerce_map_via([base_ring], other)
|
|
618
|
+
if f is not None:
|
|
619
|
+
return f
|
|
620
|
+
|
|
621
|
+
# polynomial rings in an initial subset of variables
|
|
622
|
+
# over the any base that coerces in
|
|
623
|
+
if isinstance(other, MPolynomialRing_base):
|
|
624
|
+
if self is other:
|
|
625
|
+
return True
|
|
626
|
+
n = other.ngens()
|
|
627
|
+
check = (self.ngens() >= n and
|
|
628
|
+
self.variable_names()[:n] == other.variable_names())
|
|
629
|
+
if other.base_ring is base_ring and check:
|
|
630
|
+
return True
|
|
631
|
+
elif base_ring.has_coerce_map_from(other._mpoly_base_ring(self.variable_names())):
|
|
632
|
+
return True
|
|
633
|
+
|
|
634
|
+
# polynomial rings in one of the variables
|
|
635
|
+
# over the any base that coerces in
|
|
636
|
+
elif isinstance(other, polynomial_ring.PolynomialRing_generic):
|
|
637
|
+
if other.variable_name() in self.variable_names():
|
|
638
|
+
if self.has_coerce_map_from(other.base_ring()):
|
|
639
|
+
return True
|
|
640
|
+
|
|
641
|
+
# any ring that coerces to the base ring of this polynomial ring
|
|
642
|
+
return self.base_ring().has_coerce_map_from(other)
|
|
643
|
+
|
|
644
|
+
def _extract_polydict(self, x):
|
|
645
|
+
"""
|
|
646
|
+
Assuming other_vars is a subset of ``self.variable_names()``,
|
|
647
|
+
convert the dict of ETuples with respect to other_vars to
|
|
648
|
+
a dict with respect to ``self.variable_names()``.
|
|
649
|
+
"""
|
|
650
|
+
# This is probably horribly inefficient
|
|
651
|
+
other_vars = list(x.parent().variable_names())
|
|
652
|
+
name_mapping = [(other_vars.index(var) if var in other_vars else -1)
|
|
653
|
+
for var in self.variable_names()]
|
|
654
|
+
K = self.base_ring()
|
|
655
|
+
D = {}
|
|
656
|
+
var_range = range(len(self.variable_names()))
|
|
657
|
+
for ix, a in x.monomial_coefficients().items():
|
|
658
|
+
ix = ETuple([0 if name_mapping[t] == -1 else ix[name_mapping[t]]
|
|
659
|
+
for t in var_range])
|
|
660
|
+
D[ix] = K(a)
|
|
661
|
+
return D
|
|
662
|
+
|
|
663
|
+
def __richcmp__(left, right, int op):
|
|
664
|
+
if left is right:
|
|
665
|
+
return rich_to_bool(op, 0)
|
|
666
|
+
|
|
667
|
+
if not isinstance(right, Parent) or not isinstance(left, Parent):
|
|
668
|
+
# One is not a parent -- not equal and not ordered
|
|
669
|
+
return op == Py_NE
|
|
670
|
+
|
|
671
|
+
if not isinstance(right, MPolynomialRing_base):
|
|
672
|
+
return op == Py_NE
|
|
673
|
+
|
|
674
|
+
lft = <MPolynomialRing_base>left
|
|
675
|
+
other = <MPolynomialRing_base>right
|
|
676
|
+
|
|
677
|
+
lx = (lft.base_ring(), lft._ngens,
|
|
678
|
+
lft.variable_names(),
|
|
679
|
+
lft._term_order)
|
|
680
|
+
rx = (other.base_ring(), other._ngens,
|
|
681
|
+
other.variable_names(),
|
|
682
|
+
other._term_order)
|
|
683
|
+
return richcmp(lx, rx, op)
|
|
684
|
+
|
|
685
|
+
def _repr_(self):
|
|
686
|
+
"""
|
|
687
|
+
Return string representation of this object.
|
|
688
|
+
|
|
689
|
+
EXAMPLES::
|
|
690
|
+
|
|
691
|
+
sage: PolynomialRing(QQ, names=[])
|
|
692
|
+
Multivariate Polynomial Ring in no variables over Rational Field
|
|
693
|
+
|
|
694
|
+
sage: PolynomialRing(QQ, names=['x', 'y'])
|
|
695
|
+
Multivariate Polynomial Ring in x, y over Rational Field
|
|
696
|
+
"""
|
|
697
|
+
if self.ngens() == 0:
|
|
698
|
+
generators_rep = "no variables"
|
|
699
|
+
else:
|
|
700
|
+
generators_rep = ", ".join(self.variable_names())
|
|
701
|
+
return "Multivariate Polynomial Ring in %s over %s" % (generators_rep,
|
|
702
|
+
self.base_ring())
|
|
703
|
+
|
|
704
|
+
def repr_long(self):
|
|
705
|
+
"""
|
|
706
|
+
Return structured string representation of ``self``.
|
|
707
|
+
|
|
708
|
+
EXAMPLES::
|
|
709
|
+
|
|
710
|
+
sage: P.<x,y,z> = PolynomialRing(QQ, order=TermOrder('degrevlex',1)
|
|
711
|
+
....: + TermOrder('lex',2))
|
|
712
|
+
sage: print(P.repr_long())
|
|
713
|
+
Polynomial Ring
|
|
714
|
+
Base Ring : Rational Field
|
|
715
|
+
Size : 3 Variables
|
|
716
|
+
Block 0 : Ordering : degrevlex
|
|
717
|
+
Names : x
|
|
718
|
+
Block 1 : Ordering : lex
|
|
719
|
+
Names : y, z
|
|
720
|
+
"""
|
|
721
|
+
from sage.rings.polynomial.term_order import inv_singular_name_mapping
|
|
722
|
+
n = self.ngens()
|
|
723
|
+
k = self.base_ring()
|
|
724
|
+
names = self.variable_names()
|
|
725
|
+
T = self.term_order()
|
|
726
|
+
_repr = "Polynomial Ring\n"
|
|
727
|
+
_repr += " Base Ring : %s\n" % (k,)
|
|
728
|
+
_repr += " Size : %d Variables\n" % (n,)
|
|
729
|
+
offset = 0
|
|
730
|
+
i = 0
|
|
731
|
+
for order in T.blocks():
|
|
732
|
+
_repr += " Block % 2d : Ordering : %s\n" % (i, inv_singular_name_mapping.get(order.singular_str(), order.singular_str()))
|
|
733
|
+
_repr += " Names : %s\n" % (", ".join(names[offset:offset + len(order)]))
|
|
734
|
+
offset += len(order)
|
|
735
|
+
i += 1
|
|
736
|
+
return _repr
|
|
737
|
+
|
|
738
|
+
def _latex_(self):
|
|
739
|
+
vars = ', '.join(self.latex_variable_names())
|
|
740
|
+
return "%s[%s]" % (sage.misc.latex.latex(self.base_ring()), vars)
|
|
741
|
+
|
|
742
|
+
def _ideal_class_(self, n=0):
|
|
743
|
+
from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
|
|
744
|
+
return MPolynomialIdeal
|
|
745
|
+
|
|
746
|
+
def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None):
|
|
747
|
+
"""
|
|
748
|
+
EXAMPLES::
|
|
749
|
+
|
|
750
|
+
sage: # needs sage.rings.number_field
|
|
751
|
+
sage: T.<t> = ZZ[]
|
|
752
|
+
sage: K.<i> = NumberField(t^2 + 1)
|
|
753
|
+
sage: R.<x,y> = K[]
|
|
754
|
+
sage: Q5 = Qp(5); i5 = Q5(-1).sqrt()
|
|
755
|
+
sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()]) # no coercion
|
|
756
|
+
False
|
|
757
|
+
sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()], base_map=K.hom([i5]))
|
|
758
|
+
True
|
|
759
|
+
"""
|
|
760
|
+
if base_map is None:
|
|
761
|
+
# all that is needed is that elements of the base ring
|
|
762
|
+
# of the polynomial ring canonically coerce into codomain.
|
|
763
|
+
# Since poly rings are free, any image of the gen
|
|
764
|
+
# determines a homomorphism
|
|
765
|
+
return codomain.has_coerce_map_from(self._base)
|
|
766
|
+
return True
|
|
767
|
+
|
|
768
|
+
def _magma_init_(self, magma):
|
|
769
|
+
"""
|
|
770
|
+
Used in converting this ring to the corresponding ring in Magma.
|
|
771
|
+
|
|
772
|
+
EXAMPLES::
|
|
773
|
+
|
|
774
|
+
sage: # optional - magma
|
|
775
|
+
sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
|
|
776
|
+
sage: R._magma_init_(magma)
|
|
777
|
+
'SageCreateWithNames(PolynomialRing(_sage_ref...,10,"grevlex"),["a","b","c","d","e","f","g","h","i","j"])'
|
|
778
|
+
sage: R.<y,z,w> = PolynomialRing(QQ, 3)
|
|
779
|
+
sage: magma(R)
|
|
780
|
+
Polynomial ring of rank 3 over Rational Field
|
|
781
|
+
Order: Graded Reverse Lexicographical
|
|
782
|
+
Variables: y, z, w
|
|
783
|
+
|
|
784
|
+
A complicated nested example::
|
|
785
|
+
|
|
786
|
+
sage: # optional - magma, needs sage.rings.finite_rings
|
|
787
|
+
sage: R.<a,b,c> = PolynomialRing(GF(9,'a')); S.<T,W> = R[]; S
|
|
788
|
+
Multivariate Polynomial Ring in T, W over Multivariate
|
|
789
|
+
Polynomial Ring in a, b, c over Finite Field in a of size 3^2
|
|
790
|
+
sage: magma(S)
|
|
791
|
+
Polynomial ring of rank 2 over Polynomial ring of rank 3
|
|
792
|
+
over GF(3^2)
|
|
793
|
+
Order: Graded Reverse Lexicographical
|
|
794
|
+
Variables: T, W
|
|
795
|
+
|
|
796
|
+
sage: # optional - magma
|
|
797
|
+
sage: magma(PolynomialRing(GF(7),4, 'x'))
|
|
798
|
+
Polynomial ring of rank 4 over GF(7)
|
|
799
|
+
Order: Graded Reverse Lexicographical
|
|
800
|
+
Variables: x0, x1, x2, x3
|
|
801
|
+
sage: magma(PolynomialRing(GF(49,'a'),10, 'x')) # needs sage.rings.finite_rings
|
|
802
|
+
Polynomial ring of rank 10 over GF(7^2)
|
|
803
|
+
Order: Graded Reverse Lexicographical
|
|
804
|
+
Variables: x0, x1, x2, x3, x4, x5, x6, x7, x8, x9
|
|
805
|
+
sage: magma(PolynomialRing(ZZ['a,b,c'],3, 'x'))
|
|
806
|
+
Polynomial ring of rank 3 over Polynomial ring of rank 3
|
|
807
|
+
over Integer Ring
|
|
808
|
+
Order: Graded Reverse Lexicographical
|
|
809
|
+
Variables: x0, x1, x2
|
|
810
|
+
"""
|
|
811
|
+
B = magma(self.base_ring())
|
|
812
|
+
Bref = B._ref()
|
|
813
|
+
s = 'PolynomialRing(%s,%s,%s)' % (Bref, self.ngens(),
|
|
814
|
+
self.term_order().magma_str())
|
|
815
|
+
return magma._with_names(s, self.variable_names())
|
|
816
|
+
|
|
817
|
+
def _gap_init_(self, gap=None):
|
|
818
|
+
"""
|
|
819
|
+
Return a string that yields a representation of ``self`` in GAP.
|
|
820
|
+
|
|
821
|
+
INPUT:
|
|
822
|
+
|
|
823
|
+
- ``gap`` -- (optional GAP instance) interface to which the
|
|
824
|
+
string is addressed
|
|
825
|
+
|
|
826
|
+
NOTE:
|
|
827
|
+
|
|
828
|
+
- If the optional argument ``gap`` is provided, the base ring
|
|
829
|
+
of ``self`` will be represented as ``gap(self.base_ring()).name()``.
|
|
830
|
+
- The result of applying the GAP interface to ``self`` is cached.
|
|
831
|
+
|
|
832
|
+
EXAMPLES::
|
|
833
|
+
|
|
834
|
+
sage: # needs sage.libs.gap sage.rings.number_field
|
|
835
|
+
sage: F = CyclotomicField(8)
|
|
836
|
+
sage: P.<x,y> = F[]
|
|
837
|
+
sage: gap(P) # indirect doctest
|
|
838
|
+
PolynomialRing( CF(8), ["x", "y"] )
|
|
839
|
+
sage: libgap(P)
|
|
840
|
+
<field in characteristic 0>[x,y]
|
|
841
|
+
"""
|
|
842
|
+
L = ['"%s"' % t for t in self.variable_names()]
|
|
843
|
+
if gap is not None:
|
|
844
|
+
return 'PolynomialRing(%s,[%s])' % (gap(self.base_ring()).name(),
|
|
845
|
+
','.join(L))
|
|
846
|
+
return 'PolynomialRing(%s,[%s])' % (self.base_ring()._gap_init_(),
|
|
847
|
+
','.join(L))
|
|
848
|
+
|
|
849
|
+
cpdef bint is_exact(self) except -2:
|
|
850
|
+
"""
|
|
851
|
+
Test whether this multivariate polynomial ring is defined over an exact
|
|
852
|
+
base ring.
|
|
853
|
+
|
|
854
|
+
EXAMPLES::
|
|
855
|
+
|
|
856
|
+
sage: PolynomialRing(QQ, 2, 'x').is_exact()
|
|
857
|
+
True
|
|
858
|
+
sage: PolynomialRing(RDF, 2, 'x').is_exact()
|
|
859
|
+
False
|
|
860
|
+
"""
|
|
861
|
+
return self.base_ring().is_exact()
|
|
862
|
+
|
|
863
|
+
def is_field(self, proof=True):
|
|
864
|
+
"""
|
|
865
|
+
Test whether this multivariate polynomial ring is a field.
|
|
866
|
+
|
|
867
|
+
A polynomial ring is a field when there are no variable and the base
|
|
868
|
+
ring is a field.
|
|
869
|
+
|
|
870
|
+
EXAMPLES::
|
|
871
|
+
|
|
872
|
+
sage: PolynomialRing(QQ, 'x', 2).is_field()
|
|
873
|
+
False
|
|
874
|
+
sage: PolynomialRing(QQ, 'x', 0).is_field()
|
|
875
|
+
True
|
|
876
|
+
sage: PolynomialRing(ZZ, 'x', 0).is_field()
|
|
877
|
+
False
|
|
878
|
+
sage: PolynomialRing(Zmod(1), names=['x','y']).is_finite()
|
|
879
|
+
True
|
|
880
|
+
"""
|
|
881
|
+
if not self.ngens():
|
|
882
|
+
return self.base_ring().is_field(proof)
|
|
883
|
+
return False
|
|
884
|
+
|
|
885
|
+
def term_order(self):
|
|
886
|
+
return self._term_order
|
|
887
|
+
|
|
888
|
+
def characteristic(self):
|
|
889
|
+
"""
|
|
890
|
+
Return the characteristic of this polynomial ring.
|
|
891
|
+
|
|
892
|
+
EXAMPLES::
|
|
893
|
+
|
|
894
|
+
sage: R = PolynomialRing(QQ, 'x', 3)
|
|
895
|
+
sage: R.characteristic()
|
|
896
|
+
0
|
|
897
|
+
sage: R = PolynomialRing(GF(7), 'x', 20)
|
|
898
|
+
sage: R.characteristic()
|
|
899
|
+
7
|
|
900
|
+
"""
|
|
901
|
+
return self.base_ring().characteristic()
|
|
902
|
+
|
|
903
|
+
def gen(self, n=0):
|
|
904
|
+
if n < 0 or n >= self._ngens:
|
|
905
|
+
raise ValueError("generator not defined")
|
|
906
|
+
return self._gens[int(n)]
|
|
907
|
+
|
|
908
|
+
def variable_names_recursive(self, depth=sage.rings.infinity.infinity):
|
|
909
|
+
r"""
|
|
910
|
+
Return the list of variable names of this and its base rings, as if
|
|
911
|
+
it were a single multi-variate polynomial.
|
|
912
|
+
|
|
913
|
+
EXAMPLES::
|
|
914
|
+
|
|
915
|
+
sage: R = QQ['x,y']['z,w']
|
|
916
|
+
sage: R.variable_names_recursive()
|
|
917
|
+
('x', 'y', 'z', 'w')
|
|
918
|
+
sage: R.variable_names_recursive(3)
|
|
919
|
+
('y', 'z', 'w')
|
|
920
|
+
"""
|
|
921
|
+
if depth <= 0:
|
|
922
|
+
all = ()
|
|
923
|
+
elif depth == 1:
|
|
924
|
+
all = self.variable_names()
|
|
925
|
+
else:
|
|
926
|
+
my_vars = self.variable_names()
|
|
927
|
+
try:
|
|
928
|
+
all = self.base_ring().variable_names_recursive(depth - len(my_vars)) + my_vars
|
|
929
|
+
except AttributeError:
|
|
930
|
+
all = my_vars
|
|
931
|
+
if len(all) > depth:
|
|
932
|
+
all = all[-depth:]
|
|
933
|
+
return all
|
|
934
|
+
|
|
935
|
+
def _mpoly_base_ring(self, vars=None):
|
|
936
|
+
"""
|
|
937
|
+
Return the base ring if this is viewed as a polynomial ring over vars.
|
|
938
|
+
|
|
939
|
+
See also MPolynomial._mpoly_dict_recursive.
|
|
940
|
+
"""
|
|
941
|
+
if vars is None:
|
|
942
|
+
vars = self.variable_names_recursive()
|
|
943
|
+
vars = list(vars)
|
|
944
|
+
my_vars = list(self.variable_names())
|
|
945
|
+
if vars == list(my_vars):
|
|
946
|
+
return self.base_ring()
|
|
947
|
+
elif not my_vars[-1] in vars:
|
|
948
|
+
return self
|
|
949
|
+
elif not set(my_vars).issubset(set(vars)):
|
|
950
|
+
while my_vars[-1] in vars:
|
|
951
|
+
my_vars.pop()
|
|
952
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
953
|
+
return PolynomialRing(self.base_ring(), my_vars)
|
|
954
|
+
else:
|
|
955
|
+
try:
|
|
956
|
+
return self.base_ring()._mpoly_base_ring(vars[:vars.index(my_vars[0])])
|
|
957
|
+
except AttributeError:
|
|
958
|
+
return self.base_ring()
|
|
959
|
+
|
|
960
|
+
def krull_dimension(self):
|
|
961
|
+
return self.base_ring().krull_dimension() + self.ngens()
|
|
962
|
+
|
|
963
|
+
def ngens(self):
|
|
964
|
+
return self._ngens
|
|
965
|
+
|
|
966
|
+
def _monomial_order_function(self):
|
|
967
|
+
raise NotImplementedError
|
|
968
|
+
|
|
969
|
+
def __reduce__(self):
|
|
970
|
+
base_ring = self.base_ring()
|
|
971
|
+
n = self.ngens()
|
|
972
|
+
names = self.variable_names()
|
|
973
|
+
order = self.term_order()
|
|
974
|
+
return unpickle_MPolynomialRing_generic_v1, (base_ring, n, names, order)
|
|
975
|
+
|
|
976
|
+
def _precomp_counts(self, n, d):
|
|
977
|
+
"""
|
|
978
|
+
Given a number of variable n and a degree d return a tuple (C,t)
|
|
979
|
+
such that C is a list of the cardinalities of the sets of
|
|
980
|
+
monomials up to degree d (including) in n variables and t is the
|
|
981
|
+
sum of these cardinalities.
|
|
982
|
+
|
|
983
|
+
INPUT:
|
|
984
|
+
|
|
985
|
+
- ``n`` -- number of variables
|
|
986
|
+
- ``d`` -- degree
|
|
987
|
+
|
|
988
|
+
EXAMPLES::
|
|
989
|
+
|
|
990
|
+
sage: P.<x,y> = PolynomialRing(ZZ)
|
|
991
|
+
sage: C,t = P._precomp_counts(10,2)
|
|
992
|
+
sage: C[0]
|
|
993
|
+
1
|
|
994
|
+
sage: C[1]
|
|
995
|
+
10
|
|
996
|
+
sage: C[2]
|
|
997
|
+
55
|
|
998
|
+
sage: t
|
|
999
|
+
66
|
|
1000
|
+
|
|
1001
|
+
TESTS::
|
|
1002
|
+
|
|
1003
|
+
sage: P.<x,y> = PolynomialRing(ZZ)
|
|
1004
|
+
sage: C,t = P._precomp_counts(1,2)
|
|
1005
|
+
sage: C[0]
|
|
1006
|
+
1
|
|
1007
|
+
sage: C[1]
|
|
1008
|
+
1
|
|
1009
|
+
sage: C[2]
|
|
1010
|
+
1
|
|
1011
|
+
sage: t
|
|
1012
|
+
3
|
|
1013
|
+
"""
|
|
1014
|
+
C = [1] # d = 0
|
|
1015
|
+
for dbar in range(1, d + 1):
|
|
1016
|
+
C.append(binomial(n + dbar - 1, dbar))
|
|
1017
|
+
return C, sum(C)
|
|
1018
|
+
|
|
1019
|
+
def _to_monomial(self, i, n, d):
|
|
1020
|
+
"""
|
|
1021
|
+
Given an index ``i``, a number of variables ``n`` and a degree ``d``
|
|
1022
|
+
return the `i`-th monomial of degree `d` in `n` variables.
|
|
1023
|
+
|
|
1024
|
+
INPUT:
|
|
1025
|
+
|
|
1026
|
+
- ``i`` -- index; ``0 <= i < binom(n+d-1,n-1)``
|
|
1027
|
+
- ``n`` -- number of variables
|
|
1028
|
+
- ``d`` -- degree
|
|
1029
|
+
|
|
1030
|
+
EXAMPLES::
|
|
1031
|
+
|
|
1032
|
+
sage: P.<x,y> = PolynomialRing(QQ)
|
|
1033
|
+
sage: P._to_monomial(0,10,2)
|
|
1034
|
+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 2)
|
|
1035
|
+
sage: P._to_monomial(8,10,2)
|
|
1036
|
+
(0, 0, 0, 0, 0, 0, 1, 1, 0, 0)
|
|
1037
|
+
sage: P._to_monomial(54,10,2)
|
|
1038
|
+
(2, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
1039
|
+
|
|
1040
|
+
.. NOTE::
|
|
1041
|
+
|
|
1042
|
+
We do not check if the provided index/rank is within the allowed
|
|
1043
|
+
range. If it is not an infinite loop will occur.
|
|
1044
|
+
"""
|
|
1045
|
+
from sage.combinat import combination
|
|
1046
|
+
comb = combination.from_rank(i, n + d - 1, n - 1)
|
|
1047
|
+
if not comb:
|
|
1048
|
+
return (d,)
|
|
1049
|
+
monomial = [comb[0]]
|
|
1050
|
+
monomial.extend(comb[j + 1] - comb[j] - 1 for j in range(n - 2))
|
|
1051
|
+
monomial.append(n + d - 1 - comb[-1] - 1)
|
|
1052
|
+
return tuple(monomial)
|
|
1053
|
+
|
|
1054
|
+
def _random_monomial_upto_degree_class(self, n, degree, counts=None,
|
|
1055
|
+
total=None):
|
|
1056
|
+
"""
|
|
1057
|
+
Choose a random exponent tuple for `n` variables with a random
|
|
1058
|
+
degree `d`, i.e. choose the degree uniformly at random first
|
|
1059
|
+
before choosing a random monomial.
|
|
1060
|
+
|
|
1061
|
+
INPUT:
|
|
1062
|
+
|
|
1063
|
+
- ``n`` -- number of variables
|
|
1064
|
+
- ``degree`` -- degree of monomials
|
|
1065
|
+
- ``counts`` -- ignored
|
|
1066
|
+
- ``total`` -- ignored
|
|
1067
|
+
|
|
1068
|
+
EXAMPLES::
|
|
1069
|
+
|
|
1070
|
+
sage: from collections import defaultdict
|
|
1071
|
+
sage: K.<x,y,z,w> = QQ[]
|
|
1072
|
+
sage: dic = defaultdict(Integer)
|
|
1073
|
+
sage: counter = 0
|
|
1074
|
+
|
|
1075
|
+
sage: def more_samples():
|
|
1076
|
+
....: global dic, counter
|
|
1077
|
+
....: for _ in range(100):
|
|
1078
|
+
....: dic[K._random_monomial_upto_degree_class(5, 7)] += 1
|
|
1079
|
+
....: counter += 1.0
|
|
1080
|
+
|
|
1081
|
+
sage: def prob(entries):
|
|
1082
|
+
....: degree = sum(entries)
|
|
1083
|
+
....: total = binomial(5 + degree - 1, degree)
|
|
1084
|
+
....: return 1.0/(8*total)
|
|
1085
|
+
|
|
1086
|
+
sage: more_samples()
|
|
1087
|
+
sage: while any(abs(prob(i) - dic[i]/counter) > 0.01 for i in dic): # needs sage.symbolic
|
|
1088
|
+
....: more_samples()
|
|
1089
|
+
"""
|
|
1090
|
+
# bug: doesn't handle n=1
|
|
1091
|
+
# Select random degree
|
|
1092
|
+
d = ZZ.random_element(0, degree + 1)
|
|
1093
|
+
total = binomial(n + d - 1, d)
|
|
1094
|
+
|
|
1095
|
+
# Select random monomial of degree d
|
|
1096
|
+
random_index = ZZ.random_element(0, total)
|
|
1097
|
+
# Generate the corresponding monomial
|
|
1098
|
+
return self._to_monomial(random_index, n, d)
|
|
1099
|
+
|
|
1100
|
+
def _random_monomial_upto_degree_uniform(self, n, degree, counts=None,
|
|
1101
|
+
total=None):
|
|
1102
|
+
"""
|
|
1103
|
+
Choose a random exponent tuple for `n` variables with a random
|
|
1104
|
+
degree up to `d`, i.e. choose a random monomial uniformly random
|
|
1105
|
+
from all monomials up to degree `d`. This discriminates against
|
|
1106
|
+
smaller degrees because there are more monomials of bigger
|
|
1107
|
+
degrees.
|
|
1108
|
+
|
|
1109
|
+
INPUT:
|
|
1110
|
+
|
|
1111
|
+
- ``n`` -- number of variables
|
|
1112
|
+
- ``degree`` -- degree of monomials
|
|
1113
|
+
- ``counts`` -- ignored
|
|
1114
|
+
- ``total`` -- ignored
|
|
1115
|
+
|
|
1116
|
+
EXAMPLES::
|
|
1117
|
+
|
|
1118
|
+
sage: from collections import defaultdict
|
|
1119
|
+
sage: K.<x,y,z,w> = QQ[]
|
|
1120
|
+
sage: dic = defaultdict(Integer)
|
|
1121
|
+
sage: counter = 0
|
|
1122
|
+
|
|
1123
|
+
sage: def more_samples():
|
|
1124
|
+
....: global dic, counter
|
|
1125
|
+
....: for _ in range(100):
|
|
1126
|
+
....: dic[K._random_monomial_upto_degree_uniform(5, 7)] += 1
|
|
1127
|
+
....: counter += 1.0
|
|
1128
|
+
|
|
1129
|
+
sage: more_samples()
|
|
1130
|
+
sage: while any(abs(1.0/len(dic) - dic[i]/counter) > 0.001 for i in dic):
|
|
1131
|
+
....: more_samples()
|
|
1132
|
+
"""
|
|
1133
|
+
if counts is None or total is None:
|
|
1134
|
+
counts, total = self._precomp_counts(n, degree)
|
|
1135
|
+
|
|
1136
|
+
# Select a random one
|
|
1137
|
+
random_index = ZZ.random_element(0, total - 1)
|
|
1138
|
+
# Figure out which degree it corresponds to
|
|
1139
|
+
d = 0
|
|
1140
|
+
while random_index >= counts[d]:
|
|
1141
|
+
random_index -= counts[d]
|
|
1142
|
+
d += 1
|
|
1143
|
+
# Generate the corresponding monomial
|
|
1144
|
+
return self._to_monomial(random_index, n, d)
|
|
1145
|
+
|
|
1146
|
+
def random_element(self, degree=2, terms=None, choose_degree=False,
|
|
1147
|
+
*args, **kwargs):
|
|
1148
|
+
"""
|
|
1149
|
+
Return a random polynomial of at most degree `d` and at most `t`
|
|
1150
|
+
terms.
|
|
1151
|
+
|
|
1152
|
+
First monomials are chosen uniformly random from the set of all
|
|
1153
|
+
possible monomials of degree up to `d` (inclusive). This means
|
|
1154
|
+
that it is more likely that a monomial of degree `d` appears than
|
|
1155
|
+
a monomial of degree `d-1` because the former class is bigger.
|
|
1156
|
+
|
|
1157
|
+
Exactly `t` *distinct* monomials are chosen this way and each one gets
|
|
1158
|
+
a random coefficient (possibly zero) from the base ring assigned.
|
|
1159
|
+
|
|
1160
|
+
The returned polynomial is the sum of this list of terms.
|
|
1161
|
+
|
|
1162
|
+
INPUT:
|
|
1163
|
+
|
|
1164
|
+
- ``degree`` -- maximal degree (likely to be reached) (default: 2)
|
|
1165
|
+
|
|
1166
|
+
- ``terms`` -- number of terms requested (default: 5). If more
|
|
1167
|
+
terms are requested than exist, then this parameter is
|
|
1168
|
+
silently reduced to the maximum number of available terms.
|
|
1169
|
+
|
|
1170
|
+
- ``choose_degree`` -- choose degrees of monomials randomly first
|
|
1171
|
+
rather than monomials uniformly random
|
|
1172
|
+
|
|
1173
|
+
- ``**kwargs`` -- passed to the random element generator of the base
|
|
1174
|
+
ring
|
|
1175
|
+
|
|
1176
|
+
EXAMPLES::
|
|
1177
|
+
|
|
1178
|
+
sage: P.<x,y,z> = PolynomialRing(QQ)
|
|
1179
|
+
sage: f = P.random_element(2, 5)
|
|
1180
|
+
sage: f.degree() <= 2
|
|
1181
|
+
True
|
|
1182
|
+
sage: f.parent() is P
|
|
1183
|
+
True
|
|
1184
|
+
sage: len(list(f)) <= 5
|
|
1185
|
+
True
|
|
1186
|
+
|
|
1187
|
+
sage: f = P.random_element(2, 5, choose_degree=True)
|
|
1188
|
+
sage: f.degree() <= 2
|
|
1189
|
+
True
|
|
1190
|
+
sage: f.parent() is P
|
|
1191
|
+
True
|
|
1192
|
+
sage: len(list(f)) <= 5
|
|
1193
|
+
True
|
|
1194
|
+
|
|
1195
|
+
Stacked rings::
|
|
1196
|
+
|
|
1197
|
+
sage: R = QQ['x,y']
|
|
1198
|
+
sage: S = R['t,u']
|
|
1199
|
+
sage: f = S._random_nonzero_element(degree=2, terms=1)
|
|
1200
|
+
sage: len(list(f))
|
|
1201
|
+
1
|
|
1202
|
+
sage: f.degree() <= 2
|
|
1203
|
+
True
|
|
1204
|
+
sage: f.parent() is S
|
|
1205
|
+
True
|
|
1206
|
+
|
|
1207
|
+
Default values apply if no degree and/or number of terms is
|
|
1208
|
+
provided::
|
|
1209
|
+
|
|
1210
|
+
sage: # needs sage.modules
|
|
1211
|
+
sage: M = random_matrix(QQ['x,y,z'], 2, 2)
|
|
1212
|
+
sage: all(a.degree() <= 2 for a in M.list())
|
|
1213
|
+
True
|
|
1214
|
+
sage: all(len(list(a)) <= 5 for a in M.list())
|
|
1215
|
+
True
|
|
1216
|
+
sage: M = random_matrix(QQ['x,y,z'], 2, 2, terms=1, degree=2)
|
|
1217
|
+
sage: all(a.degree() <= 2 for a in M.list())
|
|
1218
|
+
True
|
|
1219
|
+
sage: all(len(list(a)) <= 1 for a in M.list())
|
|
1220
|
+
True
|
|
1221
|
+
|
|
1222
|
+
sage: P.random_element(0, 1) in QQ
|
|
1223
|
+
True
|
|
1224
|
+
|
|
1225
|
+
sage: P.random_element(2, 0)
|
|
1226
|
+
0
|
|
1227
|
+
|
|
1228
|
+
sage: R.<x> = PolynomialRing(Integers(3), 1)
|
|
1229
|
+
sage: f = R.random_element()
|
|
1230
|
+
sage: f.degree() <= 2
|
|
1231
|
+
True
|
|
1232
|
+
sage: len(list(f)) <= 3
|
|
1233
|
+
True
|
|
1234
|
+
|
|
1235
|
+
To produce a dense polynomial, pick ``terms=Infinity``::
|
|
1236
|
+
|
|
1237
|
+
sage: P.<x,y,z> = GF(127)[]
|
|
1238
|
+
sage: f = P.random_element(degree=2, terms=Infinity)
|
|
1239
|
+
sage: while len(list(f)) != 10:
|
|
1240
|
+
....: f = P.random_element(degree=2, terms=Infinity)
|
|
1241
|
+
sage: f = P.random_element(degree=3, terms=Infinity)
|
|
1242
|
+
sage: while len(list(f)) != 20:
|
|
1243
|
+
....: f = P.random_element(degree=3, terms=Infinity)
|
|
1244
|
+
sage: f = P.random_element(degree=3, terms=Infinity, choose_degree=True)
|
|
1245
|
+
sage: while len(list(f)) != 20:
|
|
1246
|
+
....: f = P.random_element(degree=3, terms=Infinity)
|
|
1247
|
+
|
|
1248
|
+
The number of terms is silently reduced to the maximum
|
|
1249
|
+
available if more terms are requested::
|
|
1250
|
+
|
|
1251
|
+
sage: P.<x,y,z> = GF(127)[]
|
|
1252
|
+
sage: f = P.random_element(degree=2, terms=1000)
|
|
1253
|
+
sage: len(list(f)) <= 10
|
|
1254
|
+
True
|
|
1255
|
+
|
|
1256
|
+
TESTS:
|
|
1257
|
+
|
|
1258
|
+
Random ring elements should live in the ring. We check the degree-
|
|
1259
|
+
zero case for :issue:`28855`, but the same should hold generally::
|
|
1260
|
+
|
|
1261
|
+
sage: R = PolynomialRing(QQ, 'X,Y')
|
|
1262
|
+
sage: R.random_element(degree=0).parent() == R
|
|
1263
|
+
True
|
|
1264
|
+
sage: R.random_element().parent() == R
|
|
1265
|
+
True
|
|
1266
|
+
"""
|
|
1267
|
+
k = self.base_ring()
|
|
1268
|
+
n = self.ngens()
|
|
1269
|
+
|
|
1270
|
+
counts, total = self._precomp_counts(n, degree)
|
|
1271
|
+
|
|
1272
|
+
# Note that 'terms' could be None while 'total' is a
|
|
1273
|
+
# nonnegative integer, so the comparison 'terms > total' could
|
|
1274
|
+
# fail
|
|
1275
|
+
if terms and terms > total:
|
|
1276
|
+
terms = total
|
|
1277
|
+
|
|
1278
|
+
if terms is None:
|
|
1279
|
+
if total >= 5:
|
|
1280
|
+
terms = 5
|
|
1281
|
+
else:
|
|
1282
|
+
terms = total
|
|
1283
|
+
|
|
1284
|
+
if terms < 0:
|
|
1285
|
+
raise TypeError("Cannot compute polynomial with a negative number of terms.")
|
|
1286
|
+
elif terms == 0:
|
|
1287
|
+
return self._zero_element
|
|
1288
|
+
if degree == 0:
|
|
1289
|
+
return self(k.random_element(**kwargs))
|
|
1290
|
+
|
|
1291
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
1292
|
+
|
|
1293
|
+
# total is 0. Just return
|
|
1294
|
+
if total == 0:
|
|
1295
|
+
return self._zero_element
|
|
1296
|
+
|
|
1297
|
+
elif terms < total / 2:
|
|
1298
|
+
# we choose random monomials if t < total/2 because then we
|
|
1299
|
+
# expect the algorithm to be faster than generating all
|
|
1300
|
+
# monomials and picking a random index from the list. if t ==
|
|
1301
|
+
# total/2 we expect every second random monomial to be a
|
|
1302
|
+
# double such that our runtime is doubled in the worst case.
|
|
1303
|
+
M = set()
|
|
1304
|
+
if not choose_degree:
|
|
1305
|
+
while terms:
|
|
1306
|
+
m = self._random_monomial_upto_degree_uniform(n, degree, counts, total)
|
|
1307
|
+
if m not in M:
|
|
1308
|
+
M.add(m)
|
|
1309
|
+
terms -= 1
|
|
1310
|
+
else:
|
|
1311
|
+
while terms:
|
|
1312
|
+
m = self._random_monomial_upto_degree_class(n, degree)
|
|
1313
|
+
if m not in M:
|
|
1314
|
+
M.add(m)
|
|
1315
|
+
terms -= 1
|
|
1316
|
+
elif terms <= total:
|
|
1317
|
+
# generate a list of all monomials and choose among them
|
|
1318
|
+
if not choose_degree:
|
|
1319
|
+
M = sum([list(IntegerVectors(_d, n))
|
|
1320
|
+
for _d in range(degree + 1)], [])
|
|
1321
|
+
# we throw away those we don't need
|
|
1322
|
+
for mi in range(total - terms):
|
|
1323
|
+
M.pop(ZZ.random_element(0, len(M) - 1))
|
|
1324
|
+
M = [tuple(m) for m in M]
|
|
1325
|
+
else:
|
|
1326
|
+
M = [list(IntegerVectors(_d, n)) for _d in range(degree + 1)]
|
|
1327
|
+
Mbar = []
|
|
1328
|
+
for mi in range(terms):
|
|
1329
|
+
# choose degree 'd' and monomial 'm' at random
|
|
1330
|
+
d = ZZ.random_element(0, len(M))
|
|
1331
|
+
m = ZZ.random_element(0, len(M[d]))
|
|
1332
|
+
Mbar.append(M[d].pop(m)) # remove and insert
|
|
1333
|
+
if len(M[d]) == 0:
|
|
1334
|
+
M.pop(d) # bookkeeping
|
|
1335
|
+
M = [tuple(m) for m in Mbar]
|
|
1336
|
+
|
|
1337
|
+
C = [k.random_element(*args, **kwargs) for _ in range(len(M))]
|
|
1338
|
+
|
|
1339
|
+
return self(dict(zip(M, C)))
|
|
1340
|
+
|
|
1341
|
+
def some_elements(self):
|
|
1342
|
+
r"""
|
|
1343
|
+
Return a list of polynomials.
|
|
1344
|
+
|
|
1345
|
+
This is typically used for running generic tests.
|
|
1346
|
+
|
|
1347
|
+
EXAMPLES::
|
|
1348
|
+
|
|
1349
|
+
sage: R.<x,y> = QQ[]
|
|
1350
|
+
sage: R.some_elements()
|
|
1351
|
+
[x, y, x + y, x^2 + x*y, 0, 1]
|
|
1352
|
+
"""
|
|
1353
|
+
L = list(self.gens())
|
|
1354
|
+
if L:
|
|
1355
|
+
L.append(L[0] + L[-1])
|
|
1356
|
+
L.append(L[0] * L[-1])
|
|
1357
|
+
L.extend([self.zero(), self.one()])
|
|
1358
|
+
return L
|
|
1359
|
+
|
|
1360
|
+
def change_ring(self, base_ring=None, names=None, order=None):
|
|
1361
|
+
"""
|
|
1362
|
+
Return a new multivariate polynomial ring which is isomorphic to
|
|
1363
|
+
``self``, but has a different ordering given by the parameter
|
|
1364
|
+
``order`` or names given by the parameter ``names``.
|
|
1365
|
+
|
|
1366
|
+
INPUT:
|
|
1367
|
+
|
|
1368
|
+
- ``base_ring`` -- a base ring
|
|
1369
|
+
- ``names`` -- variable names
|
|
1370
|
+
- ``order`` -- a term order
|
|
1371
|
+
|
|
1372
|
+
EXAMPLES::
|
|
1373
|
+
|
|
1374
|
+
sage: P.<x,y,z> = PolynomialRing(GF(127), 3, order='lex')
|
|
1375
|
+
sage: x > y^2
|
|
1376
|
+
True
|
|
1377
|
+
sage: Q.<x,y,z> = P.change_ring(order='degrevlex')
|
|
1378
|
+
sage: x > y^2
|
|
1379
|
+
False
|
|
1380
|
+
"""
|
|
1381
|
+
if base_ring is None:
|
|
1382
|
+
base_ring = self.base_ring()
|
|
1383
|
+
if names is None:
|
|
1384
|
+
names = self.variable_names()
|
|
1385
|
+
if order is None:
|
|
1386
|
+
order = self.term_order()
|
|
1387
|
+
|
|
1388
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1389
|
+
return PolynomialRing(base_ring, self.ngens(), names, order=order)
|
|
1390
|
+
|
|
1391
|
+
def monomial(self, *exponents):
|
|
1392
|
+
"""
|
|
1393
|
+
Return the monomial with given exponents.
|
|
1394
|
+
|
|
1395
|
+
EXAMPLES::
|
|
1396
|
+
|
|
1397
|
+
sage: R.<x,y,z> = PolynomialRing(ZZ, 3)
|
|
1398
|
+
sage: R.monomial(1,1,1)
|
|
1399
|
+
x*y*z
|
|
1400
|
+
sage: e=(1,2,3)
|
|
1401
|
+
sage: R.monomial(*e)
|
|
1402
|
+
x*y^2*z^3
|
|
1403
|
+
sage: m = R.monomial(1,2,3)
|
|
1404
|
+
sage: R.monomial(*m.degrees()) == m
|
|
1405
|
+
True
|
|
1406
|
+
|
|
1407
|
+
We also allow to specify the exponents in a single tuple::
|
|
1408
|
+
|
|
1409
|
+
sage: R.monomial(e)
|
|
1410
|
+
x*y^2*z^3
|
|
1411
|
+
|
|
1412
|
+
TESTS:
|
|
1413
|
+
|
|
1414
|
+
Check that :class:`.ETuple`s and :class:`.IntegerVector` also work
|
|
1415
|
+
(:class:`.IntegerVector` is used for :meth:`basis`)::
|
|
1416
|
+
|
|
1417
|
+
sage: from sage.combinat.integer_vector import IntegerVector, IntegerVectors
|
|
1418
|
+
sage: from sage.rings.polynomial.polydict import ETuple
|
|
1419
|
+
sage: R.monomial(ETuple(e))
|
|
1420
|
+
x*y^2*z^3
|
|
1421
|
+
sage: R.monomial(IntegerVector(IntegerVectors(), e))
|
|
1422
|
+
x*y^2*z^3
|
|
1423
|
+
|
|
1424
|
+
Corner case::
|
|
1425
|
+
|
|
1426
|
+
sage: R = PolynomialRing(QQ, [])
|
|
1427
|
+
sage: R
|
|
1428
|
+
Multivariate Polynomial Ring in no variables over Rational Field
|
|
1429
|
+
sage: R.monomial(())
|
|
1430
|
+
1
|
|
1431
|
+
sage: R.monomial()
|
|
1432
|
+
1
|
|
1433
|
+
sage: R.monomial(ETuple([]))
|
|
1434
|
+
1
|
|
1435
|
+
sage: R.monomial(IntegerVector(IntegerVectors(), []))
|
|
1436
|
+
1
|
|
1437
|
+
"""
|
|
1438
|
+
from sage.combinat.integer_vector import IntegerVector
|
|
1439
|
+
if len(exponents) == 1 and isinstance((e := exponents[0]), (tuple, IntegerVector, ETuple)):
|
|
1440
|
+
return self({e: self.base_ring().one()})
|
|
1441
|
+
return self({exponents: self.base_ring().one()})
|
|
1442
|
+
|
|
1443
|
+
def monomials_of_degree(self, degree):
|
|
1444
|
+
r"""
|
|
1445
|
+
Return a list of all monomials of the given total degree in this
|
|
1446
|
+
multivariate polynomial ring.
|
|
1447
|
+
|
|
1448
|
+
EXAMPLES::
|
|
1449
|
+
|
|
1450
|
+
sage: # needs sage.combinat
|
|
1451
|
+
sage: R.<x,y,z> = ZZ[]
|
|
1452
|
+
sage: mons = R.monomials_of_degree(2)
|
|
1453
|
+
sage: mons
|
|
1454
|
+
[z^2, y*z, x*z, y^2, x*y, x^2]
|
|
1455
|
+
sage: P = PolynomialRing(QQ, 3, 'x, y, z', order=TermOrder('wdeglex', [1, 2, 1]))
|
|
1456
|
+
sage: P.monomials_of_degree(2)
|
|
1457
|
+
[z^2, y, x*z, x^2]
|
|
1458
|
+
sage: P = PolynomialRing(QQ, 3, 'x, y, z', order='lex')
|
|
1459
|
+
sage: P.monomials_of_degree(3)
|
|
1460
|
+
[z^3, y*z^2, y^2*z, y^3, x*z^2, x*y*z, x*y^2, x^2*z, x^2*y, x^3]
|
|
1461
|
+
sage: P = PolynomialRing(QQ, 3, 'x, y, z', order='invlex')
|
|
1462
|
+
sage: P.monomials_of_degree(3)
|
|
1463
|
+
[x^3, x^2*y, x*y^2, y^3, x^2*z, x*y*z, y^2*z, x*z^2, y*z^2, z^3]
|
|
1464
|
+
|
|
1465
|
+
The number of such monomials equals `\binom{n+k-1}{k}`
|
|
1466
|
+
where `n` is the number of variables and `k` the degree::
|
|
1467
|
+
|
|
1468
|
+
sage: len(mons) == binomial(3 + 2 - 1, 2) # needs sage.combinat
|
|
1469
|
+
True
|
|
1470
|
+
"""
|
|
1471
|
+
deg_of_gens = [x.degree() for x in self.gens()]
|
|
1472
|
+
from sage.combinat.integer_vector_weighted import WeightedIntegerVectors
|
|
1473
|
+
mons = [self.monomial(*a) for a in WeightedIntegerVectors(degree, deg_of_gens)]
|
|
1474
|
+
mons.sort() # This could be implemented in WeightedIntegerVectors instead
|
|
1475
|
+
return mons
|
|
1476
|
+
|
|
1477
|
+
def _macaulay_resultant_getS(self, mon_deg_tuple, dlist):
|
|
1478
|
+
r"""
|
|
1479
|
+
In the Macaulay resultant algorithm the list of all monomials of the
|
|
1480
|
+
total degree is partitioned into sets `S_i`.
|
|
1481
|
+
This function returns the index `i` for the set `S_i` for the given
|
|
1482
|
+
monomial.
|
|
1483
|
+
|
|
1484
|
+
INPUT:
|
|
1485
|
+
|
|
1486
|
+
- ``mon_deg_tuple`` -- list representing a monomial of a degree `d`
|
|
1487
|
+
- ``dlist`` -- list of degrees `d_i` of the polynomials in
|
|
1488
|
+
question, where ``d = sum(dlist) - len(dlist) + 1``
|
|
1489
|
+
|
|
1490
|
+
OUTPUT: the index `i` such that the input monomial is in `S_i`
|
|
1491
|
+
|
|
1492
|
+
EXAMPLES::
|
|
1493
|
+
|
|
1494
|
+
sage: R.<x,y> = PolynomialRing(ZZ, 2)
|
|
1495
|
+
sage: R._macaulay_resultant_getS([1,1,0],[2,1,1]) # the monomial xy where the total degree = 2
|
|
1496
|
+
1
|
|
1497
|
+
|
|
1498
|
+
sage: R._macaulay_resultant_getS([29,21,8],[10,20,30])
|
|
1499
|
+
0
|
|
1500
|
+
|
|
1501
|
+
sage: R._macaulay_resultant_getS(list(range(9))+[10],list(range(1,11)))
|
|
1502
|
+
9
|
|
1503
|
+
"""
|
|
1504
|
+
for i in range(len(dlist)):
|
|
1505
|
+
if mon_deg_tuple[i] - dlist[i] >= 0:
|
|
1506
|
+
return i
|
|
1507
|
+
|
|
1508
|
+
def _macaulay_resultant_is_reduced(self, mon_degs, dlist) -> bool:
|
|
1509
|
+
r"""
|
|
1510
|
+
Helper function for the Macaulay resultant algorithm.
|
|
1511
|
+
|
|
1512
|
+
A monomial in the variables `x_0,...,x_n` is called reduced with
|
|
1513
|
+
respect to the list of degrees `d_0,...,d_n`
|
|
1514
|
+
if the degree of `x_i` in the monomial is `>= d_i` for exactly
|
|
1515
|
+
one `i`. This function checks this property for a monomial.
|
|
1516
|
+
|
|
1517
|
+
INPUT:
|
|
1518
|
+
|
|
1519
|
+
- ``mon_degs`` -- a monomial represented by a vector of degrees
|
|
1520
|
+
- ``dlist`` -- list of degrees with respect to which we check
|
|
1521
|
+
reducedness
|
|
1522
|
+
|
|
1523
|
+
OUTPUT: boolean
|
|
1524
|
+
|
|
1525
|
+
EXAMPLES:
|
|
1526
|
+
|
|
1527
|
+
The monomial x^2*y^3*z is not reduced w.r.t. degrees vector [2,3,3]::
|
|
1528
|
+
|
|
1529
|
+
sage: R.<x,y,z> = PolynomialRing(QQ,3)
|
|
1530
|
+
sage: R._macaulay_resultant_is_reduced([2,3,1],[2,3,3])
|
|
1531
|
+
False
|
|
1532
|
+
|
|
1533
|
+
The monomial x*y^3*z^2 is not reduced w.r.t. degrees vector [2,3,3]::
|
|
1534
|
+
|
|
1535
|
+
sage: R.<x,y,z> = PolynomialRing(QQ,3)
|
|
1536
|
+
sage: R._macaulay_resultant_is_reduced([1,3,2],[2,3,3])
|
|
1537
|
+
True
|
|
1538
|
+
"""
|
|
1539
|
+
diff = [True for mi, di in zip(mon_degs, dlist) if mi >= di]
|
|
1540
|
+
return len(diff) == 1
|
|
1541
|
+
|
|
1542
|
+
def _macaulay_resultant_universal_polynomials(self, dlist):
|
|
1543
|
+
r"""
|
|
1544
|
+
Given a list of degrees, this function returns a list of ``len(dlist)`` polynomials with ``len(dlist)`` variables,
|
|
1545
|
+
with generic coefficients. This is useful for generating polynomials for tests,
|
|
1546
|
+
and for getting a universal macaulay resultant for the given degrees.
|
|
1547
|
+
|
|
1548
|
+
INPUT:
|
|
1549
|
+
|
|
1550
|
+
- ``dlist`` -- list of degrees
|
|
1551
|
+
|
|
1552
|
+
OUTPUT:
|
|
1553
|
+
|
|
1554
|
+
- a list of polynomials of the given degrees with general coefficients.
|
|
1555
|
+
- a polynomial ring over ``self`` generated by the coefficients of the output polynomials.
|
|
1556
|
+
|
|
1557
|
+
EXAMPLES::
|
|
1558
|
+
|
|
1559
|
+
sage: R.<x,y> = PolynomialRing(ZZ, 2)
|
|
1560
|
+
sage: R._macaulay_resultant_universal_polynomials([1,1,2])
|
|
1561
|
+
([u0*x0 + u1*x1 + u2*x2, u3*x0 + u4*x1 + u5*x2, u6*x0^2 +
|
|
1562
|
+
u7*x0*x1 + u9*x1^2 + u8*x0*x2 + u10*x1*x2 + u11*x2^2],
|
|
1563
|
+
Multivariate Polynomial Ring in x0, x1, x2 over Multivariate
|
|
1564
|
+
Polynomial Ring in u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10,
|
|
1565
|
+
u11 over Integer Ring)
|
|
1566
|
+
"""
|
|
1567
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
1568
|
+
|
|
1569
|
+
n = len(dlist) - 1
|
|
1570
|
+
number_of_coeffs = sum([binomial(n + di, di) for di in dlist])
|
|
1571
|
+
U = PolynomialRing(ZZ, 'u', number_of_coeffs)
|
|
1572
|
+
d = sum(dlist) - len(dlist) + 1
|
|
1573
|
+
flist = []
|
|
1574
|
+
R = PolynomialRing(U, 'x', n + 1)
|
|
1575
|
+
ulist = U.gens()
|
|
1576
|
+
for d in dlist:
|
|
1577
|
+
xlist = R.gens()
|
|
1578
|
+
degs = IntegerVectors(d, n + 1)
|
|
1579
|
+
mon_d = [prod([xlist[i]**(deg[i]) for i in range(len(deg))])
|
|
1580
|
+
for deg in degs]
|
|
1581
|
+
|
|
1582
|
+
f = sum([mon_d[i] * ulist[i] for i in range(len(mon_d))])
|
|
1583
|
+
flist.append(f)
|
|
1584
|
+
ulist = ulist[len(mon_d):]
|
|
1585
|
+
return flist, R
|
|
1586
|
+
|
|
1587
|
+
def macaulay_resultant(self, *args, **kwds):
|
|
1588
|
+
r"""
|
|
1589
|
+
Return the Macaulay resultant.
|
|
1590
|
+
|
|
1591
|
+
This computes the resultant of universal polynomials as well as
|
|
1592
|
+
polynomials with constant coefficients. This is a project done
|
|
1593
|
+
in sage days 55. It is based on the implementation in Maple by
|
|
1594
|
+
Manfred Minimair, which in turn is based on the references
|
|
1595
|
+
listed below. It calculates the Macaulay resultant for a list
|
|
1596
|
+
of polynomials, up to sign!
|
|
1597
|
+
|
|
1598
|
+
REFERENCES:
|
|
1599
|
+
|
|
1600
|
+
- [CLO2005]_
|
|
1601
|
+
|
|
1602
|
+
- [Can1990]_
|
|
1603
|
+
|
|
1604
|
+
- [Mac1916]_
|
|
1605
|
+
|
|
1606
|
+
AUTHORS:
|
|
1607
|
+
|
|
1608
|
+
- Hao Chen, Solomon Vishkautsan (7-2014)
|
|
1609
|
+
|
|
1610
|
+
INPUT:
|
|
1611
|
+
|
|
1612
|
+
- ``args`` -- list of `n` homogeneous polynomials in `n` variables
|
|
1613
|
+
works when ``args[0]`` is the list of polynomials,
|
|
1614
|
+
or ``args`` is itself the list of polynomials
|
|
1615
|
+
|
|
1616
|
+
kwds:
|
|
1617
|
+
|
|
1618
|
+
- ``sparse`` -- boolean (default: ``False``); if ``True``, the function
|
|
1619
|
+
creates sparse matrices
|
|
1620
|
+
|
|
1621
|
+
OUTPUT: the Macaulay resultant, an element of the base ring of ``self``
|
|
1622
|
+
|
|
1623
|
+
.. TODO::
|
|
1624
|
+
|
|
1625
|
+
Working with sparse matrices should usually give faster results,
|
|
1626
|
+
but with the current implementation it actually works slower.
|
|
1627
|
+
There should be a way to improve performance with regards to this.
|
|
1628
|
+
|
|
1629
|
+
EXAMPLES:
|
|
1630
|
+
|
|
1631
|
+
The number of polynomials has to match the number of variables::
|
|
1632
|
+
|
|
1633
|
+
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
|
|
1634
|
+
sage: R.macaulay_resultant([y, x + z]) # needs sage.modules
|
|
1635
|
+
Traceback (most recent call last):
|
|
1636
|
+
...
|
|
1637
|
+
TypeError: number of polynomials(= 2) must equal number of variables (= 3)
|
|
1638
|
+
|
|
1639
|
+
The polynomials need to be all homogeneous::
|
|
1640
|
+
|
|
1641
|
+
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
|
|
1642
|
+
sage: R.macaulay_resultant([y, x + z, z + x^3]) # needs sage.modules
|
|
1643
|
+
Traceback (most recent call last):
|
|
1644
|
+
...
|
|
1645
|
+
TypeError: resultant for non-homogeneous polynomials is not supported
|
|
1646
|
+
|
|
1647
|
+
All polynomials must be in the same ring::
|
|
1648
|
+
|
|
1649
|
+
sage: S.<x,y> = PolynomialRing(QQ, 2)
|
|
1650
|
+
sage: R.<x,y,z> = PolynomialRing(QQ,3)
|
|
1651
|
+
sage: S.macaulay_resultant([y, z+x]) # needs sage.modules
|
|
1652
|
+
Traceback (most recent call last):
|
|
1653
|
+
...
|
|
1654
|
+
TypeError: not all inputs are polynomials in the calling ring
|
|
1655
|
+
|
|
1656
|
+
The following example recreates Proposition 2.10 in Ch.3 in [CLO2005]::
|
|
1657
|
+
|
|
1658
|
+
sage: K.<x,y> = PolynomialRing(ZZ, 2)
|
|
1659
|
+
sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,2])
|
|
1660
|
+
sage: R.macaulay_resultant(flist) # needs sage.modules
|
|
1661
|
+
u2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 +
|
|
1662
|
+
u1*u2*u3*u5*u7 + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 -
|
|
1663
|
+
u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 -
|
|
1664
|
+
2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9 - u1*u2*u3^2*u10 +
|
|
1665
|
+
u0*u2*u3*u4*u10 + u0*u1*u3*u5*u10 - u0^2*u4*u5*u10 +
|
|
1666
|
+
u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11
|
|
1667
|
+
|
|
1668
|
+
The following example degenerates into the determinant of
|
|
1669
|
+
a `3\times 3` matrix::
|
|
1670
|
+
|
|
1671
|
+
sage: K.<x,y> = PolynomialRing(ZZ, 2)
|
|
1672
|
+
sage: flist,R = K._macaulay_resultant_universal_polynomials([1,1,1])
|
|
1673
|
+
sage: R.macaulay_resultant(flist) # needs sage.modules
|
|
1674
|
+
-u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8
|
|
1675
|
+
|
|
1676
|
+
The following example is by Patrick Ingram (:arxiv:`1310.4114`)::
|
|
1677
|
+
|
|
1678
|
+
sage: U = PolynomialRing(ZZ,'y',2); y0,y1 = U.gens()
|
|
1679
|
+
sage: R = PolynomialRing(U,'x',3); x0,x1,x2 = R.gens()
|
|
1680
|
+
sage: f0 = y0*x2^2 - x0^2 + 2*x1*x2
|
|
1681
|
+
sage: f1 = y1*x2^2 - x1^2 + 2*x0*x2
|
|
1682
|
+
sage: f2 = x0*x1 - x2^2
|
|
1683
|
+
sage: flist = [f0,f1,f2]
|
|
1684
|
+
sage: R.macaulay_resultant([f0,f1,f2]) # needs sage.modules
|
|
1685
|
+
y0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27
|
|
1686
|
+
|
|
1687
|
+
A simple example with constant rational coefficients::
|
|
1688
|
+
|
|
1689
|
+
sage: R.<x,y,z,w> = PolynomialRing(QQ, 4)
|
|
1690
|
+
sage: R.macaulay_resultant([w, z, y, x]) # needs sage.modules
|
|
1691
|
+
1
|
|
1692
|
+
|
|
1693
|
+
An example where the resultant vanishes::
|
|
1694
|
+
|
|
1695
|
+
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
|
|
1696
|
+
sage: R.macaulay_resultant([x + y, y^2, x]) # needs sage.modules
|
|
1697
|
+
0
|
|
1698
|
+
|
|
1699
|
+
An example of bad reduction at a prime `p = 5`::
|
|
1700
|
+
|
|
1701
|
+
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
|
|
1702
|
+
sage: R.macaulay_resultant([y, x^3 + 25*y^2*x, 5*z]) # needs sage.libs.pari sage.modules
|
|
1703
|
+
125
|
|
1704
|
+
|
|
1705
|
+
The input can given as an unpacked list of polynomials::
|
|
1706
|
+
|
|
1707
|
+
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
|
|
1708
|
+
sage: R.macaulay_resultant(y, x^3 + 25*y^2*x, 5*z) # needs sage.libs.pari sage.modules
|
|
1709
|
+
125
|
|
1710
|
+
|
|
1711
|
+
An example when the coefficients live in a finite field::
|
|
1712
|
+
|
|
1713
|
+
sage: F = FiniteField(11)
|
|
1714
|
+
sage: R.<x,y,z,w> = PolynomialRing(F, 4)
|
|
1715
|
+
sage: R.macaulay_resultant([z, x^3, 5*y, w]) # needs sage.modules sage.rings.finite_rings
|
|
1716
|
+
4
|
|
1717
|
+
|
|
1718
|
+
Example when the denominator in the algorithm vanishes(in this case
|
|
1719
|
+
the resultant is the constant term of the quotient of
|
|
1720
|
+
char polynomials of numerator/denominator)::
|
|
1721
|
+
|
|
1722
|
+
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
|
|
1723
|
+
sage: R.macaulay_resultant([y, x + z, z^2]) # needs sage.libs.pari sage.modules
|
|
1724
|
+
-1
|
|
1725
|
+
|
|
1726
|
+
When there are only 2 polynomials, the Macaulay resultant degenerates
|
|
1727
|
+
to the traditional resultant::
|
|
1728
|
+
|
|
1729
|
+
sage: R.<x> = PolynomialRing(QQ, 1)
|
|
1730
|
+
sage: f = x^2 + 1; g = x^5 + 1
|
|
1731
|
+
sage: fh = f.homogenize()
|
|
1732
|
+
sage: gh = g.homogenize()
|
|
1733
|
+
sage: RH = fh.parent()
|
|
1734
|
+
sage: f.resultant(g) == RH.macaulay_resultant([fh, gh]) # needs sage.modules
|
|
1735
|
+
True
|
|
1736
|
+
"""
|
|
1737
|
+
from sage.matrix.constructor import matrix
|
|
1738
|
+
from sage.matrix.constructor import zero_matrix
|
|
1739
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
1740
|
+
|
|
1741
|
+
if len(args) == 1 and isinstance(args[0], list):
|
|
1742
|
+
flist = args[0]
|
|
1743
|
+
else:
|
|
1744
|
+
flist = args
|
|
1745
|
+
|
|
1746
|
+
if len(flist) == 0:
|
|
1747
|
+
raise TypeError('input list should contain at least 1 polynomial')
|
|
1748
|
+
if not all(f.is_homogeneous() for f in flist):
|
|
1749
|
+
raise TypeError('resultant for non-homogeneous polynomials is not supported')
|
|
1750
|
+
if not all(self.is_parent_of(f) for f in flist):
|
|
1751
|
+
raise TypeError('not all inputs are polynomials in the calling ring')
|
|
1752
|
+
|
|
1753
|
+
sparse = kwds.pop('sparse', False)
|
|
1754
|
+
|
|
1755
|
+
U = self.base_ring() # ring of coefficients of self
|
|
1756
|
+
dlist = [f.degree() for f in flist]
|
|
1757
|
+
xlist = self.gens()
|
|
1758
|
+
if len(xlist) != len(dlist):
|
|
1759
|
+
raise TypeError('number of polynomials(= %d) must equal number of variables (= %d)' % (len(dlist), len(xlist)))
|
|
1760
|
+
n = len(dlist) - 1
|
|
1761
|
+
d = sum(dlist) - len(dlist) + 1
|
|
1762
|
+
# list of exponent-vectors(/lists) of monomials of degree d:
|
|
1763
|
+
mons = IntegerVectors(d, n + 1).list()
|
|
1764
|
+
# a reverse index lookup for monomials:
|
|
1765
|
+
mons_idx = {str(mon): idx for idx, mon in enumerate(mons)}
|
|
1766
|
+
mons_num = len(mons)
|
|
1767
|
+
mons_to_keep = []
|
|
1768
|
+
# strip coefficients of the input polynomials:
|
|
1769
|
+
flist = [[f.exponents(), f.coefficients()] for f in flist]
|
|
1770
|
+
numer_matrix = zero_matrix(self.base_ring(), mons_num, sparse=sparse)
|
|
1771
|
+
|
|
1772
|
+
for j, mon in enumerate(mons):
|
|
1773
|
+
# if monomial is not reduced, then we keep it in the
|
|
1774
|
+
# denominator matrix:
|
|
1775
|
+
if not self._macaulay_resultant_is_reduced(mon, dlist):
|
|
1776
|
+
mons_to_keep.append(j)
|
|
1777
|
+
si_mon = self._macaulay_resultant_getS(mon, dlist)
|
|
1778
|
+
# Monomial is in S_i under the partition, now we reduce
|
|
1779
|
+
# the i'th degree of the monomial
|
|
1780
|
+
new_mon = list(mon)
|
|
1781
|
+
new_mon[si_mon] -= dlist[si_mon]
|
|
1782
|
+
new_f = [[[g[k] + new_mon[k] for k in range(n + 1)]
|
|
1783
|
+
for g in flist[si_mon][0]], flist[si_mon][1]]
|
|
1784
|
+
|
|
1785
|
+
for i, mon in enumerate(new_f[0]):
|
|
1786
|
+
k = mons_idx[str(mon)]
|
|
1787
|
+
numer_matrix[j, k] = new_f[1][i]
|
|
1788
|
+
|
|
1789
|
+
denom_matrix = numer_matrix.matrix_from_rows_and_columns(mons_to_keep,
|
|
1790
|
+
mons_to_keep)
|
|
1791
|
+
# here we choose the determinant of an empty matrix to be 1
|
|
1792
|
+
if denom_matrix.dimensions()[0] == 0:
|
|
1793
|
+
return U(numer_matrix.det())
|
|
1794
|
+
denom_det = denom_matrix.det()
|
|
1795
|
+
if denom_det != 0:
|
|
1796
|
+
return U(numer_matrix.det() / denom_det)
|
|
1797
|
+
# if we get to this point, the determinant of the denominator
|
|
1798
|
+
# was 0, and we get the resultant by taking the free
|
|
1799
|
+
# coefficient of the quotient of two characteristic
|
|
1800
|
+
# polynomials
|
|
1801
|
+
poly_num = numer_matrix.characteristic_polynomial('T')
|
|
1802
|
+
poly_denom = denom_matrix.characteristic_polynomial('T')
|
|
1803
|
+
poly_quo = poly_num.quo_rem(poly_denom)[0]
|
|
1804
|
+
return U(poly_quo(0))
|
|
1805
|
+
|
|
1806
|
+
def weyl_algebra(self):
|
|
1807
|
+
"""
|
|
1808
|
+
Return the Weyl algebra generated from ``self``.
|
|
1809
|
+
|
|
1810
|
+
EXAMPLES::
|
|
1811
|
+
|
|
1812
|
+
sage: R = QQ['x,y,z']
|
|
1813
|
+
sage: W = R.weyl_algebra(); W # needs sage.modules
|
|
1814
|
+
Differential Weyl algebra of polynomials in x, y, z over Rational Field
|
|
1815
|
+
sage: W.polynomial_ring() == R # needs sage.modules
|
|
1816
|
+
True
|
|
1817
|
+
"""
|
|
1818
|
+
from sage.algebras.weyl_algebra import DifferentialWeylAlgebra
|
|
1819
|
+
return DifferentialWeylAlgebra(self)
|
|
1820
|
+
|
|
1821
|
+
|
|
1822
|
+
cdef class BooleanPolynomialRing_base(MPolynomialRing_base):
|
|
1823
|
+
r"""
|
|
1824
|
+
Abstract base class for :class:`~sage.rings.polynomial.pbori.pbori.BooleanPolynomialRing`.
|
|
1825
|
+
|
|
1826
|
+
This class is defined for the purpose of ``isinstance`` tests. It should not be
|
|
1827
|
+
instantiated.
|
|
1828
|
+
|
|
1829
|
+
EXAMPLES::
|
|
1830
|
+
|
|
1831
|
+
sage: from sage.rings.polynomial.multi_polynomial_ring_base import BooleanPolynomialRing_base
|
|
1832
|
+
sage: R.<x, y, z> = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori
|
|
1833
|
+
sage: isinstance(R, BooleanPolynomialRing_base) # needs sage.rings.polynomial.pbori
|
|
1834
|
+
True
|
|
1835
|
+
|
|
1836
|
+
By design, there is only one direct implementation subclass::
|
|
1837
|
+
|
|
1838
|
+
sage: len(BooleanPolynomialRing_base.__subclasses__()) <= 1
|
|
1839
|
+
True
|
|
1840
|
+
"""
|
|
1841
|
+
pass
|
|
1842
|
+
|
|
1843
|
+
|
|
1844
|
+
####################
|
|
1845
|
+
# Leave *all* old versions!
|
|
1846
|
+
|
|
1847
|
+
def unpickle_MPolynomialRing_generic_v1(base_ring, n, names, order):
|
|
1848
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1849
|
+
return PolynomialRing(base_ring, n, names=names, order=order)
|
|
1850
|
+
|
|
1851
|
+
|
|
1852
|
+
def unpickle_MPolynomialRing_generic(base_ring, n, names, order):
|
|
1853
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1854
|
+
|
|
1855
|
+
return PolynomialRing(base_ring, n, names=names, order=order)
|