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,1452 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Fraction Field of Integral Domains
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- William Stein (with input from David Joyner, David Kohel, and Joe
|
|
8
|
+
Wetherell)
|
|
9
|
+
|
|
10
|
+
- Burcin Erocal
|
|
11
|
+
|
|
12
|
+
- Julian Rüth (2017-06-27): embedding into the field of fractions and its
|
|
13
|
+
section
|
|
14
|
+
|
|
15
|
+
EXAMPLES:
|
|
16
|
+
|
|
17
|
+
Quotienting is a constructor for an element of the fraction field::
|
|
18
|
+
|
|
19
|
+
sage: R.<x> = QQ[]
|
|
20
|
+
sage: (x^2-1)/(x+1)
|
|
21
|
+
x - 1
|
|
22
|
+
sage: parent((x^2-1)/(x+1))
|
|
23
|
+
Fraction Field of Univariate Polynomial Ring in x over Rational Field
|
|
24
|
+
|
|
25
|
+
The GCD is not taken (since it doesn't converge sometimes) in the
|
|
26
|
+
inexact case::
|
|
27
|
+
|
|
28
|
+
sage: # needs sage.rings.real_mpfr
|
|
29
|
+
sage: Z.<z> = CC[]
|
|
30
|
+
sage: I = CC.gen()
|
|
31
|
+
sage: (1+I+z)/(z+0.1*I)
|
|
32
|
+
(z + 1.00000000000000 + I)/(z + 0.100000000000000*I)
|
|
33
|
+
sage: (1+I*z)/(z+1.1)
|
|
34
|
+
(I*z + 1.00000000000000)/(z + 1.10000000000000)
|
|
35
|
+
|
|
36
|
+
TESTS::
|
|
37
|
+
|
|
38
|
+
sage: F = FractionField(IntegerRing())
|
|
39
|
+
sage: F == loads(dumps(F))
|
|
40
|
+
True
|
|
41
|
+
|
|
42
|
+
::
|
|
43
|
+
|
|
44
|
+
sage: F = FractionField(PolynomialRing(RationalField(),'x'))
|
|
45
|
+
sage: F == loads(dumps(F))
|
|
46
|
+
True
|
|
47
|
+
|
|
48
|
+
::
|
|
49
|
+
|
|
50
|
+
sage: F = FractionField(PolynomialRing(IntegerRing(),'x'))
|
|
51
|
+
sage: F == loads(dumps(F))
|
|
52
|
+
True
|
|
53
|
+
|
|
54
|
+
::
|
|
55
|
+
|
|
56
|
+
sage: F = FractionField(PolynomialRing(RationalField(),2,'x'))
|
|
57
|
+
sage: F == loads(dumps(F))
|
|
58
|
+
True
|
|
59
|
+
|
|
60
|
+
Test that :issue:`15971` is fixed::
|
|
61
|
+
|
|
62
|
+
sage: # needs sage.libs.singular
|
|
63
|
+
sage: for B in [QQ['t'], QQ['s, t'], ZZ['t'], ZZ['s, t']]:
|
|
64
|
+
....: F = B.fraction_field()
|
|
65
|
+
....: R = F['x, y']
|
|
66
|
+
....: x = R.gen(0)
|
|
67
|
+
....: print(x / x)
|
|
68
|
+
1
|
|
69
|
+
1
|
|
70
|
+
1
|
|
71
|
+
1
|
|
72
|
+
"""
|
|
73
|
+
# ****************************************************************************
|
|
74
|
+
#
|
|
75
|
+
# Sage: Open Source Mathematical Software
|
|
76
|
+
#
|
|
77
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
78
|
+
# 2017 Julian Rüth <julian.rueth@fsfe.org>
|
|
79
|
+
#
|
|
80
|
+
# This program is free software: you can redistribute it and/or modify
|
|
81
|
+
# it under the terms of the GNU General Public License as published by
|
|
82
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
83
|
+
# (at your option) any later version.
|
|
84
|
+
# https://www.gnu.org/licenses/
|
|
85
|
+
# ****************************************************************************
|
|
86
|
+
|
|
87
|
+
import sage.misc.latex as latex
|
|
88
|
+
from sage.categories.basic import QuotientFields, Rings
|
|
89
|
+
from sage.categories.map import Section
|
|
90
|
+
from sage.misc.cachefunc import cached_method
|
|
91
|
+
from sage.rings import fraction_field_element, ring
|
|
92
|
+
from sage.rings.integer_ring import ZZ
|
|
93
|
+
from sage.structure.coerce import py_scalar_to_element
|
|
94
|
+
from sage.structure.coerce_maps import CallableConvertMap, DefaultConvertMap_unique
|
|
95
|
+
from sage.structure.element import parent
|
|
96
|
+
from sage.structure.parent import Parent
|
|
97
|
+
from sage.structure.richcmp import richcmp
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def FractionField(R, names=None):
|
|
101
|
+
"""
|
|
102
|
+
Create the fraction field of the integral domain ``R``.
|
|
103
|
+
|
|
104
|
+
INPUT:
|
|
105
|
+
|
|
106
|
+
- ``R`` -- an integral domain
|
|
107
|
+
|
|
108
|
+
- ``names`` -- ignored
|
|
109
|
+
|
|
110
|
+
EXAMPLES:
|
|
111
|
+
|
|
112
|
+
We create some example fraction fields::
|
|
113
|
+
|
|
114
|
+
sage: FractionField(IntegerRing())
|
|
115
|
+
Rational Field
|
|
116
|
+
sage: FractionField(PolynomialRing(RationalField(),'x'))
|
|
117
|
+
Fraction Field of Univariate Polynomial Ring in x over Rational Field
|
|
118
|
+
sage: FractionField(PolynomialRing(IntegerRing(),'x'))
|
|
119
|
+
Fraction Field of Univariate Polynomial Ring in x over Integer Ring
|
|
120
|
+
sage: FractionField(PolynomialRing(RationalField(),2,'x'))
|
|
121
|
+
Fraction Field of Multivariate Polynomial Ring in x0, x1 over Rational Field
|
|
122
|
+
|
|
123
|
+
Dividing elements often implicitly creates elements of the fraction
|
|
124
|
+
field::
|
|
125
|
+
|
|
126
|
+
sage: x = PolynomialRing(RationalField(), 'x').gen()
|
|
127
|
+
sage: f = x/(x+1)
|
|
128
|
+
sage: g = x**3/(x+1)
|
|
129
|
+
sage: f/g
|
|
130
|
+
1/x^2
|
|
131
|
+
sage: g/f
|
|
132
|
+
x^2
|
|
133
|
+
|
|
134
|
+
The input must be an integral domain::
|
|
135
|
+
|
|
136
|
+
sage: Frac(Integers(4))
|
|
137
|
+
Traceback (most recent call last):
|
|
138
|
+
...
|
|
139
|
+
TypeError: R must be an integral domain
|
|
140
|
+
"""
|
|
141
|
+
if R not in Rings():
|
|
142
|
+
raise TypeError("R must be a ring")
|
|
143
|
+
if not R.is_integral_domain():
|
|
144
|
+
raise TypeError("R must be an integral domain")
|
|
145
|
+
return R.fraction_field()
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def is_FractionField(x) -> bool:
|
|
149
|
+
"""
|
|
150
|
+
Test whether or not ``x`` inherits from :class:`FractionField_generic`.
|
|
151
|
+
|
|
152
|
+
EXAMPLES::
|
|
153
|
+
|
|
154
|
+
sage: from sage.rings.fraction_field import is_FractionField
|
|
155
|
+
sage: is_FractionField(Frac(ZZ['x']))
|
|
156
|
+
doctest:warning...
|
|
157
|
+
DeprecationWarning: The function is_FractionField is deprecated;
|
|
158
|
+
use 'isinstance(..., FractionField_generic)' instead.
|
|
159
|
+
See https://github.com/sagemath/sage/issues/38128 for details.
|
|
160
|
+
True
|
|
161
|
+
sage: is_FractionField(QQ)
|
|
162
|
+
False
|
|
163
|
+
"""
|
|
164
|
+
from sage.misc.superseded import deprecation
|
|
165
|
+
deprecation(38128,
|
|
166
|
+
"The function is_FractionField is deprecated; "
|
|
167
|
+
"use 'isinstance(..., FractionField_generic)' instead.")
|
|
168
|
+
return isinstance(x, FractionField_generic)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class FractionField_generic(ring.Field):
|
|
172
|
+
"""
|
|
173
|
+
The fraction field of an integral domain.
|
|
174
|
+
"""
|
|
175
|
+
def __init__(self, R,
|
|
176
|
+
element_class=fraction_field_element.FractionFieldElement,
|
|
177
|
+
category=QuotientFields()):
|
|
178
|
+
"""
|
|
179
|
+
Create the fraction field of the integral domain ``R``.
|
|
180
|
+
|
|
181
|
+
INPUT:
|
|
182
|
+
|
|
183
|
+
- ``R`` -- an integral domain
|
|
184
|
+
|
|
185
|
+
EXAMPLES::
|
|
186
|
+
|
|
187
|
+
sage: Frac(QQ['x'])
|
|
188
|
+
Fraction Field of Univariate Polynomial Ring in x over Rational Field
|
|
189
|
+
sage: Frac(QQ['x,y']).variable_names()
|
|
190
|
+
('x', 'y')
|
|
191
|
+
sage: category(Frac(QQ['x']))
|
|
192
|
+
Category of infinite quotient fields
|
|
193
|
+
|
|
194
|
+
TESTS::
|
|
195
|
+
|
|
196
|
+
sage: F = FractionField(QQ['x'])
|
|
197
|
+
sage: F.cardinality()
|
|
198
|
+
+Infinity
|
|
199
|
+
"""
|
|
200
|
+
self._R = R
|
|
201
|
+
self._element_class = element_class
|
|
202
|
+
cat = category
|
|
203
|
+
if R in Rings().Infinite():
|
|
204
|
+
cat = cat.Infinite()
|
|
205
|
+
elif R in Rings().Finite():
|
|
206
|
+
cat = cat.Finite()
|
|
207
|
+
Parent.__init__(self, base=R, names=R._names, category=cat)
|
|
208
|
+
|
|
209
|
+
def __reduce__(self):
|
|
210
|
+
"""
|
|
211
|
+
For pickling.
|
|
212
|
+
|
|
213
|
+
TESTS::
|
|
214
|
+
|
|
215
|
+
sage: K = Frac(QQ['x'])
|
|
216
|
+
sage: loads(dumps(K)) is K
|
|
217
|
+
True
|
|
218
|
+
"""
|
|
219
|
+
return FractionField, (self._R,)
|
|
220
|
+
|
|
221
|
+
def _coerce_map_from_(self, S):
|
|
222
|
+
"""
|
|
223
|
+
Return ``True`` if elements of ``S`` can be coerced into this
|
|
224
|
+
fraction field.
|
|
225
|
+
|
|
226
|
+
This fraction field has coercions from:
|
|
227
|
+
|
|
228
|
+
- itself
|
|
229
|
+
- any fraction field where the base ring coerces to the base
|
|
230
|
+
ring of this fraction field
|
|
231
|
+
- any ring that coerces to the base ring of this fraction field
|
|
232
|
+
|
|
233
|
+
EXAMPLES::
|
|
234
|
+
|
|
235
|
+
sage: F = QQ['x,y'].fraction_field()
|
|
236
|
+
sage: F.has_coerce_map_from(F) # indirect doctest
|
|
237
|
+
True
|
|
238
|
+
|
|
239
|
+
::
|
|
240
|
+
|
|
241
|
+
sage: F.has_coerce_map_from(ZZ['x,y'].fraction_field())
|
|
242
|
+
True
|
|
243
|
+
|
|
244
|
+
::
|
|
245
|
+
|
|
246
|
+
sage: F.has_coerce_map_from(ZZ['x,y,z'].fraction_field())
|
|
247
|
+
False
|
|
248
|
+
|
|
249
|
+
::
|
|
250
|
+
|
|
251
|
+
sage: F.has_coerce_map_from(ZZ)
|
|
252
|
+
True
|
|
253
|
+
|
|
254
|
+
Test coercions::
|
|
255
|
+
|
|
256
|
+
sage: # needs sage.libs.singular
|
|
257
|
+
sage: F.coerce(1)
|
|
258
|
+
1
|
|
259
|
+
sage: F.coerce(int(1))
|
|
260
|
+
1
|
|
261
|
+
sage: F.coerce(1/2)
|
|
262
|
+
1/2
|
|
263
|
+
|
|
264
|
+
::
|
|
265
|
+
|
|
266
|
+
sage: # needs sage.libs.singular
|
|
267
|
+
sage: K = ZZ['x,y'].fraction_field()
|
|
268
|
+
sage: x,y = K.gens()
|
|
269
|
+
sage: F.coerce(F.gen())
|
|
270
|
+
x
|
|
271
|
+
sage: F.coerce(x)
|
|
272
|
+
x
|
|
273
|
+
sage: F.coerce(x/y)
|
|
274
|
+
x/y
|
|
275
|
+
sage: L = ZZ['x'].fraction_field()
|
|
276
|
+
sage: K.coerce(L.gen())
|
|
277
|
+
x
|
|
278
|
+
|
|
279
|
+
We demonstrate that :issue:`7958` is resolved in the case of
|
|
280
|
+
number fields::
|
|
281
|
+
|
|
282
|
+
sage: # needs sage.rings.number_field
|
|
283
|
+
sage: _.<x> = ZZ[]
|
|
284
|
+
sage: K.<a> = NumberField(x^5 - 3*x^4 + 2424*x^3 + 2*x - 232)
|
|
285
|
+
sage: R = K.ring_of_integers()
|
|
286
|
+
sage: S.<y> = R[]
|
|
287
|
+
sage: F = FractionField(S)
|
|
288
|
+
sage: F(1/a)
|
|
289
|
+
(a^4 - 3*a^3 + 2424*a^2 + 2)/232
|
|
290
|
+
|
|
291
|
+
Some corner cases have been known to fail in the past (:issue:`5917`)::
|
|
292
|
+
|
|
293
|
+
sage: F1 = FractionField( QQ['a'] )
|
|
294
|
+
sage: R12 = F1['x','y']
|
|
295
|
+
sage: R12('a')
|
|
296
|
+
a
|
|
297
|
+
sage: F1(R12(F1('a')))
|
|
298
|
+
a
|
|
299
|
+
|
|
300
|
+
sage: # needs sage.libs.singular
|
|
301
|
+
sage: F2 = FractionField( QQ['a','b'] )
|
|
302
|
+
sage: R22 = F2['x','y']
|
|
303
|
+
sage: R22('a')
|
|
304
|
+
a
|
|
305
|
+
sage: F2(R22(F2('a')))
|
|
306
|
+
a
|
|
307
|
+
|
|
308
|
+
Coercion from Laurent polynomials now works (:issue:`15345`)::
|
|
309
|
+
|
|
310
|
+
sage: R = LaurentPolynomialRing(ZZ, 'x')
|
|
311
|
+
sage: T = PolynomialRing(ZZ, 'x')
|
|
312
|
+
sage: R.gen() + FractionField(T).gen()
|
|
313
|
+
2*x
|
|
314
|
+
sage: 1/(R.gen() + 1)
|
|
315
|
+
1/(x + 1)
|
|
316
|
+
|
|
317
|
+
sage: # needs sage.modules
|
|
318
|
+
sage: R = LaurentPolynomialRing(ZZ, 'x,y')
|
|
319
|
+
sage: FF = FractionField(PolynomialRing(ZZ, 'x,y'))
|
|
320
|
+
sage: prod(R.gens()) + prod(FF.gens())
|
|
321
|
+
2*x*y
|
|
322
|
+
sage: 1/(R.gen(0) + R.gen(1))
|
|
323
|
+
1/(x + y)
|
|
324
|
+
|
|
325
|
+
Test for :issue:`31320`::
|
|
326
|
+
|
|
327
|
+
sage: FQt = Frac(QQ['t'])
|
|
328
|
+
sage: LCt = LaurentPolynomialRing(CC,'t') # needs sage.rings.real_mpfr
|
|
329
|
+
sage: coercion_model.common_parent(FQt, LCt) # needs sage.rings.real_mpfr
|
|
330
|
+
Fraction Field of Univariate Polynomial Ring in t
|
|
331
|
+
over Complex Field with 53 bits of precision
|
|
332
|
+
|
|
333
|
+
Coercion from a localization::
|
|
334
|
+
|
|
335
|
+
sage: # needs sage.libs.pari
|
|
336
|
+
sage: R.<x> = ZZ[]
|
|
337
|
+
sage: L = Localization(R, (x**2 + 1,7))
|
|
338
|
+
sage: F = L.fraction_field()
|
|
339
|
+
sage: f = F.coerce_map_from(L); f
|
|
340
|
+
Coercion map:
|
|
341
|
+
From: Univariate Polynomial Ring in x over Integer Ring localized at (7, x^2 + 1)
|
|
342
|
+
To: Fraction Field of Univariate Polynomial Ring in x over Integer Ring
|
|
343
|
+
sage: f(L(1/7)) == 1/7
|
|
344
|
+
True
|
|
345
|
+
"""
|
|
346
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
347
|
+
from sage.rings.polynomial.laurent_polynomial_ring_base import (
|
|
348
|
+
LaurentPolynomialRing_generic,
|
|
349
|
+
)
|
|
350
|
+
from sage.rings.rational_field import QQ
|
|
351
|
+
|
|
352
|
+
if S is self._R:
|
|
353
|
+
parent = self._R.Hom(self)
|
|
354
|
+
return parent.__make_element_class__(FractionFieldEmbedding)(self._R, self, category=parent.homset_category())
|
|
355
|
+
|
|
356
|
+
def wrapper(x):
|
|
357
|
+
return self._element_class(self, x.numerator(), x.denominator())
|
|
358
|
+
|
|
359
|
+
# The case ``S`` being `\QQ` requires special handling since `\QQ` is
|
|
360
|
+
# not implemented as a ``FractionField_generic``.
|
|
361
|
+
if S is QQ and self._R.has_coerce_map_from(ZZ):
|
|
362
|
+
return CallableConvertMap(S, self, wrapper, parent_as_first_arg=False)
|
|
363
|
+
|
|
364
|
+
# special treatment for localizations
|
|
365
|
+
from sage.rings.localization import Localization
|
|
366
|
+
if isinstance(S, Localization):
|
|
367
|
+
parent = S.Hom(self)
|
|
368
|
+
return parent.__make_element_class__(FractionFieldEmbedding)(S, self, category=parent.homset_category())
|
|
369
|
+
|
|
370
|
+
# Number fields also need to be handled separately.
|
|
371
|
+
if isinstance(S, NumberField):
|
|
372
|
+
return CallableConvertMap(S, self,
|
|
373
|
+
self._number_field_to_frac_of_ring_of_integers,
|
|
374
|
+
parent_as_first_arg=False)
|
|
375
|
+
|
|
376
|
+
# special treatment for LaurentPolynomialRings
|
|
377
|
+
if (isinstance(S, LaurentPolynomialRing_generic) and
|
|
378
|
+
self._R.fraction_field().has_coerce_map_from(S.base_ring())):
|
|
379
|
+
|
|
380
|
+
def converter(x, y=None):
|
|
381
|
+
if y is None:
|
|
382
|
+
return self._element_class(self, *x._fraction_pair())
|
|
383
|
+
xnum, xden = x._fraction_pair()
|
|
384
|
+
ynum, yden = y._fraction_pair()
|
|
385
|
+
return self._element_class(self, xnum * yden, xden * ynum)
|
|
386
|
+
return CallableConvertMap(S, self, converter, parent_as_first_arg=False)
|
|
387
|
+
|
|
388
|
+
if (isinstance(S, FractionField_generic) and
|
|
389
|
+
self._R.has_coerce_map_from(S.ring())):
|
|
390
|
+
return CallableConvertMap(S, self, wrapper, parent_as_first_arg=False)
|
|
391
|
+
|
|
392
|
+
if self._R.has_coerce_map_from(S):
|
|
393
|
+
return CallableConvertMap(S, self, self._element_class,
|
|
394
|
+
parent_as_first_arg=True)
|
|
395
|
+
|
|
396
|
+
return None
|
|
397
|
+
|
|
398
|
+
def _number_field_to_frac_of_ring_of_integers(self, x):
|
|
399
|
+
r"""
|
|
400
|
+
Return the number field element ``x`` as an element of ``self``,
|
|
401
|
+
explicitly treating the numerator of ``x`` as an element of the ring
|
|
402
|
+
of integers and the denominator as an integer.
|
|
403
|
+
|
|
404
|
+
INPUT:
|
|
405
|
+
|
|
406
|
+
- ``x`` -- number field element
|
|
407
|
+
|
|
408
|
+
OUTPUT: Element of ``self``
|
|
409
|
+
|
|
410
|
+
TESTS:
|
|
411
|
+
|
|
412
|
+
We demonstrate that :issue:`7958` is resolved in the case of
|
|
413
|
+
number fields::
|
|
414
|
+
|
|
415
|
+
sage: # needs sage.rings.number_field
|
|
416
|
+
sage: _.<x> = ZZ[]
|
|
417
|
+
sage: K.<a> = NumberField(x^5 - 3*x^4 + 2424*x^3 + 2*x - 232)
|
|
418
|
+
sage: R = K.ring_of_integers()
|
|
419
|
+
sage: S.<y> = R[]
|
|
420
|
+
sage: F = FractionField(S) # indirect doctest
|
|
421
|
+
sage: F(1/a)
|
|
422
|
+
(a^4 - 3*a^3 + 2424*a^2 + 2)/232
|
|
423
|
+
"""
|
|
424
|
+
f = x.polynomial() # Polynomial over QQ
|
|
425
|
+
d = f.denominator() # Integer
|
|
426
|
+
return self._element_class(self, numerator=d * x, denominator=d)
|
|
427
|
+
|
|
428
|
+
def is_field(self, proof=True):
|
|
429
|
+
"""
|
|
430
|
+
Return ``True``, since the fraction field is a field.
|
|
431
|
+
|
|
432
|
+
EXAMPLES::
|
|
433
|
+
|
|
434
|
+
sage: Frac(ZZ).is_field()
|
|
435
|
+
True
|
|
436
|
+
"""
|
|
437
|
+
return True
|
|
438
|
+
|
|
439
|
+
def is_finite(self):
|
|
440
|
+
"""
|
|
441
|
+
Tells whether this fraction field is finite.
|
|
442
|
+
|
|
443
|
+
.. NOTE::
|
|
444
|
+
|
|
445
|
+
A fraction field is finite if and only if the associated
|
|
446
|
+
integral domain is finite.
|
|
447
|
+
|
|
448
|
+
EXAMPLES::
|
|
449
|
+
|
|
450
|
+
sage: Frac(QQ['a','b','c']).is_finite()
|
|
451
|
+
False
|
|
452
|
+
"""
|
|
453
|
+
return self._R.is_finite()
|
|
454
|
+
|
|
455
|
+
def base_ring(self):
|
|
456
|
+
"""
|
|
457
|
+
Return the base ring of ``self``.
|
|
458
|
+
|
|
459
|
+
This is the base ring of the ring
|
|
460
|
+
which this fraction field is the fraction field of.
|
|
461
|
+
|
|
462
|
+
EXAMPLES::
|
|
463
|
+
|
|
464
|
+
sage: R = Frac(ZZ['t'])
|
|
465
|
+
sage: R.base_ring()
|
|
466
|
+
Integer Ring
|
|
467
|
+
"""
|
|
468
|
+
return self._R.base_ring()
|
|
469
|
+
|
|
470
|
+
def characteristic(self):
|
|
471
|
+
"""
|
|
472
|
+
Return the characteristic of this fraction field.
|
|
473
|
+
|
|
474
|
+
EXAMPLES::
|
|
475
|
+
|
|
476
|
+
sage: R = Frac(ZZ['t'])
|
|
477
|
+
sage: R.base_ring()
|
|
478
|
+
Integer Ring
|
|
479
|
+
sage: R = Frac(ZZ['t']); R.characteristic()
|
|
480
|
+
0
|
|
481
|
+
sage: R = Frac(GF(5)['w']); R.characteristic()
|
|
482
|
+
5
|
|
483
|
+
"""
|
|
484
|
+
return self._R.characteristic()
|
|
485
|
+
|
|
486
|
+
def _repr_(self):
|
|
487
|
+
"""
|
|
488
|
+
Return a string representation of ``self``.
|
|
489
|
+
|
|
490
|
+
EXAMPLES::
|
|
491
|
+
|
|
492
|
+
sage: Frac(ZZ['x']) # indirect doctest
|
|
493
|
+
Fraction Field of Univariate Polynomial Ring in x over Integer Ring
|
|
494
|
+
"""
|
|
495
|
+
return "Fraction Field of %s" % self._R
|
|
496
|
+
|
|
497
|
+
def _latex_(self):
|
|
498
|
+
r"""
|
|
499
|
+
Return a latex representation of ``self``.
|
|
500
|
+
|
|
501
|
+
EXAMPLES::
|
|
502
|
+
|
|
503
|
+
sage: latex(Frac(GF(7)['x,y,z'])) # indirect doctest
|
|
504
|
+
\mathrm{Frac}(\Bold{F}_{7}[x, y, z])
|
|
505
|
+
"""
|
|
506
|
+
return "\\mathrm{Frac}(%s)" % latex.latex(self._R)
|
|
507
|
+
|
|
508
|
+
def _magma_init_(self, magma):
|
|
509
|
+
"""
|
|
510
|
+
Return a string representation of ``self`` in the given magma instance.
|
|
511
|
+
|
|
512
|
+
EXAMPLES::
|
|
513
|
+
|
|
514
|
+
sage: QQ['x'].fraction_field()._magma_init_(magma) # optional - magma
|
|
515
|
+
'SageCreateWithNames(FieldOfFractions(SageCreateWithNames(PolynomialRing(_sage_ref...),["x"])),["x"])'
|
|
516
|
+
sage: GF(9,'a')['x,y,z'].fraction_field()._magma_init_(magma) # optional - magma, needs sage.rings.finite_rings
|
|
517
|
+
'SageCreateWithNames(FieldOfFractions(SageCreateWithNames(PolynomialRing(_sage_ref...,3,"grevlex"),["x","y","z"])),["x","y","z"])'
|
|
518
|
+
|
|
519
|
+
``_magma_init_`` gets called implicitly below::
|
|
520
|
+
|
|
521
|
+
sage: magma(QQ['x,y'].fraction_field()) # optional - magma
|
|
522
|
+
Multivariate rational function field of rank 2 over Rational Field
|
|
523
|
+
Variables: x, y
|
|
524
|
+
sage: magma(ZZ['x'].fraction_field()) # optional - magma
|
|
525
|
+
Univariate rational function field over Integer Ring
|
|
526
|
+
Variables: x
|
|
527
|
+
|
|
528
|
+
Verify that conversion is being properly cached::
|
|
529
|
+
|
|
530
|
+
sage: k = Frac(QQ['x,z']) # optional - magma
|
|
531
|
+
sage: magma(k) is magma(k) # optional - magma
|
|
532
|
+
True
|
|
533
|
+
"""
|
|
534
|
+
s = 'FieldOfFractions(%s)' % self.ring()._magma_init_(magma)
|
|
535
|
+
return magma._with_names(s, self.variable_names())
|
|
536
|
+
|
|
537
|
+
def ring(self):
|
|
538
|
+
"""
|
|
539
|
+
Return the ring that this is the fraction field of.
|
|
540
|
+
|
|
541
|
+
EXAMPLES::
|
|
542
|
+
|
|
543
|
+
sage: R = Frac(QQ['x,y'])
|
|
544
|
+
sage: R
|
|
545
|
+
Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field
|
|
546
|
+
sage: R.ring()
|
|
547
|
+
Multivariate Polynomial Ring in x, y over Rational Field
|
|
548
|
+
"""
|
|
549
|
+
return self._R
|
|
550
|
+
|
|
551
|
+
@cached_method
|
|
552
|
+
def is_exact(self):
|
|
553
|
+
"""
|
|
554
|
+
Return if ``self`` is exact which is if the underlying ring is exact.
|
|
555
|
+
|
|
556
|
+
EXAMPLES::
|
|
557
|
+
|
|
558
|
+
sage: Frac(ZZ['x']).is_exact()
|
|
559
|
+
True
|
|
560
|
+
sage: Frac(CDF['x']).is_exact() # needs sage.rings.complex_double
|
|
561
|
+
False
|
|
562
|
+
"""
|
|
563
|
+
return self.ring().is_exact()
|
|
564
|
+
|
|
565
|
+
def _convert_from_finite_precision_laurent_series(self, x):
|
|
566
|
+
"""
|
|
567
|
+
Construct an element of this fraction field approximating a Laurent series.
|
|
568
|
+
|
|
569
|
+
INPUT:
|
|
570
|
+
|
|
571
|
+
- ``x`` -- a Laurent series, must have finite precision
|
|
572
|
+
|
|
573
|
+
OUTPUT: Element of ``self``
|
|
574
|
+
|
|
575
|
+
This internal method should not be used directly, use :meth:`__call__` instead,
|
|
576
|
+
which will delegates to :meth:`_element_constructor_`. There are some tests there.
|
|
577
|
+
|
|
578
|
+
.. NOTE::
|
|
579
|
+
|
|
580
|
+
Uses the algorithm described in `<https://mathoverflow.net/a/14874>`_.
|
|
581
|
+
This may be changed to use Berlekamp--Massey algorithm or something else
|
|
582
|
+
to compute Padé approximant in the future.
|
|
583
|
+
|
|
584
|
+
TESTS::
|
|
585
|
+
|
|
586
|
+
sage: F = QQ['x'].fraction_field()
|
|
587
|
+
sage: R.<x> = LaurentSeriesRing(QQ)
|
|
588
|
+
sage: f = ~R(x^2 + x + 3); f
|
|
589
|
+
1/3 - 1/9*x - 2/27*x^2 + 5/81*x^3 + ... + O(x^20)
|
|
590
|
+
sage: F._convert_from_finite_precision_laurent_series(f)
|
|
591
|
+
1/(x^2 + x + 3)
|
|
592
|
+
"""
|
|
593
|
+
integral_part = self(x.truncate(1))
|
|
594
|
+
fractional_part = x.truncate_neg(1)
|
|
595
|
+
if fractional_part.is_zero():
|
|
596
|
+
return integral_part
|
|
597
|
+
return integral_part + ~self._convert_from_finite_precision_laurent_series(~fractional_part)
|
|
598
|
+
|
|
599
|
+
def _element_constructor_(self, x, y=None, coerce=True):
|
|
600
|
+
"""
|
|
601
|
+
Construct an element of this fraction field.
|
|
602
|
+
|
|
603
|
+
EXAMPLES::
|
|
604
|
+
|
|
605
|
+
sage: # needs sage.libs.singular
|
|
606
|
+
sage: F = QQ['x,y'].fraction_field()
|
|
607
|
+
sage: F._element_constructor_(1)
|
|
608
|
+
1
|
|
609
|
+
sage: F._element_constructor_(F.gen(0)/F.gen(1))
|
|
610
|
+
x/y
|
|
611
|
+
sage: F._element_constructor_('1 + x/y')
|
|
612
|
+
(x + y)/y
|
|
613
|
+
|
|
614
|
+
::
|
|
615
|
+
|
|
616
|
+
sage: K = ZZ['x,y'].fraction_field()
|
|
617
|
+
sage: x,y = K.gens()
|
|
618
|
+
|
|
619
|
+
::
|
|
620
|
+
|
|
621
|
+
sage: F._element_constructor_(x/y) # needs sage.libs.singular
|
|
622
|
+
x/y
|
|
623
|
+
|
|
624
|
+
TESTS:
|
|
625
|
+
|
|
626
|
+
The next example failed before :issue:`4376`::
|
|
627
|
+
|
|
628
|
+
sage: K(pari((x + 1)/(x^2 + x + 1))) # needs sage.libs.pari
|
|
629
|
+
(x + 1)/(x^2 + x + 1)
|
|
630
|
+
|
|
631
|
+
These examples failed before :issue:`11368`::
|
|
632
|
+
|
|
633
|
+
sage: R.<x, y, z> = PolynomialRing(QQ)
|
|
634
|
+
sage: S = R.fraction_field()
|
|
635
|
+
sage: S(pari((x + y)/y)) # needs sage.libs.pari
|
|
636
|
+
(x + y)/y
|
|
637
|
+
|
|
638
|
+
sage: S(pari(x + y + 1/z)) # needs sage.libs.pari
|
|
639
|
+
(x*z + y*z + 1)/z
|
|
640
|
+
|
|
641
|
+
This example failed before :issue:`23664`::
|
|
642
|
+
|
|
643
|
+
sage: P0.<x> = ZZ[]
|
|
644
|
+
sage: P1.<y> = Frac(P0)[]
|
|
645
|
+
sage: frac = (x/(x^2 + 1))*y + 1/(x^3 + 1)
|
|
646
|
+
sage: Frac(ZZ['x,y'])(frac)
|
|
647
|
+
(x^4*y + x^2 + x*y + 1)/(x^5 + x^3 + x^2 + 1)
|
|
648
|
+
|
|
649
|
+
Test conversions where `y` is a string but `x` not::
|
|
650
|
+
|
|
651
|
+
sage: K = ZZ['x,y'].fraction_field()
|
|
652
|
+
sage: K._element_constructor_(2, 'x+y')
|
|
653
|
+
2/(x + y)
|
|
654
|
+
sage: K._element_constructor_(1, 'z')
|
|
655
|
+
Traceback (most recent call last):
|
|
656
|
+
...
|
|
657
|
+
TypeError: unable to evaluate 'z' in Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring
|
|
658
|
+
|
|
659
|
+
Check that :issue:`17971` is fixed::
|
|
660
|
+
|
|
661
|
+
sage: A.<a,c> = Frac(PolynomialRing(QQ,'a,c'))
|
|
662
|
+
sage: B.<d,e> = PolynomialRing(A,'d,e')
|
|
663
|
+
sage: R.<x> = PolynomialRing(B,'x')
|
|
664
|
+
sage: (a*d*x^2+a+e+1).resultant(-4*c^2*x+1) # needs sage.libs.pari
|
|
665
|
+
a*d + (16*c^4)*e + (16*a*c^4 + 16*c^4)
|
|
666
|
+
|
|
667
|
+
Check that :issue:`24539` is fixed::
|
|
668
|
+
|
|
669
|
+
sage: tau = polygen(QQ, 'tau')
|
|
670
|
+
sage: PolynomialRing(CyclotomicField(2), 'z').fraction_field()(tau/(1+tau)) # needs sage.rings.number_field
|
|
671
|
+
z/(z + 1)
|
|
672
|
+
|
|
673
|
+
Check that :issue:`26150` is fixed::
|
|
674
|
+
|
|
675
|
+
sage: z = SR.var('z') # needs sage.symbolic
|
|
676
|
+
sage: CyclotomicField(2)['z'].fraction_field()(2*(4*z + 5)/((z + 1)*(z - 1)^4)) # needs sage.rings.number_field sage.symbolic
|
|
677
|
+
(8*z + 10)/(z^5 - 3*z^4 + 2*z^3 + 2*z^2 - 3*z + 1)
|
|
678
|
+
|
|
679
|
+
::
|
|
680
|
+
|
|
681
|
+
sage: T.<t> = ZZ[]
|
|
682
|
+
sage: S.<s> = ZZ[]
|
|
683
|
+
sage: S.fraction_field()(s/(s+1), (t-1)/(t+2))
|
|
684
|
+
(s^2 + 2*s)/(s^2 - 1)
|
|
685
|
+
|
|
686
|
+
Check that :issue:`29713` is fixed::
|
|
687
|
+
|
|
688
|
+
sage: F = FractionField(QQ['a'])
|
|
689
|
+
sage: a = F.gen()
|
|
690
|
+
sage: R = PolynomialRing(F, 'x')
|
|
691
|
+
sage: FF = FractionField(R)
|
|
692
|
+
sage: elt = F(-1/2/(a^2+a))
|
|
693
|
+
sage: x = FF(elt)
|
|
694
|
+
sage: F(x)
|
|
695
|
+
-1/2/(a^2 + a)
|
|
696
|
+
|
|
697
|
+
Conversion from power series to rational function field gives an approximation::
|
|
698
|
+
|
|
699
|
+
sage: F.<x> = Frac(QQ['x'])
|
|
700
|
+
sage: R.<x> = QQ[[]]
|
|
701
|
+
sage: f = 1/(x+1)
|
|
702
|
+
sage: f.parent()
|
|
703
|
+
Power Series Ring in x over Rational Field
|
|
704
|
+
sage: F(f)
|
|
705
|
+
doctest:warning...
|
|
706
|
+
DeprecationWarning: Previously conversion from power series to rational function field truncates
|
|
707
|
+
instead of gives an approximation. Use .truncate() to recover the old behavior
|
|
708
|
+
See https://github.com/sagemath/sage/issues/39485 for details.
|
|
709
|
+
1/(x + 1)
|
|
710
|
+
|
|
711
|
+
Previously, the power series was truncated. To recover the old behavior, use
|
|
712
|
+
:meth:`~sage.rings.power_series_ring_element.PowerSeries.truncate`::
|
|
713
|
+
|
|
714
|
+
sage: F(f.truncate())
|
|
715
|
+
-x^19 + x^18 - x^17 + x^16 - x^15 + x^14 - x^13 + x^12 - x^11 + x^10 - x^9 + x^8 - x^7 + x^6 - x^5 + x^4 - x^3 + x^2 - x + 1
|
|
716
|
+
|
|
717
|
+
Conversion from Laurent series to rational function field gives an approximation::
|
|
718
|
+
|
|
719
|
+
sage: F.<x> = Frac(QQ['x'])
|
|
720
|
+
sage: R.<x> = QQ[[]]
|
|
721
|
+
sage: f = Frac(R)(1/(x+1))
|
|
722
|
+
sage: f.parent()
|
|
723
|
+
Laurent Series Ring in x over Rational Field
|
|
724
|
+
sage: F(f)
|
|
725
|
+
1/(x + 1)
|
|
726
|
+
sage: f = f.truncate(20); f # infinite precision
|
|
727
|
+
1 - x + x^2 - x^3 + x^4 - x^5 + x^6 - x^7 + x^8 - x^9 + x^10 - x^11 + x^12 - x^13 + x^14 - x^15 + x^16 - x^17 + x^18 - x^19
|
|
728
|
+
sage: f.parent()
|
|
729
|
+
Laurent Series Ring in x over Rational Field
|
|
730
|
+
sage: F(f)
|
|
731
|
+
-x^19 + x^18 - x^17 + x^16 - x^15 + x^14 - x^13 + x^12 - x^11 + x^10 - x^9 + x^8 - x^7 + x^6 - x^5 + x^4 - x^3 + x^2 - x + 1
|
|
732
|
+
sage: f = 1/(x*(x+1))
|
|
733
|
+
sage: f.parent()
|
|
734
|
+
Laurent Series Ring in x over Rational Field
|
|
735
|
+
sage: F(f)
|
|
736
|
+
1/(x^2 + x)
|
|
737
|
+
|
|
738
|
+
::
|
|
739
|
+
|
|
740
|
+
sage: K.<x> = FunctionField(QQ)
|
|
741
|
+
sage: R.<x> = QQ[[]]
|
|
742
|
+
sage: f = 1/(x+1); f.parent()
|
|
743
|
+
Power Series Ring in x over Rational Field
|
|
744
|
+
sage: K(f)
|
|
745
|
+
doctest:warning...
|
|
746
|
+
DeprecationWarning: Previously conversion from power series to rational function field truncates
|
|
747
|
+
instead of gives an approximation. Use .truncate() to recover the old behavior
|
|
748
|
+
See https://github.com/sagemath/sage/issues/39485 for details.
|
|
749
|
+
1/(x + 1)
|
|
750
|
+
sage: f = Frac(R)(1/(x+1))
|
|
751
|
+
sage: K(f)
|
|
752
|
+
1/(x + 1)
|
|
753
|
+
sage: f = 1/(x*(x+1))
|
|
754
|
+
sage: K(f)
|
|
755
|
+
1/(x^2 + x)
|
|
756
|
+
"""
|
|
757
|
+
if isinstance(x, (list, tuple)) and len(x) == 1:
|
|
758
|
+
x = x[0]
|
|
759
|
+
if y is None:
|
|
760
|
+
if parent(x) is self:
|
|
761
|
+
return x
|
|
762
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
763
|
+
if isinstance(self.ring(), PolynomialRing_generic):
|
|
764
|
+
from sage.rings.power_series_ring_element import PowerSeries
|
|
765
|
+
from sage.rings.laurent_series_ring_element import LaurentSeries
|
|
766
|
+
if isinstance(x, PowerSeries):
|
|
767
|
+
from sage.misc.superseded import deprecation
|
|
768
|
+
deprecation(
|
|
769
|
+
39485,
|
|
770
|
+
"Previously conversion from power series to rational function field truncates "
|
|
771
|
+
"instead of gives an approximation. Use .truncate() to recover the old behavior")
|
|
772
|
+
x = x.laurent_series()
|
|
773
|
+
if isinstance(x, LaurentSeries):
|
|
774
|
+
from sage.rings.infinity import infinity
|
|
775
|
+
if x.prec() == infinity:
|
|
776
|
+
return self(x.laurent_polynomial())
|
|
777
|
+
return self._convert_from_finite_precision_laurent_series(x)
|
|
778
|
+
ring_one = self.ring().one()
|
|
779
|
+
try:
|
|
780
|
+
return self._element_class(self, x, ring_one, coerce=coerce)
|
|
781
|
+
except (TypeError, ValueError):
|
|
782
|
+
pass
|
|
783
|
+
y = self.one()
|
|
784
|
+
else:
|
|
785
|
+
if parent(x) is self:
|
|
786
|
+
y = self(y)
|
|
787
|
+
x, y = x.numerator() * y.denominator(), y.numerator() * x.denominator()
|
|
788
|
+
try:
|
|
789
|
+
return self._element_class(self, x, y, coerce=coerce)
|
|
790
|
+
except (TypeError, ValueError):
|
|
791
|
+
pass
|
|
792
|
+
|
|
793
|
+
if isinstance(x, str):
|
|
794
|
+
from sage.misc.sage_eval import sage_eval
|
|
795
|
+
try:
|
|
796
|
+
x = sage_eval(x, self.gens_dict_recursive())
|
|
797
|
+
except NameError:
|
|
798
|
+
raise TypeError("unable to evaluate {!r} in {}".format(x, self))
|
|
799
|
+
if isinstance(y, str):
|
|
800
|
+
from sage.misc.sage_eval import sage_eval
|
|
801
|
+
try:
|
|
802
|
+
y = sage_eval(y, self.gens_dict_recursive())
|
|
803
|
+
except NameError:
|
|
804
|
+
raise TypeError("unable to evaluate {!r} in {}".format(y, self))
|
|
805
|
+
|
|
806
|
+
x = py_scalar_to_element(x)
|
|
807
|
+
y = py_scalar_to_element(y)
|
|
808
|
+
|
|
809
|
+
try:
|
|
810
|
+
from cypari2.gen import Gen as pari_gen
|
|
811
|
+
except ImportError:
|
|
812
|
+
pari_gen = ()
|
|
813
|
+
|
|
814
|
+
if isinstance(x, pari_gen) and x.type() == 't_POL':
|
|
815
|
+
# This recursive approach is needed because PARI
|
|
816
|
+
# represents multivariate polynomials as iterated
|
|
817
|
+
# univariate polynomials (see the above examples).
|
|
818
|
+
# Below, v is the variable with highest priority,
|
|
819
|
+
# and the x[i] are rational functions in the
|
|
820
|
+
# remaining variables.
|
|
821
|
+
d = x.poldegree()
|
|
822
|
+
if d.type() == 't_INFINITY':
|
|
823
|
+
return self.zero()
|
|
824
|
+
v = self._element_class(self, x.variable(), 1)
|
|
825
|
+
x = sum(self(x[i]) * v**i for i in range(d + 1))
|
|
826
|
+
|
|
827
|
+
def resolve_fractions(x, y):
|
|
828
|
+
xn = x.numerator()
|
|
829
|
+
xd = x.denominator()
|
|
830
|
+
yn = y.numerator()
|
|
831
|
+
yd = y.denominator()
|
|
832
|
+
try:
|
|
833
|
+
return (xn * yd, yn * xd)
|
|
834
|
+
except (AttributeError, TypeError, ValueError):
|
|
835
|
+
pass
|
|
836
|
+
try:
|
|
837
|
+
P = parent(yd)
|
|
838
|
+
return (P(xn) * yd, yn * P(xd))
|
|
839
|
+
except (AttributeError, TypeError, ValueError):
|
|
840
|
+
pass
|
|
841
|
+
try:
|
|
842
|
+
P = parent(xd)
|
|
843
|
+
return (xn * P(yd), P(yn) * xd)
|
|
844
|
+
except (AttributeError, TypeError, ValueError):
|
|
845
|
+
pass
|
|
846
|
+
raise TypeError
|
|
847
|
+
|
|
848
|
+
while True:
|
|
849
|
+
x0, y0 = x, y
|
|
850
|
+
try:
|
|
851
|
+
x, y = resolve_fractions(x0, y0)
|
|
852
|
+
except (AttributeError, TypeError):
|
|
853
|
+
raise TypeError("cannot convert {!r}/{!r} to an element of {}".format(
|
|
854
|
+
x0, y0, self))
|
|
855
|
+
try:
|
|
856
|
+
return self._element_class(self, x, y, coerce=coerce)
|
|
857
|
+
except TypeError:
|
|
858
|
+
if parent(x) is parent(x0):
|
|
859
|
+
raise
|
|
860
|
+
|
|
861
|
+
def construction(self):
|
|
862
|
+
"""
|
|
863
|
+
EXAMPLES::
|
|
864
|
+
|
|
865
|
+
sage: Frac(ZZ['x']).construction()
|
|
866
|
+
(FractionField, Univariate Polynomial Ring in x over Integer Ring)
|
|
867
|
+
sage: K = Frac(GF(3)['t'])
|
|
868
|
+
sage: f, R = K.construction()
|
|
869
|
+
sage: f(R)
|
|
870
|
+
Fraction Field of Univariate Polynomial Ring in t
|
|
871
|
+
over Finite Field of size 3
|
|
872
|
+
sage: f(R) == K
|
|
873
|
+
True
|
|
874
|
+
"""
|
|
875
|
+
from sage.categories.pushout import FractionField
|
|
876
|
+
return FractionField(), self.ring()
|
|
877
|
+
|
|
878
|
+
def __eq__(self, other):
|
|
879
|
+
"""
|
|
880
|
+
Check whether ``self`` is equal to ``other``.
|
|
881
|
+
|
|
882
|
+
EXAMPLES::
|
|
883
|
+
|
|
884
|
+
sage: Frac(ZZ['x']) == Frac(ZZ['x'])
|
|
885
|
+
True
|
|
886
|
+
sage: Frac(ZZ['x']) == Frac(QQ['x'])
|
|
887
|
+
False
|
|
888
|
+
sage: Frac(ZZ['x']) == Frac(ZZ['y'])
|
|
889
|
+
False
|
|
890
|
+
sage: Frac(ZZ['x']) == QQ['x']
|
|
891
|
+
False
|
|
892
|
+
"""
|
|
893
|
+
if not isinstance(other, FractionField_generic):
|
|
894
|
+
return False
|
|
895
|
+
return self._R == other._R
|
|
896
|
+
|
|
897
|
+
def __ne__(self, other):
|
|
898
|
+
"""
|
|
899
|
+
Check whether ``self`` is not equal to ``other``.
|
|
900
|
+
|
|
901
|
+
EXAMPLES::
|
|
902
|
+
|
|
903
|
+
sage: Frac(ZZ['x']) != Frac(ZZ['x'])
|
|
904
|
+
False
|
|
905
|
+
sage: Frac(ZZ['x']) != Frac(QQ['x'])
|
|
906
|
+
True
|
|
907
|
+
sage: Frac(ZZ['x']) != Frac(ZZ['y'])
|
|
908
|
+
True
|
|
909
|
+
sage: Frac(ZZ['x']) != QQ['x']
|
|
910
|
+
True
|
|
911
|
+
"""
|
|
912
|
+
return not (self == other)
|
|
913
|
+
|
|
914
|
+
def __hash__(self):
|
|
915
|
+
"""
|
|
916
|
+
Compute the hash of ``self``.
|
|
917
|
+
|
|
918
|
+
EXAMPLES::
|
|
919
|
+
|
|
920
|
+
sage: h0 = hash(Frac(ZZ['x']))
|
|
921
|
+
sage: h1 = hash(Frac(ZZ['x']))
|
|
922
|
+
sage: h2 = hash(Frac(QQ['x']))
|
|
923
|
+
sage: h3 = hash(ZZ['x'])
|
|
924
|
+
sage: h0 == h1 and h1 != h2 and h1 != h3
|
|
925
|
+
True
|
|
926
|
+
"""
|
|
927
|
+
# to avoid having exactly the same hash as the base ring,
|
|
928
|
+
# we change this hash using a random number
|
|
929
|
+
return hash(self._R) ^ 147068341996611
|
|
930
|
+
|
|
931
|
+
def ngens(self):
|
|
932
|
+
"""
|
|
933
|
+
This is the same as for the parent object.
|
|
934
|
+
|
|
935
|
+
EXAMPLES::
|
|
936
|
+
|
|
937
|
+
sage: R = Frac(PolynomialRing(QQ,'z',10)); R
|
|
938
|
+
Fraction Field of Multivariate Polynomial Ring
|
|
939
|
+
in z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field
|
|
940
|
+
sage: R.ngens()
|
|
941
|
+
10
|
|
942
|
+
"""
|
|
943
|
+
return self._R.ngens()
|
|
944
|
+
|
|
945
|
+
def gen(self, i=0):
|
|
946
|
+
"""
|
|
947
|
+
Return the ``i``-th generator of ``self``.
|
|
948
|
+
|
|
949
|
+
EXAMPLES::
|
|
950
|
+
|
|
951
|
+
sage: R = Frac(PolynomialRing(QQ,'z',10)); R
|
|
952
|
+
Fraction Field of Multivariate Polynomial Ring
|
|
953
|
+
in z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field
|
|
954
|
+
sage: R.0
|
|
955
|
+
z0
|
|
956
|
+
sage: R.gen(3)
|
|
957
|
+
z3
|
|
958
|
+
sage: R.3
|
|
959
|
+
z3
|
|
960
|
+
"""
|
|
961
|
+
x = self._R.gen(i)
|
|
962
|
+
one = self._R.one()
|
|
963
|
+
r = self._element_class(self, x, one, coerce=False, reduce=False)
|
|
964
|
+
return r
|
|
965
|
+
|
|
966
|
+
def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None):
|
|
967
|
+
"""
|
|
968
|
+
Check if the homomorphism defined by sending generators of this
|
|
969
|
+
fraction field to ``im_gens`` in ``codomain`` is valid.
|
|
970
|
+
|
|
971
|
+
EXAMPLES::
|
|
972
|
+
|
|
973
|
+
sage: F = QQ['x,y'].fraction_field()
|
|
974
|
+
sage: x,y = F.gens()
|
|
975
|
+
sage: F._is_valid_homomorphism_(F, [y,x])
|
|
976
|
+
True
|
|
977
|
+
sage: R = ZZ['x']; x = R.gen()
|
|
978
|
+
sage: F._is_valid_homomorphism_(R, [x, x])
|
|
979
|
+
False
|
|
980
|
+
|
|
981
|
+
TESTS::
|
|
982
|
+
|
|
983
|
+
sage: F._is_valid_homomorphism_(ZZ, [])
|
|
984
|
+
False
|
|
985
|
+
|
|
986
|
+
Test homomorphisms::
|
|
987
|
+
|
|
988
|
+
sage: # needs sage.libs.singular
|
|
989
|
+
sage: phi = F.hom([2*y, x])
|
|
990
|
+
sage: phi(x+y)
|
|
991
|
+
x + 2*y
|
|
992
|
+
sage: phi(x/y)
|
|
993
|
+
2*y/x
|
|
994
|
+
"""
|
|
995
|
+
if len(im_gens) != self.ngens():
|
|
996
|
+
return False
|
|
997
|
+
# It is very difficult to check that the image of any element
|
|
998
|
+
# is invertible. Checking that the image of each generator
|
|
999
|
+
# is a unit is not sufficient. So we just give up and check
|
|
1000
|
+
# that elements of the base ring coerce to the codomain
|
|
1001
|
+
if base_map is None and not codomain.has_coerce_map_from(self.base_ring()):
|
|
1002
|
+
return False
|
|
1003
|
+
return True
|
|
1004
|
+
|
|
1005
|
+
def random_element(self, *args, **kwds):
|
|
1006
|
+
"""
|
|
1007
|
+
Return a random element in this fraction field.
|
|
1008
|
+
|
|
1009
|
+
The arguments are passed to the random generator of the underlying ring.
|
|
1010
|
+
|
|
1011
|
+
EXAMPLES::
|
|
1012
|
+
|
|
1013
|
+
sage: F = ZZ['x'].fraction_field()
|
|
1014
|
+
sage: F.random_element() # random
|
|
1015
|
+
(2*x - 8)/(-x^2 + x)
|
|
1016
|
+
|
|
1017
|
+
::
|
|
1018
|
+
|
|
1019
|
+
sage: f = F.random_element(degree=5)
|
|
1020
|
+
sage: f.numerator().degree() == f.denominator().degree()
|
|
1021
|
+
True
|
|
1022
|
+
sage: f.denominator().degree() <= 5
|
|
1023
|
+
True
|
|
1024
|
+
sage: while f.numerator().degree() != 5:
|
|
1025
|
+
....: f = F.random_element(degree=5)
|
|
1026
|
+
"""
|
|
1027
|
+
return self._element_class(self, self._R.random_element(*args, **kwds),
|
|
1028
|
+
self._R._random_nonzero_element(*args, **kwds),
|
|
1029
|
+
coerce=False, reduce=True)
|
|
1030
|
+
|
|
1031
|
+
def some_elements(self):
|
|
1032
|
+
r"""
|
|
1033
|
+
Return some elements in this field.
|
|
1034
|
+
|
|
1035
|
+
EXAMPLES::
|
|
1036
|
+
|
|
1037
|
+
sage: R.<x> = QQ[]
|
|
1038
|
+
sage: R.fraction_field().some_elements()
|
|
1039
|
+
[0,
|
|
1040
|
+
1,
|
|
1041
|
+
x,
|
|
1042
|
+
2*x,
|
|
1043
|
+
x/(x^2 + 2*x + 1),
|
|
1044
|
+
1/x^2,
|
|
1045
|
+
...
|
|
1046
|
+
(2*x^2 + 2)/(x^2 + 2*x + 1),
|
|
1047
|
+
(2*x^2 + 2)/x^3,
|
|
1048
|
+
(2*x^2 + 2)/(x^2 - 1),
|
|
1049
|
+
2]
|
|
1050
|
+
"""
|
|
1051
|
+
ret = [self.zero(), self.one()]
|
|
1052
|
+
ret.extend(self(a) / self(b)
|
|
1053
|
+
for a in self._R.some_elements()
|
|
1054
|
+
for b in self._R.some_elements()
|
|
1055
|
+
if a != b and self(a) and self(b))
|
|
1056
|
+
return ret
|
|
1057
|
+
|
|
1058
|
+
def _gcd_univariate_polynomial(self, f, g):
|
|
1059
|
+
r"""
|
|
1060
|
+
Helper method used to compute polynomial gcds over this field.
|
|
1061
|
+
|
|
1062
|
+
See :meth:`sage.rings.polynomial.polynomial_element.Polynomial.gcd`.
|
|
1063
|
+
|
|
1064
|
+
TESTS::
|
|
1065
|
+
|
|
1066
|
+
sage: # needs sage.libs.singular
|
|
1067
|
+
sage: A.<x,y> = ZZ[]
|
|
1068
|
+
sage: C.<z> = Frac(A)[]
|
|
1069
|
+
sage: c = (2*y^2 - 11*x - 2*y + 1)/(-x^2 + x*y - 2*y^2)
|
|
1070
|
+
sage: p = (c*z^2 + x^10*z + 1)^6
|
|
1071
|
+
sage: q = (z^2 + c*x^10*z + 1)^6
|
|
1072
|
+
sage: g = p.gcd(q)
|
|
1073
|
+
sage: g
|
|
1074
|
+
1
|
|
1075
|
+
sage: g.parent() is p.parent()
|
|
1076
|
+
True
|
|
1077
|
+
sage: (p*(z-x)).gcd(q*(z-x))
|
|
1078
|
+
z - x
|
|
1079
|
+
sage: C.zero().gcd(2*z)
|
|
1080
|
+
z
|
|
1081
|
+
sage: (x*z).gcd(0)
|
|
1082
|
+
z
|
|
1083
|
+
sage: C.zero().gcd(0)
|
|
1084
|
+
0
|
|
1085
|
+
"""
|
|
1086
|
+
if g.is_zero():
|
|
1087
|
+
if f.is_zero():
|
|
1088
|
+
return f
|
|
1089
|
+
else:
|
|
1090
|
+
return f.monic()
|
|
1091
|
+
Pol = f.parent()
|
|
1092
|
+
Num = Pol.change_ring(self.base())
|
|
1093
|
+
f1 = Num(f.numerator())
|
|
1094
|
+
g1 = Num(g.numerator())
|
|
1095
|
+
return Pol(f1.gcd(g1)).monic()
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
class FractionField_1poly_field(FractionField_generic):
|
|
1099
|
+
"""
|
|
1100
|
+
The fraction field of a univariate polynomial ring over a field.
|
|
1101
|
+
|
|
1102
|
+
Many of the functions here are included for coherence with number fields.
|
|
1103
|
+
"""
|
|
1104
|
+
def __init__(self, R,
|
|
1105
|
+
element_class=fraction_field_element.FractionFieldElement_1poly_field):
|
|
1106
|
+
"""
|
|
1107
|
+
Just change the default for ``element_class``.
|
|
1108
|
+
|
|
1109
|
+
EXAMPLES::
|
|
1110
|
+
|
|
1111
|
+
sage: R.<t> = QQ[]; K = R.fraction_field()
|
|
1112
|
+
sage: K._element_class
|
|
1113
|
+
<class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>
|
|
1114
|
+
"""
|
|
1115
|
+
FractionField_generic.__init__(self, R, element_class)
|
|
1116
|
+
|
|
1117
|
+
def ring_of_integers(self):
|
|
1118
|
+
"""
|
|
1119
|
+
Return the ring of integers in this fraction field.
|
|
1120
|
+
|
|
1121
|
+
EXAMPLES::
|
|
1122
|
+
|
|
1123
|
+
sage: K = FractionField(GF(5)['t'])
|
|
1124
|
+
sage: K.ring_of_integers()
|
|
1125
|
+
Univariate Polynomial Ring in t over Finite Field of size 5
|
|
1126
|
+
"""
|
|
1127
|
+
return self._R
|
|
1128
|
+
|
|
1129
|
+
def maximal_order(self):
|
|
1130
|
+
"""
|
|
1131
|
+
Return the maximal order in this fraction field.
|
|
1132
|
+
|
|
1133
|
+
EXAMPLES::
|
|
1134
|
+
|
|
1135
|
+
sage: K = FractionField(GF(5)['t'])
|
|
1136
|
+
sage: K.maximal_order()
|
|
1137
|
+
Univariate Polynomial Ring in t over Finite Field of size 5
|
|
1138
|
+
"""
|
|
1139
|
+
return self._R
|
|
1140
|
+
|
|
1141
|
+
def class_number(self):
|
|
1142
|
+
"""
|
|
1143
|
+
Here for compatibility with number fields and function fields.
|
|
1144
|
+
|
|
1145
|
+
EXAMPLES::
|
|
1146
|
+
|
|
1147
|
+
sage: R.<t> = GF(5)[]; K = R.fraction_field()
|
|
1148
|
+
sage: K.class_number()
|
|
1149
|
+
1
|
|
1150
|
+
"""
|
|
1151
|
+
return 1
|
|
1152
|
+
|
|
1153
|
+
def _factor_univariate_polynomial(self, f):
|
|
1154
|
+
r"""
|
|
1155
|
+
Return the factorization of ``f`` over this field.
|
|
1156
|
+
|
|
1157
|
+
EXAMPLES::
|
|
1158
|
+
|
|
1159
|
+
sage: # needs sage.rings.finite_rings
|
|
1160
|
+
sage: k.<a> = GF(9)
|
|
1161
|
+
sage: K = k['t'].fraction_field()
|
|
1162
|
+
sage: R.<x> = K[]
|
|
1163
|
+
sage: f = x^3 + a
|
|
1164
|
+
sage: f.factor()
|
|
1165
|
+
(x + 2*a + 1)^3
|
|
1166
|
+
"""
|
|
1167
|
+
# The default implementation would try to convert this element to singular and factor there.
|
|
1168
|
+
# This fails silently over some base fields, see #23642, so we convert
|
|
1169
|
+
# to the function field and factor there.
|
|
1170
|
+
return f.change_ring(self.function_field()).factor().base_change(f.parent())
|
|
1171
|
+
|
|
1172
|
+
def function_field(self):
|
|
1173
|
+
r"""
|
|
1174
|
+
Return the isomorphic function field.
|
|
1175
|
+
|
|
1176
|
+
EXAMPLES::
|
|
1177
|
+
|
|
1178
|
+
sage: R.<t> = GF(5)[]
|
|
1179
|
+
sage: K = R.fraction_field()
|
|
1180
|
+
sage: K.function_field()
|
|
1181
|
+
Rational function field in t over Finite Field of size 5
|
|
1182
|
+
|
|
1183
|
+
.. SEEALSO::
|
|
1184
|
+
|
|
1185
|
+
:meth:`sage.rings.function_field.RationalFunctionField.field`
|
|
1186
|
+
"""
|
|
1187
|
+
from sage.rings.function_field.constructor import FunctionField
|
|
1188
|
+
return FunctionField(self.base_ring(), names=self.variable_name())
|
|
1189
|
+
|
|
1190
|
+
def _coerce_map_from_(self, R):
|
|
1191
|
+
r"""
|
|
1192
|
+
Return a coerce map from ``R`` to this field.
|
|
1193
|
+
|
|
1194
|
+
EXAMPLES::
|
|
1195
|
+
|
|
1196
|
+
sage: # needs sage.rings.finite_rings
|
|
1197
|
+
sage: R.<t> = GF(5)[]
|
|
1198
|
+
sage: K = R.fraction_field()
|
|
1199
|
+
sage: L = K.function_field()
|
|
1200
|
+
sage: f = K.coerce_map_from(L); f # indirect doctest
|
|
1201
|
+
Isomorphism:
|
|
1202
|
+
From: Rational function field in t over Finite Field of size 5
|
|
1203
|
+
To: Fraction Field of Univariate Polynomial Ring in t
|
|
1204
|
+
over Finite Field of size 5
|
|
1205
|
+
sage: f(~L.gen())
|
|
1206
|
+
1/t
|
|
1207
|
+
"""
|
|
1208
|
+
from sage.rings.function_field.function_field_rational import (
|
|
1209
|
+
RationalFunctionField,
|
|
1210
|
+
)
|
|
1211
|
+
if isinstance(R, RationalFunctionField) and self.variable_name() == R.variable_name() and self.base_ring() is R.constant_base_field():
|
|
1212
|
+
from sage.categories.homset import Hom
|
|
1213
|
+
parent = Hom(R, self)
|
|
1214
|
+
from sage.rings.function_field.maps import FunctionFieldToFractionField
|
|
1215
|
+
return parent.__make_element_class__(FunctionFieldToFractionField)(parent)
|
|
1216
|
+
|
|
1217
|
+
return super()._coerce_map_from_(R)
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
class FractionFieldEmbedding(DefaultConvertMap_unique):
|
|
1221
|
+
r"""
|
|
1222
|
+
The embedding of an integral domain into its field of fractions.
|
|
1223
|
+
|
|
1224
|
+
EXAMPLES::
|
|
1225
|
+
|
|
1226
|
+
sage: R.<x> = QQ[]
|
|
1227
|
+
sage: f = R.fraction_field().coerce_map_from(R); f
|
|
1228
|
+
Coercion map:
|
|
1229
|
+
From: Univariate Polynomial Ring in x over Rational Field
|
|
1230
|
+
To: Fraction Field of Univariate Polynomial Ring in x over Rational Field
|
|
1231
|
+
|
|
1232
|
+
TESTS::
|
|
1233
|
+
|
|
1234
|
+
sage: from sage.rings.fraction_field import FractionFieldEmbedding
|
|
1235
|
+
sage: isinstance(f, FractionFieldEmbedding)
|
|
1236
|
+
True
|
|
1237
|
+
sage: TestSuite(f).run()
|
|
1238
|
+
|
|
1239
|
+
Check that :issue:`23185` has been resolved::
|
|
1240
|
+
|
|
1241
|
+
sage: R.<x> = QQ[]
|
|
1242
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1243
|
+
sage: R.is_subring(K)
|
|
1244
|
+
True
|
|
1245
|
+
sage: R.is_subring(R.fraction_field())
|
|
1246
|
+
True
|
|
1247
|
+
"""
|
|
1248
|
+
def is_surjective(self):
|
|
1249
|
+
r"""
|
|
1250
|
+
Return whether this map is surjective.
|
|
1251
|
+
|
|
1252
|
+
EXAMPLES::
|
|
1253
|
+
|
|
1254
|
+
sage: R.<x> = QQ[]
|
|
1255
|
+
sage: R.fraction_field().coerce_map_from(R).is_surjective()
|
|
1256
|
+
False
|
|
1257
|
+
"""
|
|
1258
|
+
return self.domain().is_field()
|
|
1259
|
+
|
|
1260
|
+
def is_injective(self):
|
|
1261
|
+
r"""
|
|
1262
|
+
Return whether this map is injective.
|
|
1263
|
+
|
|
1264
|
+
EXAMPLES:
|
|
1265
|
+
|
|
1266
|
+
The map from an integral domain to its fraction field is always
|
|
1267
|
+
injective::
|
|
1268
|
+
|
|
1269
|
+
sage: R.<x> = QQ[]
|
|
1270
|
+
sage: R.fraction_field().coerce_map_from(R).is_injective()
|
|
1271
|
+
True
|
|
1272
|
+
"""
|
|
1273
|
+
return True
|
|
1274
|
+
|
|
1275
|
+
def section(self):
|
|
1276
|
+
r"""
|
|
1277
|
+
Return a section of this map.
|
|
1278
|
+
|
|
1279
|
+
EXAMPLES::
|
|
1280
|
+
|
|
1281
|
+
sage: R.<x> = QQ[]
|
|
1282
|
+
sage: R.fraction_field().coerce_map_from(R).section()
|
|
1283
|
+
Section map:
|
|
1284
|
+
From: Fraction Field of Univariate Polynomial Ring in x over Rational Field
|
|
1285
|
+
To: Univariate Polynomial Ring in x over Rational Field
|
|
1286
|
+
"""
|
|
1287
|
+
from sage.categories.homset import Hom
|
|
1288
|
+
from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
|
|
1289
|
+
parent = Hom(self.codomain(), self.domain(), SetsWithPartialMaps())
|
|
1290
|
+
return parent.__make_element_class__(FractionFieldEmbeddingSection)(self)
|
|
1291
|
+
|
|
1292
|
+
def _richcmp_(self, other, op):
|
|
1293
|
+
r"""
|
|
1294
|
+
Compare this element to ``other`` with respect to ``op``.
|
|
1295
|
+
|
|
1296
|
+
EXAMPLES::
|
|
1297
|
+
|
|
1298
|
+
sage: R.<x> = QQ[]
|
|
1299
|
+
sage: f = R.fraction_field().coerce_map_from(R)
|
|
1300
|
+
sage: S.<y> = GF(2)[]
|
|
1301
|
+
sage: g = S.fraction_field().coerce_map_from(S)
|
|
1302
|
+
|
|
1303
|
+
sage: f == g # indirect doctest
|
|
1304
|
+
False
|
|
1305
|
+
sage: f == f
|
|
1306
|
+
True
|
|
1307
|
+
"""
|
|
1308
|
+
if type(self) is not type(other):
|
|
1309
|
+
return NotImplemented
|
|
1310
|
+
return richcmp((self.domain(), self.codomain()), (other.domain(), other.codomain()), op)
|
|
1311
|
+
|
|
1312
|
+
def __hash__(self):
|
|
1313
|
+
r"""
|
|
1314
|
+
Return a hash value for this embedding.
|
|
1315
|
+
|
|
1316
|
+
EXAMPLES::
|
|
1317
|
+
|
|
1318
|
+
sage: R.<x> = QQ[]
|
|
1319
|
+
sage: hash(R.fraction_field().coerce_map_from(R)) == hash(R.fraction_field().coerce_map_from(R))
|
|
1320
|
+
True
|
|
1321
|
+
"""
|
|
1322
|
+
return hash((type(self), self.domain()))
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
class FractionFieldEmbeddingSection(Section):
|
|
1326
|
+
r"""
|
|
1327
|
+
The section of the embedding of an integral domain into its field of
|
|
1328
|
+
fractions.
|
|
1329
|
+
|
|
1330
|
+
EXAMPLES::
|
|
1331
|
+
|
|
1332
|
+
sage: R.<x> = QQ[]
|
|
1333
|
+
sage: f = R.fraction_field().coerce_map_from(R).section(); f
|
|
1334
|
+
Section map:
|
|
1335
|
+
From: Fraction Field of Univariate Polynomial Ring in x over Rational Field
|
|
1336
|
+
To: Univariate Polynomial Ring in x over Rational Field
|
|
1337
|
+
|
|
1338
|
+
TESTS::
|
|
1339
|
+
|
|
1340
|
+
sage: from sage.rings.fraction_field import FractionFieldEmbeddingSection
|
|
1341
|
+
sage: isinstance(f, FractionFieldEmbeddingSection)
|
|
1342
|
+
True
|
|
1343
|
+
sage: TestSuite(f).run()
|
|
1344
|
+
"""
|
|
1345
|
+
def _call_(self, x, check=True):
|
|
1346
|
+
r"""
|
|
1347
|
+
Evaluate this map at ``x``.
|
|
1348
|
+
|
|
1349
|
+
EXAMPLES::
|
|
1350
|
+
|
|
1351
|
+
sage: R.<x> = QQ[]
|
|
1352
|
+
sage: K = R.fraction_field()
|
|
1353
|
+
sage: x = K.gen()
|
|
1354
|
+
sage: f = K.coerce_map_from(R).section()
|
|
1355
|
+
sage: f(x)
|
|
1356
|
+
x
|
|
1357
|
+
sage: f(1/x)
|
|
1358
|
+
Traceback (most recent call last):
|
|
1359
|
+
...
|
|
1360
|
+
TypeError: fraction must have unit denominator
|
|
1361
|
+
|
|
1362
|
+
TESTS:
|
|
1363
|
+
|
|
1364
|
+
Over inexact rings, we have to take the precision of the denominators
|
|
1365
|
+
into account::
|
|
1366
|
+
|
|
1367
|
+
sage: # needs sage.rings.padics
|
|
1368
|
+
sage: R = ZpCR(2)
|
|
1369
|
+
sage: S.<x> = R[]
|
|
1370
|
+
sage: f = x/S(R(3, absprec=2))
|
|
1371
|
+
sage: S(f)
|
|
1372
|
+
(1 + 2 + O(2^2))*x
|
|
1373
|
+
|
|
1374
|
+
Test for Localization::
|
|
1375
|
+
|
|
1376
|
+
sage: R.<x> = ZZ[]
|
|
1377
|
+
sage: L = Localization(R, x**2 + 2*x + 1) # needs sage.libs.pari
|
|
1378
|
+
sage: 1/(x + 1) in L # indirect doctest # needs sage.libs.pari
|
|
1379
|
+
True
|
|
1380
|
+
sage: 1/(x + 2) in L # indirect doctest # needs sage.libs.pari
|
|
1381
|
+
False
|
|
1382
|
+
"""
|
|
1383
|
+
codom = self.codomain()
|
|
1384
|
+
if self.domain()._R is codom:
|
|
1385
|
+
num = x.numerator()
|
|
1386
|
+
den = x.denominator()
|
|
1387
|
+
else:
|
|
1388
|
+
# codomain may different from the fraction fields base ring
|
|
1389
|
+
# for example for localizations
|
|
1390
|
+
num = codom(x.numerator())
|
|
1391
|
+
den = codom(x.denominator())
|
|
1392
|
+
|
|
1393
|
+
if codom.is_exact() and den.is_one():
|
|
1394
|
+
return num
|
|
1395
|
+
if check and not den.is_unit():
|
|
1396
|
+
# This should probably be a ValueError.
|
|
1397
|
+
# However, too much existing code is expecting this to throw a
|
|
1398
|
+
# TypeError, so we decided to keep it for the time being.
|
|
1399
|
+
raise TypeError("fraction must have unit denominator")
|
|
1400
|
+
return num * den.inverse_of_unit()
|
|
1401
|
+
|
|
1402
|
+
def _call_with_args(self, x, args=(), kwds={}):
|
|
1403
|
+
r"""
|
|
1404
|
+
Evaluate this map at ``x``.
|
|
1405
|
+
|
|
1406
|
+
INPUT:
|
|
1407
|
+
|
|
1408
|
+
- ``check`` -- whether or not to check
|
|
1409
|
+
|
|
1410
|
+
EXAMPLES::
|
|
1411
|
+
|
|
1412
|
+
sage: R.<x> = QQ[]
|
|
1413
|
+
sage: K = R.fraction_field()
|
|
1414
|
+
sage: R(K.gen(), check=True)
|
|
1415
|
+
x
|
|
1416
|
+
"""
|
|
1417
|
+
check = kwds.get('check', True)
|
|
1418
|
+
if args or any(key != 'check' for key in kwds):
|
|
1419
|
+
raise NotImplementedError("__call__ cannot be called with additional arguments other than check=True/False")
|
|
1420
|
+
return self._call_(x, check=check)
|
|
1421
|
+
|
|
1422
|
+
def _richcmp_(self, other, op):
|
|
1423
|
+
r"""
|
|
1424
|
+
Compare this element to ``other`` with respect to ``op``.
|
|
1425
|
+
|
|
1426
|
+
EXAMPLES::
|
|
1427
|
+
|
|
1428
|
+
sage: R.<x> = QQ[]
|
|
1429
|
+
sage: f = R.fraction_field().coerce_map_from(R).section()
|
|
1430
|
+
sage: S.<y> = GF(2)[]
|
|
1431
|
+
sage: g = S.fraction_field().coerce_map_from(S).section()
|
|
1432
|
+
|
|
1433
|
+
sage: f == g # indirect doctest
|
|
1434
|
+
False
|
|
1435
|
+
sage: f == f
|
|
1436
|
+
True
|
|
1437
|
+
"""
|
|
1438
|
+
if type(self) is not type(other):
|
|
1439
|
+
return NotImplemented
|
|
1440
|
+
return richcmp((self.domain(), self.codomain()), (other.domain(), other.codomain()), op)
|
|
1441
|
+
|
|
1442
|
+
def __hash__(self):
|
|
1443
|
+
r"""
|
|
1444
|
+
Return a hash value for this section.
|
|
1445
|
+
|
|
1446
|
+
EXAMPLES::
|
|
1447
|
+
|
|
1448
|
+
sage: R.<x> = QQ[]
|
|
1449
|
+
sage: hash(R.fraction_field().coerce_map_from(R).section()) == hash(R.fraction_field().coerce_map_from(R).section())
|
|
1450
|
+
True
|
|
1451
|
+
"""
|
|
1452
|
+
return hash((type(self), self.codomain()))
|