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
sage/rings/rational.pyx
ADDED
|
@@ -0,0 +1,4284 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Rational Numbers
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- William Stein (2005): first version
|
|
8
|
+
|
|
9
|
+
- William Stein (2006-02-22): floor and ceil (pure fast GMP versions).
|
|
10
|
+
|
|
11
|
+
- Gonzalo Tornaria and William Stein (2006-03-02): greatly improved
|
|
12
|
+
python/GMP conversion; hashing
|
|
13
|
+
|
|
14
|
+
- William Stein and Naqi Jaffery (2006-03-06): height, sqrt examples,
|
|
15
|
+
and improve behavior of sqrt.
|
|
16
|
+
|
|
17
|
+
- David Harvey (2006-09-15): added nth_root
|
|
18
|
+
|
|
19
|
+
- Pablo De Napoli (2007-04-01): corrected the implementations of
|
|
20
|
+
multiplicative_order, is_one; optimized __bool__ ; documented:
|
|
21
|
+
lcm,gcd
|
|
22
|
+
|
|
23
|
+
- John Cremona (2009-05-15): added support for local and global
|
|
24
|
+
logarithmic heights.
|
|
25
|
+
|
|
26
|
+
- Travis Scrimshaw (2012-10-18): Added doctests for full coverage.
|
|
27
|
+
|
|
28
|
+
- Vincent Delecroix (2013): continued fraction
|
|
29
|
+
|
|
30
|
+
- Vincent Delecroix (2017-05-03): faster integer-rational comparison
|
|
31
|
+
|
|
32
|
+
- Vincent Klein (2017-05-11): add __mpq__() to class Rational
|
|
33
|
+
|
|
34
|
+
- Vincent Klein (2017-05-22): Rational constructor support gmpy2.mpq
|
|
35
|
+
or gmpy2.mpz parameter. Add __mpz__ to class Rational.
|
|
36
|
+
|
|
37
|
+
TESTS::
|
|
38
|
+
|
|
39
|
+
sage: a = -2/3
|
|
40
|
+
sage: a == loads(dumps(a))
|
|
41
|
+
True
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
# ****************************************************************************
|
|
45
|
+
# Copyright (C) 2004, 2006 William Stein <wstein@gmail.com>
|
|
46
|
+
# Copyright (C) 2017 Vincent Delecroix <20100.delecroix@gmail.com>
|
|
47
|
+
#
|
|
48
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
49
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
50
|
+
# the License, or (at your option) any later version.
|
|
51
|
+
# https://www.gnu.org/licenses/
|
|
52
|
+
# ****************************************************************************
|
|
53
|
+
|
|
54
|
+
cimport cython
|
|
55
|
+
from cpython cimport *
|
|
56
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
57
|
+
|
|
58
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
59
|
+
|
|
60
|
+
import operator
|
|
61
|
+
import fractions
|
|
62
|
+
|
|
63
|
+
import sage.rings.rational_field
|
|
64
|
+
|
|
65
|
+
from sage.arith.long cimport integer_check_long_py
|
|
66
|
+
from sage.categories.morphism cimport Morphism
|
|
67
|
+
from sage.categories.map cimport Map
|
|
68
|
+
from sage.cpython.string cimport char_to_str, str_to_bytes
|
|
69
|
+
from sage.libs.gmp.pylong cimport mpz_set_pylong
|
|
70
|
+
from sage.rings.integer cimport Integer, smallInteger
|
|
71
|
+
from sage.rings.integer_ring import ZZ
|
|
72
|
+
from sage.structure.coerce cimport coercion_model, is_numpy_type
|
|
73
|
+
from sage.structure.element cimport Element
|
|
74
|
+
from sage.structure.parent cimport Parent
|
|
75
|
+
from sage.structure.richcmp cimport rich_to_bool_sgn
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
RealNumber_classes = ()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _register_real_number_class(cls):
|
|
82
|
+
r"""
|
|
83
|
+
Register ``cls``.
|
|
84
|
+
|
|
85
|
+
This is called by ``sage.rings.real_mpfr``, to avoid a cyclic import.
|
|
86
|
+
"""
|
|
87
|
+
global RealNumber_classes
|
|
88
|
+
RealNumber_classes += (cls,)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
RealDouble_classes = (float,)
|
|
92
|
+
try:
|
|
93
|
+
from sage.rings.real_double import RealDoubleElement
|
|
94
|
+
RealDouble_classes += (RealDoubleElement,)
|
|
95
|
+
except ImportError:
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
from libc.stdint cimport uint64_t
|
|
100
|
+
from sage.libs.gmp.binop cimport mpq_add_z, mpq_mul_z, mpq_div_zz
|
|
101
|
+
|
|
102
|
+
cimport sage.rings.fast_arith
|
|
103
|
+
import sage.rings.fast_arith
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
from cypari2.gen import Gen as pari_gen
|
|
108
|
+
except ImportError:
|
|
109
|
+
pari_gen = ()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
set_rational_from_gen = None
|
|
113
|
+
new_gen_from_rational = None
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
cdef sage.rings.fast_arith.arith_int ai
|
|
117
|
+
ai = sage.rings.fast_arith.arith_int()
|
|
118
|
+
|
|
119
|
+
cdef object numpy_long_interface = {'typestr': '=i4' if sizeof(long) == 4 else '=i8' }
|
|
120
|
+
cdef object numpy_int64_interface = {'typestr': '=i8'}
|
|
121
|
+
cdef object numpy_object_interface = {'typestr': '|O'}
|
|
122
|
+
cdef object numpy_double_interface = {'typestr': '=f8'}
|
|
123
|
+
|
|
124
|
+
from libc.math cimport ldexp
|
|
125
|
+
from sage.libs.gmp.all cimport *
|
|
126
|
+
|
|
127
|
+
cimport gmpy2
|
|
128
|
+
gmpy2.import_gmpy2()
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
cdef class Rational(sage.structure.element.FieldElement)
|
|
132
|
+
|
|
133
|
+
cdef inline void set_from_mpq(Rational self, mpq_t value) noexcept:
|
|
134
|
+
mpq_set(self.value, value)
|
|
135
|
+
|
|
136
|
+
cdef inline void set_from_Rational(Rational self, Rational other) noexcept:
|
|
137
|
+
mpq_set(self.value, other.value)
|
|
138
|
+
|
|
139
|
+
cdef inline void set_from_Integer(Rational self, integer.Integer other) noexcept:
|
|
140
|
+
mpq_set_z(self.value, other.value)
|
|
141
|
+
|
|
142
|
+
cdef object Rational_mul_(Rational a, Rational b):
|
|
143
|
+
cdef Rational x
|
|
144
|
+
x = <Rational> Rational.__new__(Rational)
|
|
145
|
+
|
|
146
|
+
sig_on()
|
|
147
|
+
mpq_mul(x.value, a.value, b.value)
|
|
148
|
+
sig_off()
|
|
149
|
+
|
|
150
|
+
return x
|
|
151
|
+
|
|
152
|
+
cdef object Rational_div_(Rational a, Rational b):
|
|
153
|
+
cdef Rational x
|
|
154
|
+
x = <Rational> Rational.__new__(Rational)
|
|
155
|
+
|
|
156
|
+
sig_on()
|
|
157
|
+
mpq_div(x.value, a.value, b.value)
|
|
158
|
+
sig_off()
|
|
159
|
+
|
|
160
|
+
return x
|
|
161
|
+
|
|
162
|
+
cdef Rational_add_(Rational self, Rational other):
|
|
163
|
+
cdef Rational x
|
|
164
|
+
x = <Rational> Rational.__new__(Rational)
|
|
165
|
+
sig_on()
|
|
166
|
+
mpq_add(x.value, self.value, other.value)
|
|
167
|
+
sig_off()
|
|
168
|
+
return x
|
|
169
|
+
|
|
170
|
+
cdef Rational_sub_(Rational self, Rational other):
|
|
171
|
+
cdef Rational x
|
|
172
|
+
x = <Rational> Rational.__new__(Rational)
|
|
173
|
+
|
|
174
|
+
sig_on()
|
|
175
|
+
mpq_sub(x.value, self.value, other.value)
|
|
176
|
+
sig_off()
|
|
177
|
+
|
|
178
|
+
return x
|
|
179
|
+
|
|
180
|
+
cdef Parent the_rational_ring = sage.rings.rational_field.Q
|
|
181
|
+
|
|
182
|
+
# make sure zero/one elements are set
|
|
183
|
+
cdef set_zero_one_elements():
|
|
184
|
+
global the_rational_ring
|
|
185
|
+
the_rational_ring._zero_element = Rational(0)
|
|
186
|
+
the_rational_ring._one_element = Rational(1)
|
|
187
|
+
|
|
188
|
+
set_zero_one_elements()
|
|
189
|
+
|
|
190
|
+
cpdef Integer integer_rational_power(Integer a, Rational b):
|
|
191
|
+
"""
|
|
192
|
+
Compute `a^b` as an integer, if it is integral, or return ``None``.
|
|
193
|
+
|
|
194
|
+
The nonnegative real root is taken for even denominators.
|
|
195
|
+
|
|
196
|
+
INPUT:
|
|
197
|
+
|
|
198
|
+
- ``a`` -- an ``Integer``
|
|
199
|
+
- ``b`` -- a nonnegative ``Rational``
|
|
200
|
+
|
|
201
|
+
OUTPUT: `a^b` as an ``Integer`` or ``None``
|
|
202
|
+
|
|
203
|
+
EXAMPLES::
|
|
204
|
+
|
|
205
|
+
sage: from sage.rings.rational import integer_rational_power
|
|
206
|
+
sage: integer_rational_power(49, 1/2)
|
|
207
|
+
7
|
|
208
|
+
sage: integer_rational_power(27, 1/3)
|
|
209
|
+
3
|
|
210
|
+
sage: integer_rational_power(-27, 1/3) is None
|
|
211
|
+
True
|
|
212
|
+
sage: integer_rational_power(-27, 2/3) is None
|
|
213
|
+
True
|
|
214
|
+
sage: integer_rational_power(512, 7/9)
|
|
215
|
+
128
|
|
216
|
+
|
|
217
|
+
sage: integer_rational_power(27, 1/4) is None
|
|
218
|
+
True
|
|
219
|
+
sage: integer_rational_power(-16, 1/4) is None
|
|
220
|
+
True
|
|
221
|
+
|
|
222
|
+
sage: integer_rational_power(0, 7/9)
|
|
223
|
+
0
|
|
224
|
+
sage: integer_rational_power(1, 7/9)
|
|
225
|
+
1
|
|
226
|
+
sage: integer_rational_power(-1, 7/9) is None
|
|
227
|
+
True
|
|
228
|
+
sage: integer_rational_power(-1, 8/9) is None
|
|
229
|
+
True
|
|
230
|
+
sage: integer_rational_power(-1, 9/8) is None
|
|
231
|
+
True
|
|
232
|
+
|
|
233
|
+
TESTS (:issue:`11228`)::
|
|
234
|
+
|
|
235
|
+
sage: integer_rational_power(-10, QQ(2))
|
|
236
|
+
100
|
|
237
|
+
sage: integer_rational_power(0, QQ(0))
|
|
238
|
+
1
|
|
239
|
+
"""
|
|
240
|
+
cdef Integer z = Integer.__new__(Integer)
|
|
241
|
+
if mpz_sgn(mpq_numref(b.value)) < 0:
|
|
242
|
+
raise ValueError("Only positive exponents supported.")
|
|
243
|
+
cdef int sgn = mpz_sgn(a.value)
|
|
244
|
+
cdef bint exact
|
|
245
|
+
if (mpz_cmp_ui(a.value, 1) == 0 or
|
|
246
|
+
mpz_cmp_ui(mpq_numref(b.value), 0) == 0):
|
|
247
|
+
mpz_set_ui(z.value, 1)
|
|
248
|
+
elif sgn == 0:
|
|
249
|
+
pass # z is 0
|
|
250
|
+
elif sgn < 0 and mpz_cmp_ui(mpq_denref(b.value), 1):
|
|
251
|
+
return None
|
|
252
|
+
else:
|
|
253
|
+
if (not mpz_fits_ulong_p(mpq_numref(b.value))
|
|
254
|
+
or not mpz_fits_ulong_p(mpq_denref(b.value))):
|
|
255
|
+
# too big to take roots/powers
|
|
256
|
+
return None
|
|
257
|
+
elif mpz_cmp_ui(mpq_denref(b.value), 2) == 0:
|
|
258
|
+
if mpz_perfect_square_p(a.value):
|
|
259
|
+
mpz_sqrt(z.value, a.value)
|
|
260
|
+
else:
|
|
261
|
+
return None
|
|
262
|
+
else:
|
|
263
|
+
exact = mpz_root(z.value, a.value, mpz_get_ui(mpq_denref(b.value)))
|
|
264
|
+
if not exact:
|
|
265
|
+
return None
|
|
266
|
+
mpz_pow_ui(z.value, z.value, mpz_get_ui(mpq_numref(b.value)))
|
|
267
|
+
return z
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
cpdef rational_power_parts(a, Rational b, factor_limit=10**5):
|
|
271
|
+
"""
|
|
272
|
+
Compute rationals or integers `c` and `d` such that `a^b = c*d^b`
|
|
273
|
+
with `d` small. This is used for simplifying radicals.
|
|
274
|
+
|
|
275
|
+
INPUT:
|
|
276
|
+
|
|
277
|
+
- ``a`` -- a rational or integer
|
|
278
|
+
- ``b`` -- a rational
|
|
279
|
+
- ``factor_limit`` -- the limit used in factoring ``a``
|
|
280
|
+
|
|
281
|
+
EXAMPLES::
|
|
282
|
+
|
|
283
|
+
sage: from sage.rings.rational import rational_power_parts
|
|
284
|
+
sage: rational_power_parts(27, 1/2)
|
|
285
|
+
(3, 3)
|
|
286
|
+
sage: rational_power_parts(-128, 3/4)
|
|
287
|
+
(8, -8)
|
|
288
|
+
sage: rational_power_parts(-4, 1/2)
|
|
289
|
+
(2, -1)
|
|
290
|
+
sage: rational_power_parts(-4, 1/3)
|
|
291
|
+
(1, -4)
|
|
292
|
+
sage: rational_power_parts(9/1000, 1/2)
|
|
293
|
+
(3/10, 1/10)
|
|
294
|
+
|
|
295
|
+
TESTS:
|
|
296
|
+
|
|
297
|
+
Check if :issue:`8540` is fixed::
|
|
298
|
+
|
|
299
|
+
sage: rational_power_parts(3/4, -1/2)
|
|
300
|
+
(2, 3)
|
|
301
|
+
sage: t = (3/4)^(-1/2); t # needs sage.symbolic
|
|
302
|
+
2/3*sqrt(3)
|
|
303
|
+
sage: t^2 # needs sage.symbolic
|
|
304
|
+
4/3
|
|
305
|
+
|
|
306
|
+
Check if :issue:`15605` is fixed::
|
|
307
|
+
|
|
308
|
+
sage: rational_power_parts(-1, -1/3)
|
|
309
|
+
(1, -1)
|
|
310
|
+
sage: rational_power_parts(-1, 2/3)
|
|
311
|
+
(1, -1)
|
|
312
|
+
sage: all(rational_power_parts(-1, i/77) == (1,-1) for i in range(1,9))
|
|
313
|
+
True
|
|
314
|
+
|
|
315
|
+
sage: # needs sage.symbolic
|
|
316
|
+
sage: (-1)^(-1/3)
|
|
317
|
+
-(-1)^(2/3)
|
|
318
|
+
sage: 1 / ((-1)^(1/3))
|
|
319
|
+
-(-1)^(2/3)
|
|
320
|
+
sage: (-1)^(2/3)
|
|
321
|
+
(-1)^(2/3)
|
|
322
|
+
sage: (-1)^(1/3)*(-1)^(1/5)
|
|
323
|
+
(-1)^(8/15)
|
|
324
|
+
sage: bool((-1)^(2/3) == -1/2 + sqrt(3)/2*I)
|
|
325
|
+
True
|
|
326
|
+
sage: all((-1)^(p/q) == cos(p*pi/q) + I * sin(p*pi/q)
|
|
327
|
+
....: for p in srange(1, 6) for q in srange(1, 6))
|
|
328
|
+
True
|
|
329
|
+
|
|
330
|
+
A few more tests added in :issue:`26414`::
|
|
331
|
+
|
|
332
|
+
sage: rational_power_parts(-1, 2/1)
|
|
333
|
+
(1, 1)
|
|
334
|
+
sage: rational_power_parts(-8, 2/3)
|
|
335
|
+
(4, -1)
|
|
336
|
+
sage: all(isinstance(z, Integer) for z in rational_power_parts(-1, 1/1))
|
|
337
|
+
True
|
|
338
|
+
sage: all(isinstance(z, Integer) for z in rational_power_parts(-1, 2/3))
|
|
339
|
+
True
|
|
340
|
+
"""
|
|
341
|
+
cdef bint b_negative = (b < 0)
|
|
342
|
+
if b_negative:
|
|
343
|
+
b = -b
|
|
344
|
+
a = ~a
|
|
345
|
+
|
|
346
|
+
if isinstance(a, Integer):
|
|
347
|
+
pass
|
|
348
|
+
elif isinstance(a, Rational):
|
|
349
|
+
c1, d1 = rational_power_parts(a.numerator(), b)
|
|
350
|
+
c2, d2 = rational_power_parts(a.denominator(), b)
|
|
351
|
+
return (c1/c2, d1/d2) if not b_negative else (c1/c2, d2/d1)
|
|
352
|
+
else:
|
|
353
|
+
a = Integer(a)
|
|
354
|
+
|
|
355
|
+
c = integer_rational_power(a, b)
|
|
356
|
+
if c is not None:
|
|
357
|
+
return c, smallInteger(1)
|
|
358
|
+
|
|
359
|
+
numer, denom = b.numerator(), b.denominator()
|
|
360
|
+
if a < factor_limit*factor_limit:
|
|
361
|
+
f = a.factor()
|
|
362
|
+
else:
|
|
363
|
+
from sage.rings.factorint import factor_trial_division
|
|
364
|
+
f = factor_trial_division(a, factor_limit)
|
|
365
|
+
c = smallInteger(1)
|
|
366
|
+
# The sign is not handled by the loop below. We don't want to
|
|
367
|
+
# simplify (-1)^(2/3) to 1 (see Issue #15605), so we always move
|
|
368
|
+
# the sign over to d. Note that the case (-1)^2 is already
|
|
369
|
+
# handled by integer_rational_power() above.
|
|
370
|
+
if a >= 0:
|
|
371
|
+
# d = 1
|
|
372
|
+
d = c
|
|
373
|
+
else:
|
|
374
|
+
# d = -1
|
|
375
|
+
d = smallInteger(-1)
|
|
376
|
+
for p, e in f:
|
|
377
|
+
c *= p**((e // denom)*numer)
|
|
378
|
+
d *= p**(e % denom)
|
|
379
|
+
return (c, d) if not b_negative else (c, ~d)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def is_Rational(x):
|
|
383
|
+
"""
|
|
384
|
+
Return ``True`` if ``x`` is of the Sage :class:`Rational` type.
|
|
385
|
+
|
|
386
|
+
EXAMPLES::
|
|
387
|
+
|
|
388
|
+
sage: from sage.rings.rational import is_Rational
|
|
389
|
+
sage: is_Rational(2)
|
|
390
|
+
doctest:warning...
|
|
391
|
+
DeprecationWarning: The function is_Rational is deprecated;
|
|
392
|
+
use 'isinstance(..., Rational)' instead.
|
|
393
|
+
See https://github.com/sagemath/sage/issues/38128 for details.
|
|
394
|
+
False
|
|
395
|
+
sage: is_Rational(2/1)
|
|
396
|
+
True
|
|
397
|
+
sage: is_Rational(int(2))
|
|
398
|
+
False
|
|
399
|
+
sage: is_Rational('5')
|
|
400
|
+
False
|
|
401
|
+
"""
|
|
402
|
+
from sage.misc.superseded import deprecation_cython
|
|
403
|
+
deprecation_cython(38128,
|
|
404
|
+
"The function is_Rational is deprecated; "
|
|
405
|
+
"use 'isinstance(..., Rational)' instead.")
|
|
406
|
+
return isinstance(x, Rational)
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
cdef class Rational(sage.structure.element.FieldElement):
|
|
410
|
+
"""
|
|
411
|
+
A rational number.
|
|
412
|
+
|
|
413
|
+
Rational numbers are implemented using the GMP C library.
|
|
414
|
+
|
|
415
|
+
EXAMPLES::
|
|
416
|
+
|
|
417
|
+
sage: a = -2/3
|
|
418
|
+
sage: type(a)
|
|
419
|
+
<class 'sage.rings.rational.Rational'>
|
|
420
|
+
sage: parent(a)
|
|
421
|
+
Rational Field
|
|
422
|
+
sage: Rational('1/0')
|
|
423
|
+
Traceback (most recent call last):
|
|
424
|
+
...
|
|
425
|
+
TypeError: unable to convert '1/0' to a rational
|
|
426
|
+
sage: Rational(1.5)
|
|
427
|
+
3/2
|
|
428
|
+
sage: Rational('9/6')
|
|
429
|
+
3/2
|
|
430
|
+
sage: Rational((2^99,2^100))
|
|
431
|
+
1/2
|
|
432
|
+
sage: Rational(("2", "10"), 16)
|
|
433
|
+
1/8
|
|
434
|
+
sage: Rational(QQbar(125/8).nth_root(3)) # needs sage.rings.number_field
|
|
435
|
+
5/2
|
|
436
|
+
sage: Rational(AA(209735/343 - 17910/49*golden_ratio).nth_root(3) # needs sage.rings.number_field sage.symbolic
|
|
437
|
+
....: + 3*AA(golden_ratio))
|
|
438
|
+
53/7
|
|
439
|
+
sage: QQ(float(1.5))
|
|
440
|
+
3/2
|
|
441
|
+
sage: QQ(RDF(1.2))
|
|
442
|
+
6/5
|
|
443
|
+
|
|
444
|
+
Conversion from fractions::
|
|
445
|
+
|
|
446
|
+
sage: import fractions
|
|
447
|
+
sage: f = fractions.Fraction(1r, 2r)
|
|
448
|
+
sage: Rational(f)
|
|
449
|
+
1/2
|
|
450
|
+
|
|
451
|
+
Conversion from PARI::
|
|
452
|
+
|
|
453
|
+
sage: Rational(pari('-939082/3992923')) # needs sage.libs.pari
|
|
454
|
+
-939082/3992923
|
|
455
|
+
sage: Rational(pari('Pol([-1/2])')) #9595 # needs sage.libs.pari
|
|
456
|
+
-1/2
|
|
457
|
+
|
|
458
|
+
Conversions from numpy::
|
|
459
|
+
|
|
460
|
+
sage: # needs numpy
|
|
461
|
+
sage: import numpy as np
|
|
462
|
+
sage: QQ(np.int8('-15'))
|
|
463
|
+
-15
|
|
464
|
+
sage: QQ(np.int16('-32'))
|
|
465
|
+
-32
|
|
466
|
+
sage: QQ(np.int32('-19'))
|
|
467
|
+
-19
|
|
468
|
+
sage: QQ(np.uint32('1412'))
|
|
469
|
+
1412
|
|
470
|
+
|
|
471
|
+
sage: QQ(np.float16('12')) # needs numpy
|
|
472
|
+
12
|
|
473
|
+
|
|
474
|
+
Conversions from gmpy2::
|
|
475
|
+
|
|
476
|
+
sage: from gmpy2 import *
|
|
477
|
+
sage: QQ(mpq('3/4'))
|
|
478
|
+
3/4
|
|
479
|
+
sage: QQ(mpz(42))
|
|
480
|
+
42
|
|
481
|
+
sage: Rational(mpq(2/3))
|
|
482
|
+
2/3
|
|
483
|
+
sage: Rational(mpz(5))
|
|
484
|
+
5
|
|
485
|
+
|
|
486
|
+
TESTS:
|
|
487
|
+
|
|
488
|
+
Check that :issue:`28321` is fixed::
|
|
489
|
+
|
|
490
|
+
sage: QQ((2r^100r, 3r^100r))
|
|
491
|
+
1267650600228229401496703205376/515377520732011331036461129765621272702107522001
|
|
492
|
+
sage: QQ((-2r^100r, -3r^100r))
|
|
493
|
+
1267650600228229401496703205376/515377520732011331036461129765621272702107522001
|
|
494
|
+
"""
|
|
495
|
+
def __cinit__(self):
|
|
496
|
+
r"""
|
|
497
|
+
Initialize ``self`` as an element of `\QQ`.
|
|
498
|
+
|
|
499
|
+
EXAMPLES::
|
|
500
|
+
|
|
501
|
+
sage: p = Rational(3) # indirect doctest
|
|
502
|
+
sage: p.parent()
|
|
503
|
+
Rational Field
|
|
504
|
+
"""
|
|
505
|
+
global the_rational_ring
|
|
506
|
+
mpq_init(self.value)
|
|
507
|
+
self._parent = the_rational_ring
|
|
508
|
+
|
|
509
|
+
def __init__(self, x=None, unsigned int base=0):
|
|
510
|
+
"""
|
|
511
|
+
Create a new rational number.
|
|
512
|
+
|
|
513
|
+
INPUT:
|
|
514
|
+
|
|
515
|
+
- ``x`` -- object (default: ``None``)
|
|
516
|
+
|
|
517
|
+
- ``base`` -- base if ``x`` is a string
|
|
518
|
+
|
|
519
|
+
EXAMPLES::
|
|
520
|
+
|
|
521
|
+
sage: a = Rational()
|
|
522
|
+
sage: a.__init__(7); a
|
|
523
|
+
7
|
|
524
|
+
sage: a.__init__('70', base=8); a
|
|
525
|
+
56
|
|
526
|
+
sage: a.__init__(pari('2/3')); a # needs sage.libs.pari
|
|
527
|
+
2/3
|
|
528
|
+
sage: a.__init__('-h/3ki', 32); a
|
|
529
|
+
-17/3730
|
|
530
|
+
sage: from gmpy2 import mpq
|
|
531
|
+
sage: a.__init__(mpq('3/5')); a
|
|
532
|
+
3/5
|
|
533
|
+
|
|
534
|
+
TESTS:
|
|
535
|
+
|
|
536
|
+
Check that :issue:`19835` is fixed::
|
|
537
|
+
|
|
538
|
+
sage: QQ((0r,-1r))
|
|
539
|
+
0
|
|
540
|
+
sage: QQ((-1r,-1r))
|
|
541
|
+
1
|
|
542
|
+
|
|
543
|
+
.. NOTE::
|
|
544
|
+
|
|
545
|
+
This is for doctesting purposes only. Rationals are defined
|
|
546
|
+
to be immutable.
|
|
547
|
+
"""
|
|
548
|
+
if x is not None:
|
|
549
|
+
self.__set_value(x, base)
|
|
550
|
+
|
|
551
|
+
def __reduce__(self):
|
|
552
|
+
"""
|
|
553
|
+
Used in pickling rational numbers.
|
|
554
|
+
|
|
555
|
+
EXAMPLES::
|
|
556
|
+
|
|
557
|
+
sage: a = 3/5
|
|
558
|
+
sage: a.__reduce__()
|
|
559
|
+
(<cyfunction make_rational at ...>, ('3/5',))
|
|
560
|
+
"""
|
|
561
|
+
return sage.rings.rational.make_rational, (self.str(32),)
|
|
562
|
+
|
|
563
|
+
def __index__(self):
|
|
564
|
+
"""
|
|
565
|
+
Needed so integers can be used as list indices.
|
|
566
|
+
|
|
567
|
+
EXAMPLES::
|
|
568
|
+
|
|
569
|
+
sage: v = [1,2,3,4,5]
|
|
570
|
+
sage: v[3/1]
|
|
571
|
+
4
|
|
572
|
+
sage: v[3/2]
|
|
573
|
+
Traceback (most recent call last):
|
|
574
|
+
...
|
|
575
|
+
TypeError: unable to convert rational 3/2 to an integer
|
|
576
|
+
"""
|
|
577
|
+
if self.denominator() == 1:
|
|
578
|
+
return int(self)
|
|
579
|
+
|
|
580
|
+
raise TypeError(f"unable to convert rational {self} to an integer")
|
|
581
|
+
|
|
582
|
+
cdef __set_value(self, x, unsigned int base):
|
|
583
|
+
cdef int n
|
|
584
|
+
cdef Rational temp_rational
|
|
585
|
+
cdef integer.Integer a, b
|
|
586
|
+
|
|
587
|
+
if isinstance(x, Rational):
|
|
588
|
+
set_from_Rational(self, x)
|
|
589
|
+
|
|
590
|
+
elif isinstance(x, int):
|
|
591
|
+
mpz_set_pylong(mpq_numref(self.value), x)
|
|
592
|
+
|
|
593
|
+
elif isinstance(x, integer.Integer):
|
|
594
|
+
set_from_Integer(self, x)
|
|
595
|
+
|
|
596
|
+
elif isinstance(x, RealNumber_classes):
|
|
597
|
+
|
|
598
|
+
if x == 0:
|
|
599
|
+
mpq_set_si(self.value, 0, 1)
|
|
600
|
+
return
|
|
601
|
+
if not base:
|
|
602
|
+
set_from_Rational(self, x.simplest_rational())
|
|
603
|
+
else:
|
|
604
|
+
# Truncate in base 10 to match repr(x).
|
|
605
|
+
# See https://github.com/sagemath/sage/issues/21124
|
|
606
|
+
xstr = x.str(base, truncate=(base == 10))
|
|
607
|
+
if '.' in xstr:
|
|
608
|
+
exp = (len(xstr) - (xstr.index('.') +1))
|
|
609
|
+
p = base**exp
|
|
610
|
+
pstr = '1'+'0'*exp
|
|
611
|
+
s = xstr.replace('.','') +'/'+pstr
|
|
612
|
+
n = mpq_set_str(self.value, str_to_bytes(s), base)
|
|
613
|
+
if n or mpz_cmp_si(mpq_denref(self.value), 0) == 0:
|
|
614
|
+
raise TypeError("unable to convert {!r} to a rational".format(x))
|
|
615
|
+
mpq_canonicalize(self.value)
|
|
616
|
+
else:
|
|
617
|
+
n = mpq_set_str(self.value, xstr, base)
|
|
618
|
+
if n or mpz_cmp_si(mpq_denref(self.value), 0) == 0:
|
|
619
|
+
raise TypeError("unable to convert {!r} to a rational".format(x))
|
|
620
|
+
mpq_canonicalize(self.value)
|
|
621
|
+
elif isinstance(x, bytes):
|
|
622
|
+
n = mpq_set_str(self.value, x, base)
|
|
623
|
+
if n or mpz_cmp_si(mpq_denref(self.value), 0) == 0:
|
|
624
|
+
raise TypeError("unable to convert {!r} to a rational".format(x))
|
|
625
|
+
mpq_canonicalize(self.value)
|
|
626
|
+
elif isinstance(x, unicode):
|
|
627
|
+
n = mpq_set_str(self.value, str_to_bytes(x), base)
|
|
628
|
+
if n or mpz_cmp_si(mpq_denref(self.value), 0) == 0:
|
|
629
|
+
raise TypeError("unable to convert {!r} to a rational".format(x))
|
|
630
|
+
mpq_canonicalize(self.value)
|
|
631
|
+
|
|
632
|
+
elif hasattr(x, "_rational_"):
|
|
633
|
+
set_from_Rational(self, x._rational_())
|
|
634
|
+
|
|
635
|
+
elif isinstance(x, tuple) and len(x) == 2:
|
|
636
|
+
num = x[0]
|
|
637
|
+
denom = x[1]
|
|
638
|
+
|
|
639
|
+
if isinstance(num, int):
|
|
640
|
+
mpz_set_pylong(mpq_numref(self.value), num)
|
|
641
|
+
else:
|
|
642
|
+
if not isinstance(num, integer.Integer):
|
|
643
|
+
num = integer.Integer(num, base)
|
|
644
|
+
mpz_set(mpq_numref(self.value), (<integer.Integer>num).value)
|
|
645
|
+
|
|
646
|
+
if isinstance(denom, int):
|
|
647
|
+
mpz_set_pylong(mpq_denref(self.value), denom)
|
|
648
|
+
else:
|
|
649
|
+
if not isinstance(denom, integer.Integer):
|
|
650
|
+
denom = integer.Integer(denom, base)
|
|
651
|
+
mpz_set(mpq_denref(self.value), (<integer.Integer>denom).value)
|
|
652
|
+
|
|
653
|
+
if mpz_sgn(mpq_denref(self.value)) == 0:
|
|
654
|
+
raise ValueError("denominator must not be 0")
|
|
655
|
+
|
|
656
|
+
mpq_canonicalize(self.value)
|
|
657
|
+
|
|
658
|
+
elif isinstance(x, pari_gen):
|
|
659
|
+
global set_rational_from_gen
|
|
660
|
+
if set_rational_from_gen is None:
|
|
661
|
+
from sage.libs.pari.convert_sage import set_rational_from_gen
|
|
662
|
+
set_rational_from_gen(self, x)
|
|
663
|
+
|
|
664
|
+
elif isinstance(x, list) and len(x) == 1:
|
|
665
|
+
self.__set_value(x[0], base)
|
|
666
|
+
|
|
667
|
+
elif hasattr(x, 'rational_reconstruction'):
|
|
668
|
+
temp_rational = x.rational_reconstruction()
|
|
669
|
+
mpq_set(self.value, temp_rational.value)
|
|
670
|
+
|
|
671
|
+
elif isinstance(x, (float, sage.rings.real_double.RealDoubleElement)):
|
|
672
|
+
try:
|
|
673
|
+
from sage.rings.real_mpfr import RR, RealNumber
|
|
674
|
+
except ImportError:
|
|
675
|
+
if base:
|
|
676
|
+
raise
|
|
677
|
+
from fractions import Fraction
|
|
678
|
+
self.__set_value(Fraction.from_float(float(x)), 0)
|
|
679
|
+
else:
|
|
680
|
+
self.__set_value(RealNumber(RR, x), base)
|
|
681
|
+
|
|
682
|
+
elif is_numpy_type(type(x)):
|
|
683
|
+
import numpy
|
|
684
|
+
if isinstance(x, numpy.integer):
|
|
685
|
+
self.__set_value(integer.Integer(x), base)
|
|
686
|
+
elif isinstance(x, numpy.floating):
|
|
687
|
+
from sage.rings.real_mpfr import RR
|
|
688
|
+
self.__set_value(RR(x), base)
|
|
689
|
+
else:
|
|
690
|
+
raise TypeError("unable to convert {!r} to a rational".format(x))
|
|
691
|
+
|
|
692
|
+
elif isinstance(x, fractions.Fraction):
|
|
693
|
+
mpz_set(mpq_numref(self.value), (<integer.Integer> integer.Integer(x.numerator)).value)
|
|
694
|
+
mpz_set(mpq_denref(self.value), (<integer.Integer> integer.Integer(x.denominator)).value)
|
|
695
|
+
|
|
696
|
+
elif type(x) is gmpy2.mpq:
|
|
697
|
+
mpq_set(self.value, (<gmpy2.mpq>x).q)
|
|
698
|
+
|
|
699
|
+
elif type(x) is gmpy2.mpz:
|
|
700
|
+
mpq_set_z(self.value, (<gmpy2.mpz>x).z)
|
|
701
|
+
|
|
702
|
+
else:
|
|
703
|
+
raise TypeError("unable to convert {!r} to a rational".format(x))
|
|
704
|
+
|
|
705
|
+
cdef void set_from_mpq(Rational self, mpq_t value) noexcept:
|
|
706
|
+
mpq_set(self.value, value)
|
|
707
|
+
|
|
708
|
+
def list(self):
|
|
709
|
+
"""
|
|
710
|
+
Return a list with the rational element in it, to be compatible
|
|
711
|
+
with the method for number fields.
|
|
712
|
+
|
|
713
|
+
OUTPUT: the list ``[self]``
|
|
714
|
+
|
|
715
|
+
EXAMPLES::
|
|
716
|
+
|
|
717
|
+
sage: m = 5/3
|
|
718
|
+
sage: m.list()
|
|
719
|
+
[5/3]
|
|
720
|
+
"""
|
|
721
|
+
return [ self ]
|
|
722
|
+
|
|
723
|
+
def continued_fraction_list(self, type='std'):
|
|
724
|
+
r"""
|
|
725
|
+
Return the list of partial quotients of this rational number.
|
|
726
|
+
|
|
727
|
+
INPUT:
|
|
728
|
+
|
|
729
|
+
- ``type`` -- either ``'std'`` (the default) for the standard continued
|
|
730
|
+
fractions or ``'hj'`` for the Hirzebruch-Jung ones
|
|
731
|
+
|
|
732
|
+
EXAMPLES::
|
|
733
|
+
|
|
734
|
+
sage: (13/9).continued_fraction_list()
|
|
735
|
+
[1, 2, 4]
|
|
736
|
+
sage: 1 + 1/(2 + 1/4)
|
|
737
|
+
13/9
|
|
738
|
+
|
|
739
|
+
sage: (225/157).continued_fraction_list()
|
|
740
|
+
[1, 2, 3, 4, 5]
|
|
741
|
+
sage: 1 + 1/(2 + 1/(3 + 1/(4 + 1/5)))
|
|
742
|
+
225/157
|
|
743
|
+
|
|
744
|
+
sage: (fibonacci(20)/fibonacci(19)).continued_fraction_list() # needs sage.libs.pari
|
|
745
|
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]
|
|
746
|
+
|
|
747
|
+
sage: (-1/3).continued_fraction_list()
|
|
748
|
+
[-1, 1, 2]
|
|
749
|
+
|
|
750
|
+
Check that the partial quotients of an integer ``n`` is simply ``[n]``::
|
|
751
|
+
|
|
752
|
+
sage: QQ(1).continued_fraction_list()
|
|
753
|
+
[1]
|
|
754
|
+
sage: QQ(0).continued_fraction_list()
|
|
755
|
+
[0]
|
|
756
|
+
sage: QQ(-1).continued_fraction_list()
|
|
757
|
+
[-1]
|
|
758
|
+
|
|
759
|
+
Hirzebruch-Jung continued fractions::
|
|
760
|
+
|
|
761
|
+
sage: (11/19).continued_fraction_list("hj")
|
|
762
|
+
[1, 3, 2, 3, 2]
|
|
763
|
+
sage: 1 - 1/(3 - 1/(2 - 1/(3 - 1/2)))
|
|
764
|
+
11/19
|
|
765
|
+
|
|
766
|
+
sage: (225/137).continued_fraction_list("hj")
|
|
767
|
+
[2, 3, 5, 10]
|
|
768
|
+
sage: 2 - 1/(3 - 1/(5 - 1/10))
|
|
769
|
+
225/137
|
|
770
|
+
|
|
771
|
+
sage: (-23/19).continued_fraction_list("hj")
|
|
772
|
+
[-1, 5, 4]
|
|
773
|
+
sage: -1 - 1/(5 - 1/4)
|
|
774
|
+
-23/19
|
|
775
|
+
"""
|
|
776
|
+
cdef Integer z
|
|
777
|
+
cdef mpz_t p,q,tmp
|
|
778
|
+
cdef list res = []
|
|
779
|
+
|
|
780
|
+
mpz_init(tmp)
|
|
781
|
+
mpz_init(p)
|
|
782
|
+
mpz_init(q)
|
|
783
|
+
mpz_set(p, mpq_numref(self.value))
|
|
784
|
+
mpz_set(q, mpq_denref(self.value))
|
|
785
|
+
|
|
786
|
+
if type == "std":
|
|
787
|
+
while mpz_sgn(q) != 0:
|
|
788
|
+
z = Integer.__new__(Integer)
|
|
789
|
+
mpz_fdiv_qr(z.value,tmp,p,q)
|
|
790
|
+
mpz_set(p,q)
|
|
791
|
+
mpz_set(q,tmp)
|
|
792
|
+
res.append(z)
|
|
793
|
+
elif type == "hj":
|
|
794
|
+
while mpz_sgn(q) != 0:
|
|
795
|
+
z = Integer.__new__(Integer)
|
|
796
|
+
mpz_cdiv_qr(z.value,tmp,p,q)
|
|
797
|
+
mpz_set(p,q)
|
|
798
|
+
mpz_set(q,tmp)
|
|
799
|
+
res.append(z)
|
|
800
|
+
if mpz_sgn(q) == 0:
|
|
801
|
+
break
|
|
802
|
+
z = Integer.__new__(Integer)
|
|
803
|
+
mpz_fdiv_qr(z.value,tmp,p,q)
|
|
804
|
+
mpz_set(p,q)
|
|
805
|
+
mpz_set(q,tmp)
|
|
806
|
+
mpz_neg(z.value,z.value)
|
|
807
|
+
res.append(z)
|
|
808
|
+
else:
|
|
809
|
+
mpz_clear(p)
|
|
810
|
+
mpz_clear(q)
|
|
811
|
+
mpz_clear(tmp)
|
|
812
|
+
raise ValueError("the type must be one of 'floor', 'hj'")
|
|
813
|
+
|
|
814
|
+
mpz_clear(p)
|
|
815
|
+
mpz_clear(q)
|
|
816
|
+
mpz_clear(tmp)
|
|
817
|
+
|
|
818
|
+
return res
|
|
819
|
+
|
|
820
|
+
def continued_fraction(self):
|
|
821
|
+
r"""
|
|
822
|
+
Return the continued fraction of that rational.
|
|
823
|
+
|
|
824
|
+
EXAMPLES::
|
|
825
|
+
|
|
826
|
+
sage: (641/472).continued_fraction()
|
|
827
|
+
[1; 2, 1, 3, 1, 4, 1, 5]
|
|
828
|
+
|
|
829
|
+
sage: a = (355/113).continued_fraction(); a
|
|
830
|
+
[3; 7, 16]
|
|
831
|
+
sage: a.n(digits=10) # needs sage.rings.real_mpfr
|
|
832
|
+
3.141592920
|
|
833
|
+
sage: pi.n(digits=10) # needs sage.rings.real_mpfr sage.symbolic
|
|
834
|
+
3.141592654
|
|
835
|
+
|
|
836
|
+
It's almost pi!
|
|
837
|
+
"""
|
|
838
|
+
#TODO: do better
|
|
839
|
+
from sage.rings.continued_fraction import ContinuedFraction_periodic
|
|
840
|
+
l = self.continued_fraction_list()
|
|
841
|
+
return ContinuedFraction_periodic(l)
|
|
842
|
+
|
|
843
|
+
cpdef _richcmp_(left, right, int op):
|
|
844
|
+
"""
|
|
845
|
+
Compare two rational numbers.
|
|
846
|
+
|
|
847
|
+
INPUT:
|
|
848
|
+
|
|
849
|
+
- ``left``, ``right`` -- objects
|
|
850
|
+
|
|
851
|
+
- ``op`` -- integer
|
|
852
|
+
|
|
853
|
+
EXAMPLES::
|
|
854
|
+
|
|
855
|
+
sage: 1/3 < 2/3
|
|
856
|
+
True
|
|
857
|
+
sage: 2/3 < 1/3
|
|
858
|
+
False
|
|
859
|
+
sage: 4/5 < 2.0
|
|
860
|
+
True
|
|
861
|
+
sage: 4/5 < 0.8
|
|
862
|
+
False
|
|
863
|
+
|
|
864
|
+
sage: ones = [1, 1r, 1l, 1/1, 1.0r, 1.0]
|
|
865
|
+
sage: twos = [2, 2r, 2l, 2/1, 2.0r, 2.0]
|
|
866
|
+
sage: threes = [3, 3r, 3l, 3/1, 3.0r, 3.0]
|
|
867
|
+
sage: from itertools import product
|
|
868
|
+
sage: for one,two,three in product(ones,twos,threes):
|
|
869
|
+
....: assert one < two < three
|
|
870
|
+
....: assert one <= two <= three
|
|
871
|
+
....: assert three > two > one
|
|
872
|
+
....: assert three >= two >= one
|
|
873
|
+
....: assert one != two and one != three and two != three
|
|
874
|
+
sage: for one1, one2 in product(ones,repeat=2):
|
|
875
|
+
....: assert (one1 == one2) is True
|
|
876
|
+
....: assert (one1 <= one2) is True
|
|
877
|
+
....: assert (one1 >= one2) is True
|
|
878
|
+
|
|
879
|
+
Comparisons with gmpy2 values (:issue:`28394`)::
|
|
880
|
+
|
|
881
|
+
sage: import gmpy2
|
|
882
|
+
sage: values = [(-2,5),(-1,3),(0,1),(2,9),(1,1),(73,2)]
|
|
883
|
+
sage: for num1, den1 in values:
|
|
884
|
+
....: for num2, den2 in values:
|
|
885
|
+
....: a1 = QQ((num1, den1))
|
|
886
|
+
....: a2 = QQ((num2, den2))
|
|
887
|
+
....: b1 = gmpy2.mpq(num1, den1)
|
|
888
|
+
....: b2 = gmpy2.mpq(num2, den2)
|
|
889
|
+
....: assert a1 == b1 and b1 == a1 and a2 == b2 and b2 == a2
|
|
890
|
+
....: assert (a1 == a2) == (b1 == b2) == (a1 == b2) == (b1 == a2)
|
|
891
|
+
....: assert (a1 != a2) == (b1 != b2) == (a1 != b2) == (b1 != a2)
|
|
892
|
+
....: assert (a1 < a2) == (b1 < b2) == (a1 < b2) == (b1 < a2)
|
|
893
|
+
....: assert (a1 <= a2) == (b1 <= b2) == (a1 <= b2) == (b1 <= a2)
|
|
894
|
+
....: assert (a1 > a2) == (b1 > b2) == (a1 > b2) == (b1 > a2)
|
|
895
|
+
....: assert (a1 >= a2) == (b1 >= b2) == (a1 >= b2) == (b1 >= a2)
|
|
896
|
+
"""
|
|
897
|
+
cdef int c
|
|
898
|
+
if op == Py_EQ:
|
|
899
|
+
return <bint> mpq_equal((<Rational>left).value,
|
|
900
|
+
(<Rational>right).value)
|
|
901
|
+
elif op == Py_NE:
|
|
902
|
+
return not mpq_equal((<Rational>left).value,
|
|
903
|
+
(<Rational>right).value)
|
|
904
|
+
c = mpq_cmp((<Rational>left).value, (<Rational>right).value)
|
|
905
|
+
return rich_to_bool_sgn(op, c)
|
|
906
|
+
|
|
907
|
+
def __copy__(self):
|
|
908
|
+
"""
|
|
909
|
+
EXAMPLES::
|
|
910
|
+
|
|
911
|
+
sage: a = -17/37
|
|
912
|
+
sage: copy(a) is a
|
|
913
|
+
True
|
|
914
|
+
|
|
915
|
+
Coercion does not make a new copy::
|
|
916
|
+
|
|
917
|
+
sage: QQ(a) is a
|
|
918
|
+
True
|
|
919
|
+
|
|
920
|
+
Calling the constructor directly makes a new copy::
|
|
921
|
+
|
|
922
|
+
sage: Rational(a) is a
|
|
923
|
+
False
|
|
924
|
+
"""
|
|
925
|
+
# immutable
|
|
926
|
+
return self
|
|
927
|
+
|
|
928
|
+
def __deepcopy__(self, memo):
|
|
929
|
+
"""
|
|
930
|
+
EXAMPLES::
|
|
931
|
+
|
|
932
|
+
sage: a = -17/37
|
|
933
|
+
sage: deepcopy(a) is a
|
|
934
|
+
True
|
|
935
|
+
"""
|
|
936
|
+
# immutable
|
|
937
|
+
return self
|
|
938
|
+
|
|
939
|
+
def __dealloc__(self):
|
|
940
|
+
"""
|
|
941
|
+
Free memory occupied by this rational number.
|
|
942
|
+
|
|
943
|
+
EXAMPLES::
|
|
944
|
+
|
|
945
|
+
sage: a = -17/37
|
|
946
|
+
sage: del a # indirect test
|
|
947
|
+
"""
|
|
948
|
+
mpq_clear(self.value)
|
|
949
|
+
|
|
950
|
+
def __repr__(self):
|
|
951
|
+
"""
|
|
952
|
+
Return string representation of this rational number.
|
|
953
|
+
|
|
954
|
+
EXAMPLES::
|
|
955
|
+
|
|
956
|
+
sage: a = -17/37; a.__repr__()
|
|
957
|
+
'-17/37'
|
|
958
|
+
"""
|
|
959
|
+
return self.str()
|
|
960
|
+
|
|
961
|
+
def _latex_(self):
|
|
962
|
+
"""
|
|
963
|
+
Return Latex representation of this rational number.
|
|
964
|
+
|
|
965
|
+
EXAMPLES::
|
|
966
|
+
|
|
967
|
+
sage: a = -17/37
|
|
968
|
+
sage: a._latex_()
|
|
969
|
+
'-\\frac{17}{37}'
|
|
970
|
+
"""
|
|
971
|
+
if self.denom() == 1:
|
|
972
|
+
return str(self.numer())
|
|
973
|
+
if self < 0:
|
|
974
|
+
return "-\\frac{%s}{%s}" % (-self.numer(), self.denom())
|
|
975
|
+
else:
|
|
976
|
+
return "\\frac{%s}{%s}" % (self.numer(), self.denom())
|
|
977
|
+
|
|
978
|
+
def _symbolic_(self, sring):
|
|
979
|
+
"""
|
|
980
|
+
Return this rational as symbolic expression.
|
|
981
|
+
|
|
982
|
+
EXAMPLES::
|
|
983
|
+
|
|
984
|
+
sage: ex = SR(QQ(7)/3); ex # needs sage.symbolic
|
|
985
|
+
7/3
|
|
986
|
+
sage: parent(ex) # needs sage.symbolic
|
|
987
|
+
Symbolic Ring
|
|
988
|
+
"""
|
|
989
|
+
return sring._force_pyobject(self, force=True)
|
|
990
|
+
|
|
991
|
+
def _sympy_(self):
|
|
992
|
+
"""
|
|
993
|
+
Convert Sage ``Rational`` to SymPy ``Rational``.
|
|
994
|
+
|
|
995
|
+
EXAMPLES::
|
|
996
|
+
|
|
997
|
+
sage: # needs sympy
|
|
998
|
+
sage: n = 1/2; n._sympy_()
|
|
999
|
+
1/2
|
|
1000
|
+
sage: n = -1/5; n._sympy_()
|
|
1001
|
+
-1/5
|
|
1002
|
+
sage: from sympy import Symbol
|
|
1003
|
+
sage: QQ(1) + Symbol('x')*QQ(2)
|
|
1004
|
+
2*x + 1
|
|
1005
|
+
"""
|
|
1006
|
+
import sympy
|
|
1007
|
+
return sympy.Rational(int(self.numerator()), int(self.denominator()))
|
|
1008
|
+
|
|
1009
|
+
def __mpz__(self):
|
|
1010
|
+
"""
|
|
1011
|
+
Return a gmpy2 ``mpz`` if this Rational is an integer.
|
|
1012
|
+
|
|
1013
|
+
EXAMPLES::
|
|
1014
|
+
|
|
1015
|
+
sage: q = 6/2
|
|
1016
|
+
sage: q.__mpz__()
|
|
1017
|
+
mpz(3)
|
|
1018
|
+
sage: q = 1/4
|
|
1019
|
+
sage: q.__mpz__()
|
|
1020
|
+
Traceback (most recent call last):
|
|
1021
|
+
...
|
|
1022
|
+
TypeError: unable to convert rational 1/4 to an integer
|
|
1023
|
+
|
|
1024
|
+
TESTS::
|
|
1025
|
+
|
|
1026
|
+
sage: QQ().__mpz__(); raise NotImplementedError("gmpy2 is not installed")
|
|
1027
|
+
Traceback (most recent call last):
|
|
1028
|
+
...
|
|
1029
|
+
NotImplementedError: gmpy2 is not installed
|
|
1030
|
+
"""
|
|
1031
|
+
if self.denominator() != 1:
|
|
1032
|
+
raise TypeError(f"unable to convert rational {self} to an integer")
|
|
1033
|
+
return self.numerator().__mpz__()
|
|
1034
|
+
|
|
1035
|
+
def __mpq__(self):
|
|
1036
|
+
"""
|
|
1037
|
+
Convert Sage ``Rational`` to gmpy2 ``Rational``.
|
|
1038
|
+
|
|
1039
|
+
EXAMPLES::
|
|
1040
|
+
|
|
1041
|
+
sage: r = 5/3
|
|
1042
|
+
sage: r.__mpq__()
|
|
1043
|
+
mpq(5,3)
|
|
1044
|
+
sage: from gmpy2 import mpq
|
|
1045
|
+
sage: mpq(r)
|
|
1046
|
+
mpq(5,3)
|
|
1047
|
+
"""
|
|
1048
|
+
return gmpy2.GMPy_MPQ_From_mpq(self.value)
|
|
1049
|
+
|
|
1050
|
+
_lean_init_ = _interface_init_
|
|
1051
|
+
|
|
1052
|
+
def _magma_init_(self, magma):
|
|
1053
|
+
"""
|
|
1054
|
+
Return the magma representation of ``self``.
|
|
1055
|
+
|
|
1056
|
+
EXAMPLES::
|
|
1057
|
+
|
|
1058
|
+
sage: n = -485/82847
|
|
1059
|
+
sage: n._magma_init_(magma) # optional - magma
|
|
1060
|
+
'-485/82847'
|
|
1061
|
+
"""
|
|
1062
|
+
return self.numerator()._magma_init_(magma) + '/' + self.denominator()._magma_init_(magma)
|
|
1063
|
+
|
|
1064
|
+
@property
|
|
1065
|
+
def __array_interface__(self):
|
|
1066
|
+
"""
|
|
1067
|
+
Used for NumPy conversion. If ``self`` is integral, it converts to
|
|
1068
|
+
an ``Integer``. Otherwise it converts to a double floating point
|
|
1069
|
+
value.
|
|
1070
|
+
|
|
1071
|
+
EXAMPLES::
|
|
1072
|
+
|
|
1073
|
+
sage: # needs numpy
|
|
1074
|
+
sage: import numpy
|
|
1075
|
+
sage: numpy.array([1, 2, 3/1])
|
|
1076
|
+
array([1, 2, 3])
|
|
1077
|
+
sage: numpy.array(QQ(2**40)).dtype
|
|
1078
|
+
dtype('int64')
|
|
1079
|
+
sage: numpy.array(QQ(2**400)).dtype
|
|
1080
|
+
dtype('O')
|
|
1081
|
+
sage: numpy.array([1, 1/2, 3/4])
|
|
1082
|
+
array([1. , 0.5 , 0.75])
|
|
1083
|
+
"""
|
|
1084
|
+
if mpz_cmp_ui(mpq_denref(self.value), 1) == 0:
|
|
1085
|
+
if mpz_fits_slong_p(mpq_numref(self.value)):
|
|
1086
|
+
return numpy_long_interface
|
|
1087
|
+
elif sizeof(long) == 4 and mpz_sizeinbase(mpq_numref(self.value), 2) <= 63:
|
|
1088
|
+
return numpy_int64_interface
|
|
1089
|
+
else:
|
|
1090
|
+
return numpy_object_interface
|
|
1091
|
+
else:
|
|
1092
|
+
return numpy_double_interface
|
|
1093
|
+
|
|
1094
|
+
def _mathml_(self):
|
|
1095
|
+
"""
|
|
1096
|
+
Return mathml representation of this rational number.
|
|
1097
|
+
|
|
1098
|
+
EXAMPLES::
|
|
1099
|
+
|
|
1100
|
+
sage: a = -17/37; a._mathml_()
|
|
1101
|
+
'<mo>-</mo><mfrac><mrow><mn>17</mn></mrow><mrow><mn>37</mn></mrow></mfrac>'
|
|
1102
|
+
"""
|
|
1103
|
+
if self.denom() == 1:
|
|
1104
|
+
return '<mn>%s</mn>' % (self.numer())
|
|
1105
|
+
else:
|
|
1106
|
+
from sage.misc.mathml import mathml
|
|
1107
|
+
t = ''
|
|
1108
|
+
if self < 0:
|
|
1109
|
+
t = t + '<mo>-</mo>'
|
|
1110
|
+
t = t + '<mfrac><mrow>%s</mrow><mrow>%s</mrow></mfrac>' % (
|
|
1111
|
+
mathml(abs(self.numer())), mathml(self.denom()))
|
|
1112
|
+
return t
|
|
1113
|
+
|
|
1114
|
+
def _im_gens_(self, codomain, im_gens, base_map=None):
|
|
1115
|
+
"""
|
|
1116
|
+
Return the image of ``self`` under the homomorphism from the rational
|
|
1117
|
+
field to ``codomain``.
|
|
1118
|
+
|
|
1119
|
+
This always just returns ``self`` coerced into the ``codomain``.
|
|
1120
|
+
|
|
1121
|
+
INPUT:
|
|
1122
|
+
|
|
1123
|
+
- ``codomain`` -- object (usually a ring)
|
|
1124
|
+
|
|
1125
|
+
- ``im_gens`` -- list of elements of ``codomain``
|
|
1126
|
+
|
|
1127
|
+
EXAMPLES::
|
|
1128
|
+
|
|
1129
|
+
sage: a = -17/37
|
|
1130
|
+
sage: a._im_gens_(QQ, [1/1])
|
|
1131
|
+
-17/37
|
|
1132
|
+
"""
|
|
1133
|
+
return codomain.coerce(self)
|
|
1134
|
+
|
|
1135
|
+
def content(self, other):
|
|
1136
|
+
"""
|
|
1137
|
+
Return the content of ``self`` and ``other``, i.e., the unique positive
|
|
1138
|
+
rational number `c` such that ``self/c`` and ``other/c`` are coprime
|
|
1139
|
+
integers.
|
|
1140
|
+
|
|
1141
|
+
``other`` can be a rational number or a list of rational numbers.
|
|
1142
|
+
|
|
1143
|
+
EXAMPLES::
|
|
1144
|
+
|
|
1145
|
+
sage: a = 2/3
|
|
1146
|
+
sage: a.content(2/3)
|
|
1147
|
+
2/3
|
|
1148
|
+
sage: a.content(1/5)
|
|
1149
|
+
1/15
|
|
1150
|
+
sage: a.content([2/5, 4/9])
|
|
1151
|
+
2/45
|
|
1152
|
+
"""
|
|
1153
|
+
from sage.structure.sequence import Sequence
|
|
1154
|
+
seq = Sequence(other)
|
|
1155
|
+
seq.append(self)
|
|
1156
|
+
nums = [x.numerator() for x in seq]
|
|
1157
|
+
denoms = [x.denominator() for x in seq]
|
|
1158
|
+
from sage.arith.misc import GCD as gcd
|
|
1159
|
+
from sage.arith.functions import lcm
|
|
1160
|
+
return gcd(nums) / lcm(denoms)
|
|
1161
|
+
|
|
1162
|
+
def valuation(self, p):
|
|
1163
|
+
r"""
|
|
1164
|
+
Return the power of ``p`` in the factorization of ``self``.
|
|
1165
|
+
|
|
1166
|
+
INPUT:
|
|
1167
|
+
|
|
1168
|
+
- ``p`` -- a prime number
|
|
1169
|
+
|
|
1170
|
+
OUTPUT:
|
|
1171
|
+
|
|
1172
|
+
(integer or infinity) ``Infinity`` if ``self`` is zero, otherwise the
|
|
1173
|
+
(positive or negative) integer `e` such that ``self`` = `m*p^e`
|
|
1174
|
+
with `m` coprime to `p`.
|
|
1175
|
+
|
|
1176
|
+
.. NOTE::
|
|
1177
|
+
|
|
1178
|
+
See also :meth:`val_unit()` which returns the pair `(e,m)`. The
|
|
1179
|
+
function :meth:`ord()` is an alias for :meth:`valuation()`.
|
|
1180
|
+
|
|
1181
|
+
EXAMPLES::
|
|
1182
|
+
|
|
1183
|
+
sage: x = -5/9
|
|
1184
|
+
sage: x.valuation(5)
|
|
1185
|
+
1
|
|
1186
|
+
sage: x.ord(5)
|
|
1187
|
+
1
|
|
1188
|
+
sage: x.valuation(3)
|
|
1189
|
+
-2
|
|
1190
|
+
sage: x.valuation(2)
|
|
1191
|
+
0
|
|
1192
|
+
|
|
1193
|
+
Some edge cases::
|
|
1194
|
+
|
|
1195
|
+
sage: (0/1).valuation(4)
|
|
1196
|
+
+Infinity
|
|
1197
|
+
sage: (7/16).valuation(4)
|
|
1198
|
+
-2
|
|
1199
|
+
"""
|
|
1200
|
+
return self.numerator().valuation(p) - self.denominator().valuation(p)
|
|
1201
|
+
|
|
1202
|
+
ord = valuation
|
|
1203
|
+
|
|
1204
|
+
def local_height(self, p, prec=None):
|
|
1205
|
+
r"""
|
|
1206
|
+
Return the local height of this rational number at the prime `p`.
|
|
1207
|
+
|
|
1208
|
+
INPUT:
|
|
1209
|
+
|
|
1210
|
+
- ``p`` -- a prime number
|
|
1211
|
+
|
|
1212
|
+
- ``prec`` -- integer (default: default :class:`RealField` precision);
|
|
1213
|
+
desired floating point precision
|
|
1214
|
+
|
|
1215
|
+
OUTPUT:
|
|
1216
|
+
|
|
1217
|
+
(real) The local height of this rational number at the
|
|
1218
|
+
prime `p`.
|
|
1219
|
+
|
|
1220
|
+
EXAMPLES::
|
|
1221
|
+
|
|
1222
|
+
sage: a = QQ(25/6)
|
|
1223
|
+
sage: a.local_height(2) # needs sage.rings.real_mpfr
|
|
1224
|
+
0.693147180559945
|
|
1225
|
+
sage: a.local_height(3) # needs sage.rings.real_mpfr
|
|
1226
|
+
1.09861228866811
|
|
1227
|
+
sage: a.local_height(5) # needs sage.rings.real_mpfr
|
|
1228
|
+
0.000000000000000
|
|
1229
|
+
"""
|
|
1230
|
+
from sage.rings.real_mpfr import RealField
|
|
1231
|
+
if prec is None:
|
|
1232
|
+
R = RealField()
|
|
1233
|
+
else:
|
|
1234
|
+
R = RealField(prec)
|
|
1235
|
+
if self.is_zero():
|
|
1236
|
+
return R.zero()
|
|
1237
|
+
val = self.valuation(p)
|
|
1238
|
+
if val >= 0:
|
|
1239
|
+
return R.zero()
|
|
1240
|
+
return -val * R(p).log()
|
|
1241
|
+
|
|
1242
|
+
def local_height_arch(self, prec=None):
|
|
1243
|
+
r"""
|
|
1244
|
+
Return the Archimedean local height of this rational number at the
|
|
1245
|
+
infinite place.
|
|
1246
|
+
|
|
1247
|
+
INPUT:
|
|
1248
|
+
|
|
1249
|
+
- ``prec`` -- integer (default: default :class:`RealField` precision);
|
|
1250
|
+
desired floating point precision
|
|
1251
|
+
|
|
1252
|
+
OUTPUT:
|
|
1253
|
+
|
|
1254
|
+
(real) The local height of this rational number `x` at the
|
|
1255
|
+
unique infinite place of `\QQ`, which is
|
|
1256
|
+
`\max(\log(|x|),0)`.
|
|
1257
|
+
|
|
1258
|
+
EXAMPLES::
|
|
1259
|
+
|
|
1260
|
+
sage: a = QQ(6/25)
|
|
1261
|
+
sage: a.local_height_arch() # needs sage.rings.real_mpfr
|
|
1262
|
+
0.000000000000000
|
|
1263
|
+
sage: (1/a).local_height_arch() # needs sage.rings.real_mpfr
|
|
1264
|
+
1.42711635564015
|
|
1265
|
+
sage: (1/a).local_height_arch(100) # needs sage.rings.real_mpfr
|
|
1266
|
+
1.4271163556401457483890413081
|
|
1267
|
+
"""
|
|
1268
|
+
from sage.rings.real_mpfr import RealField
|
|
1269
|
+
if prec is None:
|
|
1270
|
+
R = RealField()
|
|
1271
|
+
else:
|
|
1272
|
+
R = RealField(prec)
|
|
1273
|
+
a = self.abs()
|
|
1274
|
+
if a <= 1:
|
|
1275
|
+
return R.zero()
|
|
1276
|
+
return R(a).log()
|
|
1277
|
+
|
|
1278
|
+
def global_height_non_arch(self, prec=None):
|
|
1279
|
+
r"""
|
|
1280
|
+
Return the total non-archimedean component of the height of this
|
|
1281
|
+
rational number.
|
|
1282
|
+
|
|
1283
|
+
INPUT:
|
|
1284
|
+
|
|
1285
|
+
- ``prec`` -- integer (default: default :class:`RealField` precision);
|
|
1286
|
+
desired floating point precision
|
|
1287
|
+
|
|
1288
|
+
OUTPUT:
|
|
1289
|
+
|
|
1290
|
+
(real) The total non-archimedean component of the height of
|
|
1291
|
+
this rational number.
|
|
1292
|
+
|
|
1293
|
+
ALGORITHM:
|
|
1294
|
+
|
|
1295
|
+
This is the sum of the local heights at all primes `p`, which
|
|
1296
|
+
may be computed without factorization as the log of the
|
|
1297
|
+
denominator.
|
|
1298
|
+
|
|
1299
|
+
EXAMPLES::
|
|
1300
|
+
|
|
1301
|
+
sage: a = QQ(5/6)
|
|
1302
|
+
sage: a.support()
|
|
1303
|
+
[2, 3, 5]
|
|
1304
|
+
sage: a.global_height_non_arch() # needs sage.rings.real_mpfr
|
|
1305
|
+
1.79175946922805
|
|
1306
|
+
sage: [a.local_height(p) for p in a.support()] # needs sage.rings.real_mpfr
|
|
1307
|
+
[0.693147180559945, 1.09861228866811, 0.000000000000000]
|
|
1308
|
+
sage: sum([a.local_height(p) for p in a.support()]) # needs sage.rings.real_mpfr
|
|
1309
|
+
1.79175946922805
|
|
1310
|
+
"""
|
|
1311
|
+
from sage.rings.real_mpfr import RealField
|
|
1312
|
+
if prec is None:
|
|
1313
|
+
R = RealField()
|
|
1314
|
+
else:
|
|
1315
|
+
R = RealField(prec)
|
|
1316
|
+
d = self.denominator()
|
|
1317
|
+
if d.is_one():
|
|
1318
|
+
return R.zero()
|
|
1319
|
+
return R(d).log()
|
|
1320
|
+
|
|
1321
|
+
def global_height_arch(self, prec=None):
|
|
1322
|
+
r"""
|
|
1323
|
+
Return the total archimedean component of the height of this rational
|
|
1324
|
+
number.
|
|
1325
|
+
|
|
1326
|
+
INPUT:
|
|
1327
|
+
|
|
1328
|
+
- ``prec`` -- integer (default: default :class:`RealField` precision);
|
|
1329
|
+
desired floating point precision
|
|
1330
|
+
|
|
1331
|
+
OUTPUT:
|
|
1332
|
+
|
|
1333
|
+
(real) The total archimedean component of the height of
|
|
1334
|
+
this rational number.
|
|
1335
|
+
|
|
1336
|
+
ALGORITHM:
|
|
1337
|
+
|
|
1338
|
+
Since `\QQ` has only one infinite place this is just the value
|
|
1339
|
+
of the local height at that place. This separate function is
|
|
1340
|
+
included for compatibility with number fields.
|
|
1341
|
+
|
|
1342
|
+
EXAMPLES::
|
|
1343
|
+
|
|
1344
|
+
sage: a = QQ(6/25)
|
|
1345
|
+
sage: a.global_height_arch() # needs sage.rings.real_mpfr
|
|
1346
|
+
0.000000000000000
|
|
1347
|
+
sage: (1/a).global_height_arch() # needs sage.rings.real_mpfr
|
|
1348
|
+
1.42711635564015
|
|
1349
|
+
sage: (1/a).global_height_arch(100) # needs sage.rings.real_mpfr
|
|
1350
|
+
1.4271163556401457483890413081
|
|
1351
|
+
"""
|
|
1352
|
+
return self.local_height_arch(prec)
|
|
1353
|
+
|
|
1354
|
+
def global_height(self, prec=None):
|
|
1355
|
+
r"""
|
|
1356
|
+
Return the absolute logarithmic height of this rational number.
|
|
1357
|
+
|
|
1358
|
+
INPUT:
|
|
1359
|
+
|
|
1360
|
+
- ``prec`` -- integer (default: default :class:`RealField` precision);
|
|
1361
|
+
desired floating point precision
|
|
1362
|
+
|
|
1363
|
+
OUTPUT:
|
|
1364
|
+
|
|
1365
|
+
(real) The absolute logarithmic height of this rational number.
|
|
1366
|
+
|
|
1367
|
+
ALGORITHM:
|
|
1368
|
+
|
|
1369
|
+
The height is the sum of the total archimedean and
|
|
1370
|
+
non-archimedean components, which is equal to
|
|
1371
|
+
`\max(\log(n),\log(d))` where `n,d` are the numerator and
|
|
1372
|
+
denominator of the rational number.
|
|
1373
|
+
|
|
1374
|
+
EXAMPLES::
|
|
1375
|
+
|
|
1376
|
+
sage: # needs sage.rings.real_mpfr
|
|
1377
|
+
sage: a = QQ(6/25)
|
|
1378
|
+
sage: a.global_height_arch() + a.global_height_non_arch()
|
|
1379
|
+
3.21887582486820
|
|
1380
|
+
sage: a.global_height()
|
|
1381
|
+
3.21887582486820
|
|
1382
|
+
sage: (1/a).global_height()
|
|
1383
|
+
3.21887582486820
|
|
1384
|
+
sage: QQ(0).global_height()
|
|
1385
|
+
0.000000000000000
|
|
1386
|
+
sage: QQ(1).global_height()
|
|
1387
|
+
0.000000000000000
|
|
1388
|
+
"""
|
|
1389
|
+
from sage.rings.real_mpfr import RealField
|
|
1390
|
+
if prec is None:
|
|
1391
|
+
R = RealField()
|
|
1392
|
+
else:
|
|
1393
|
+
R = RealField(prec)
|
|
1394
|
+
return R(max(self.numerator().abs(),self.denominator())).log()
|
|
1395
|
+
|
|
1396
|
+
def is_square(self):
|
|
1397
|
+
"""
|
|
1398
|
+
Return whether or not this rational number is a square.
|
|
1399
|
+
|
|
1400
|
+
OUTPUT: boolean
|
|
1401
|
+
|
|
1402
|
+
EXAMPLES::
|
|
1403
|
+
|
|
1404
|
+
sage: x = 9/4
|
|
1405
|
+
sage: x.is_square()
|
|
1406
|
+
True
|
|
1407
|
+
sage: x = (7/53)^100
|
|
1408
|
+
sage: x.is_square()
|
|
1409
|
+
True
|
|
1410
|
+
sage: x = 4/3
|
|
1411
|
+
sage: x.is_square()
|
|
1412
|
+
False
|
|
1413
|
+
sage: x = -1/4
|
|
1414
|
+
sage: x.is_square()
|
|
1415
|
+
False
|
|
1416
|
+
"""
|
|
1417
|
+
return mpq_sgn(self.value) >= 0 and mpz_perfect_square_p(mpq_numref(self.value)) and mpz_perfect_square_p(mpq_denref(self.value))
|
|
1418
|
+
|
|
1419
|
+
def is_norm(self, L, element=False, proof=True):
|
|
1420
|
+
r"""
|
|
1421
|
+
Determine whether ``self`` is the norm of an element of ``L``.
|
|
1422
|
+
|
|
1423
|
+
INPUT:
|
|
1424
|
+
|
|
1425
|
+
- ``L`` -- a number field
|
|
1426
|
+
- ``element`` -- boolean (default: ``False``); whether to also output
|
|
1427
|
+
an element of which ``self`` is a norm
|
|
1428
|
+
- ``proof`` -- if ``True``, then the output is correct unconditionally;
|
|
1429
|
+
if ``False``, then the output assumes GRH
|
|
1430
|
+
|
|
1431
|
+
OUTPUT:
|
|
1432
|
+
|
|
1433
|
+
If element is ``False``, then the output is a boolean ``B``, which is
|
|
1434
|
+
``True`` if and only if ``self`` is the norm of an element of ``L``.
|
|
1435
|
+
If ``element`` is ``False``, then the output is a pair ``(B, x)``,
|
|
1436
|
+
where ``B`` is as above. If ``B`` is ``True``, then ``x`` an element of
|
|
1437
|
+
``L`` such that ``self == x.norm()``. Otherwise, ``x is None``.
|
|
1438
|
+
|
|
1439
|
+
ALGORITHM:
|
|
1440
|
+
|
|
1441
|
+
Uses the PARI function :pari:`bnfisnorm`. See :meth:`_bnfisnorm()`.
|
|
1442
|
+
|
|
1443
|
+
EXAMPLES::
|
|
1444
|
+
|
|
1445
|
+
sage: # needs sage.rings.number_field
|
|
1446
|
+
sage: x = polygen(QQ, 'x')
|
|
1447
|
+
sage: K = NumberField(x^2 - 2, 'beta')
|
|
1448
|
+
sage: (1/7).is_norm(K)
|
|
1449
|
+
True
|
|
1450
|
+
sage: (1/10).is_norm(K)
|
|
1451
|
+
False
|
|
1452
|
+
sage: 0.is_norm(K)
|
|
1453
|
+
True
|
|
1454
|
+
sage: (1/7).is_norm(K, element=True)
|
|
1455
|
+
(True, 1/7*beta + 3/7)
|
|
1456
|
+
sage: (1/10).is_norm(K, element=True)
|
|
1457
|
+
(False, None)
|
|
1458
|
+
sage: (1/691).is_norm(QQ, element=True)
|
|
1459
|
+
(True, 1/691)
|
|
1460
|
+
|
|
1461
|
+
The number field doesn't have to be defined by an
|
|
1462
|
+
integral polynomial::
|
|
1463
|
+
|
|
1464
|
+
sage: B, e = (1/5).is_norm(QuadraticField(5/4, 'a'), element=True) # needs sage.rings.number_field
|
|
1465
|
+
sage: B # needs sage.rings.number_field
|
|
1466
|
+
True
|
|
1467
|
+
sage: e.norm() # needs sage.rings.number_field
|
|
1468
|
+
1/5
|
|
1469
|
+
|
|
1470
|
+
A non-Galois number field::
|
|
1471
|
+
|
|
1472
|
+
sage: # needs sage.rings.number_field
|
|
1473
|
+
sage: K.<a> = NumberField(x^3 - 2)
|
|
1474
|
+
sage: B, e = (3/5).is_norm(K, element=True); B
|
|
1475
|
+
True
|
|
1476
|
+
sage: e.norm()
|
|
1477
|
+
3/5
|
|
1478
|
+
sage: 7.is_norm(K) # needs sage.groups
|
|
1479
|
+
Traceback (most recent call last):
|
|
1480
|
+
...
|
|
1481
|
+
NotImplementedError: is_norm is not implemented unconditionally
|
|
1482
|
+
for norms from non-Galois number fields
|
|
1483
|
+
sage: 7.is_norm(K, proof=False) # needs sage.groups
|
|
1484
|
+
False
|
|
1485
|
+
|
|
1486
|
+
AUTHORS:
|
|
1487
|
+
|
|
1488
|
+
- Craig Citro (2008-04-05)
|
|
1489
|
+
|
|
1490
|
+
- Marco Streng (2010-12-03)
|
|
1491
|
+
"""
|
|
1492
|
+
if not element:
|
|
1493
|
+
return self.is_norm(L, element=True, proof=proof)[0]
|
|
1494
|
+
|
|
1495
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
1496
|
+
if not isinstance(L, NumberField):
|
|
1497
|
+
raise ValueError("L (=%s) must be a NumberField in is_norm" % L)
|
|
1498
|
+
if L.degree() == 1 or self.is_zero():
|
|
1499
|
+
return True, L(self)
|
|
1500
|
+
d = L.polynomial().denominator()
|
|
1501
|
+
if not d == 1:
|
|
1502
|
+
M, M_to_L = L.subfield(L.gen()*d)
|
|
1503
|
+
b, x = self.is_norm(M, element=True, proof=proof)
|
|
1504
|
+
if b:
|
|
1505
|
+
x = M_to_L(x)
|
|
1506
|
+
return b, x
|
|
1507
|
+
a, b = self._bnfisnorm(L, proof=proof)
|
|
1508
|
+
if b == 1:
|
|
1509
|
+
assert a.norm() == self
|
|
1510
|
+
return True, a
|
|
1511
|
+
if L.is_galois():
|
|
1512
|
+
return False, None
|
|
1513
|
+
M = L.galois_closure('a')
|
|
1514
|
+
from sage.functions.log import log
|
|
1515
|
+
from sage.functions.other import floor
|
|
1516
|
+
extra_primes = floor(12*log(abs(M.discriminant()))**2)
|
|
1517
|
+
a, b = self._bnfisnorm(L, proof=proof, extra_primes=extra_primes)
|
|
1518
|
+
if b == 1:
|
|
1519
|
+
assert a.norm() == self
|
|
1520
|
+
return True, a
|
|
1521
|
+
if proof:
|
|
1522
|
+
raise NotImplementedError("is_norm is not implemented unconditionally for norms from non-Galois number fields")
|
|
1523
|
+
return False, None
|
|
1524
|
+
|
|
1525
|
+
def _bnfisnorm(self, K, proof=True, extra_primes=0):
|
|
1526
|
+
r"""
|
|
1527
|
+
Return the output of the PARI function :pari:`bnfisnorm`.
|
|
1528
|
+
|
|
1529
|
+
Tries to tell whether the rational number ``self`` is the norm of some
|
|
1530
|
+
element `y` in ``K``. Returns a pair `(a, b)` where
|
|
1531
|
+
``self = Norm(a)*b``. Looks for a solution that is an `S`-unit, with
|
|
1532
|
+
`S` a certain set of prime ideals containing (among others) all primes
|
|
1533
|
+
dividing ``self``.
|
|
1534
|
+
|
|
1535
|
+
If `K` is known to be Galois, set ``extra_primes = 0`` (in this case,
|
|
1536
|
+
``self`` is a norm iff `b = 1`).
|
|
1537
|
+
|
|
1538
|
+
If ``extra_primes`` is nonzero, the program adds to `S` the following
|
|
1539
|
+
prime ideals, depending on the sign of extra_primes.
|
|
1540
|
+
If ``extra_primes > 0``, the ideals of norm less than ``extra_primes``.
|
|
1541
|
+
And if ``extra_primes < 0``, the ideals dividing ``extra_primes``.
|
|
1542
|
+
|
|
1543
|
+
Assuming GRH, the answer is guaranteed (i.e., ``self`` is a norm
|
|
1544
|
+
iff `b = 1`), if `S` contains all primes less than
|
|
1545
|
+
`12\log(\disc(L))^2`,
|
|
1546
|
+
where `L` is the Galois closure of `K`.
|
|
1547
|
+
|
|
1548
|
+
INPUT:
|
|
1549
|
+
|
|
1550
|
+
- ``K`` -- a number field
|
|
1551
|
+
- ``proof`` -- whether to certify the output of bnfinit;
|
|
1552
|
+
if ``False``, then correctness of the output depends on GRH
|
|
1553
|
+
- ``extra_primes`` -- integer as explained above
|
|
1554
|
+
|
|
1555
|
+
OUTPUT:
|
|
1556
|
+
|
|
1557
|
+
A pair `(a, b)` with `a` in `K` and `b` in `\QQ` such that
|
|
1558
|
+
``self == Norm(a)*b`` as explained above.
|
|
1559
|
+
|
|
1560
|
+
ALGORITHM:
|
|
1561
|
+
|
|
1562
|
+
Uses PARI's bnfisnorm.
|
|
1563
|
+
|
|
1564
|
+
EXAMPLES::
|
|
1565
|
+
|
|
1566
|
+
sage: QQ(2)._bnfisnorm(QuadraticField(-1, 'i')) # needs sage.rings.number_field
|
|
1567
|
+
(i - 1, 1)
|
|
1568
|
+
sage: x = polygen(QQ, 'x')
|
|
1569
|
+
sage: 7._bnfisnorm(NumberField(x^3 - 2, 'b')) # needs sage.rings.number_field
|
|
1570
|
+
(1, 7)
|
|
1571
|
+
|
|
1572
|
+
AUTHORS:
|
|
1573
|
+
|
|
1574
|
+
- Craig Citro (2008-04-05)
|
|
1575
|
+
|
|
1576
|
+
- Marco Streng (2010-12-03)
|
|
1577
|
+
"""
|
|
1578
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
1579
|
+
if not isinstance(K, NumberField):
|
|
1580
|
+
raise ValueError("K must be a NumberField in bnfisnorm")
|
|
1581
|
+
|
|
1582
|
+
a, b = K.pari_bnf(proof=proof).bnfisnorm(self, flag=extra_primes)
|
|
1583
|
+
return K(a), Rational(b)
|
|
1584
|
+
|
|
1585
|
+
def is_perfect_power(self, expected_value=False):
|
|
1586
|
+
r"""
|
|
1587
|
+
Return ``True`` if ``self`` is a perfect power.
|
|
1588
|
+
|
|
1589
|
+
INPUT:
|
|
1590
|
+
|
|
1591
|
+
- ``expected_value`` -- boolean; whether or not this rational is
|
|
1592
|
+
expected to be a perfect power. This does not affect the correctness
|
|
1593
|
+
of the output, only the runtime.
|
|
1594
|
+
|
|
1595
|
+
If ``expected_value`` is ``False`` (default) it will check the
|
|
1596
|
+
smallest of the numerator and denominator is a perfect power
|
|
1597
|
+
as a first step, which is often faster than checking if the
|
|
1598
|
+
quotient is a perfect power.
|
|
1599
|
+
|
|
1600
|
+
EXAMPLES::
|
|
1601
|
+
|
|
1602
|
+
sage: (4/9).is_perfect_power()
|
|
1603
|
+
True
|
|
1604
|
+
sage: (144/1).is_perfect_power()
|
|
1605
|
+
True
|
|
1606
|
+
sage: (4/3).is_perfect_power()
|
|
1607
|
+
False
|
|
1608
|
+
sage: (2/27).is_perfect_power()
|
|
1609
|
+
False
|
|
1610
|
+
sage: (4/27).is_perfect_power()
|
|
1611
|
+
False
|
|
1612
|
+
sage: (-1/25).is_perfect_power()
|
|
1613
|
+
False
|
|
1614
|
+
sage: (-1/27).is_perfect_power()
|
|
1615
|
+
True
|
|
1616
|
+
sage: (0/1).is_perfect_power()
|
|
1617
|
+
True
|
|
1618
|
+
|
|
1619
|
+
The second parameter does not change the result, but may
|
|
1620
|
+
change the runtime.
|
|
1621
|
+
|
|
1622
|
+
::
|
|
1623
|
+
|
|
1624
|
+
sage: (-1/27).is_perfect_power(True)
|
|
1625
|
+
True
|
|
1626
|
+
sage: (-1/25).is_perfect_power(True)
|
|
1627
|
+
False
|
|
1628
|
+
sage: (2/27).is_perfect_power(True)
|
|
1629
|
+
False
|
|
1630
|
+
sage: (144/1).is_perfect_power(True)
|
|
1631
|
+
True
|
|
1632
|
+
|
|
1633
|
+
This test makes sure we workaround a bug in GMP (see :issue:`4612`)::
|
|
1634
|
+
|
|
1635
|
+
sage: [-a for a in srange(100) if not QQ(-a^3).is_perfect_power()]
|
|
1636
|
+
[]
|
|
1637
|
+
sage: [-a for a in srange(100) if not QQ(-a^3).is_perfect_power(True)]
|
|
1638
|
+
[]
|
|
1639
|
+
"""
|
|
1640
|
+
cdef int s
|
|
1641
|
+
|
|
1642
|
+
if (mpz_cmp_ui(mpq_numref(self.value), 0) == 0):
|
|
1643
|
+
return True
|
|
1644
|
+
elif (mpz_cmp_ui(mpq_numref(self.value), 1) == 0):
|
|
1645
|
+
return mpz_perfect_power_p(mpq_denref(self.value))
|
|
1646
|
+
|
|
1647
|
+
cdef mpz_t prod
|
|
1648
|
+
cdef bint res
|
|
1649
|
+
|
|
1650
|
+
# We should be able to run the code in the sign == 1 case
|
|
1651
|
+
# below for both cases. However, we need to do extra work to
|
|
1652
|
+
# avoid a bug in GMP's mpz_perfect_power_p; see Issue #4612 for
|
|
1653
|
+
# more details.
|
|
1654
|
+
#
|
|
1655
|
+
# The code in the case of sign == -1 could definitely be
|
|
1656
|
+
# cleaned up, but it will be removed shortly, since both GMP
|
|
1657
|
+
# and eMPIRe have fixes for the mpz_perfect_power_p bug.
|
|
1658
|
+
|
|
1659
|
+
s = mpz_sgn(mpq_numref(self.value))
|
|
1660
|
+
if s == 1: # self is positive
|
|
1661
|
+
|
|
1662
|
+
if (mpz_cmp_ui(mpq_denref(self.value), 1) == 0):
|
|
1663
|
+
return mpz_perfect_power_p(mpq_numref(self.value))
|
|
1664
|
+
if not expected_value:
|
|
1665
|
+
# A necessary condition is that both the numerator and denominator
|
|
1666
|
+
# be perfect powers, which can be faster to disprove than the full
|
|
1667
|
+
# product (especially if both have a large prime factor).
|
|
1668
|
+
if mpz_cmpabs(mpq_numref(self.value), mpq_denref(self.value)) < 0:
|
|
1669
|
+
if not mpz_perfect_power_p(mpq_numref(self.value)):
|
|
1670
|
+
return False
|
|
1671
|
+
else:
|
|
1672
|
+
if not mpz_perfect_power_p(mpq_denref(self.value)):
|
|
1673
|
+
return False
|
|
1674
|
+
mpz_init(prod)
|
|
1675
|
+
mpz_mul(prod, mpq_numref(self.value), mpq_denref(self.value))
|
|
1676
|
+
res = mpz_perfect_power_p(prod)
|
|
1677
|
+
mpz_clear(prod)
|
|
1678
|
+
return res == 1
|
|
1679
|
+
|
|
1680
|
+
else: # self is negative
|
|
1681
|
+
|
|
1682
|
+
if (mpz_cmp_ui(mpq_denref(self.value), 1) == 0):
|
|
1683
|
+
if (mpz_cmp_si(mpq_numref(self.value), -1) == 0):
|
|
1684
|
+
return True
|
|
1685
|
+
mpz_init(prod)
|
|
1686
|
+
mpz_mul_si(prod, mpq_numref(self.value), -1)
|
|
1687
|
+
while mpz_perfect_square_p(prod):
|
|
1688
|
+
mpz_sqrt(prod, prod)
|
|
1689
|
+
s = mpz_perfect_power_p(prod)
|
|
1690
|
+
mpz_clear(prod)
|
|
1691
|
+
return s == 1
|
|
1692
|
+
|
|
1693
|
+
if not expected_value:
|
|
1694
|
+
if mpz_cmpabs(mpq_numref(self.value), mpq_denref(self.value)) < 0:
|
|
1695
|
+
mpz_init(prod)
|
|
1696
|
+
mpz_mul_si(prod, mpq_numref(self.value), -1)
|
|
1697
|
+
if mpz_cmp_ui(prod, 1) != 0:
|
|
1698
|
+
while mpz_perfect_square_p(prod):
|
|
1699
|
+
mpz_sqrt(prod, prod)
|
|
1700
|
+
if not mpz_perfect_power_p(prod):
|
|
1701
|
+
mpz_clear(prod)
|
|
1702
|
+
return False
|
|
1703
|
+
else:
|
|
1704
|
+
if not mpz_perfect_power_p(mpq_denref(self.value)):
|
|
1705
|
+
return False
|
|
1706
|
+
mpz_init(prod)
|
|
1707
|
+
else:
|
|
1708
|
+
mpz_init(prod)
|
|
1709
|
+
|
|
1710
|
+
mpz_mul(prod, mpq_numref(self.value), mpq_denref(self.value))
|
|
1711
|
+
mpz_mul_si(prod, prod, -1)
|
|
1712
|
+
while mpz_perfect_square_p(prod):
|
|
1713
|
+
mpz_sqrt(prod, prod)
|
|
1714
|
+
res = mpz_perfect_power_p(prod)
|
|
1715
|
+
mpz_clear(prod)
|
|
1716
|
+
return res == 1
|
|
1717
|
+
|
|
1718
|
+
def squarefree_part(self):
|
|
1719
|
+
"""
|
|
1720
|
+
Return the square free part of `x`, i.e., an integer `z` such
|
|
1721
|
+
that `x = z y^2`, for a perfect square `y^2`.
|
|
1722
|
+
|
|
1723
|
+
EXAMPLES::
|
|
1724
|
+
|
|
1725
|
+
sage: a = 1/2
|
|
1726
|
+
sage: a.squarefree_part()
|
|
1727
|
+
2
|
|
1728
|
+
sage: b = a/a.squarefree_part()
|
|
1729
|
+
sage: b, b.is_square()
|
|
1730
|
+
(1/4, True)
|
|
1731
|
+
sage: a = 24/5
|
|
1732
|
+
sage: a.squarefree_part()
|
|
1733
|
+
30
|
|
1734
|
+
"""
|
|
1735
|
+
return self.numer().squarefree_part() * self.denom().squarefree_part()
|
|
1736
|
+
|
|
1737
|
+
def is_padic_square(self, p, check=True):
|
|
1738
|
+
r"""
|
|
1739
|
+
Determines whether this rational number is a square in `\QQ_p` (or in
|
|
1740
|
+
`R` when ``p = infinity``).
|
|
1741
|
+
|
|
1742
|
+
INPUT:
|
|
1743
|
+
|
|
1744
|
+
- ``p`` -- a prime number, or ``infinity``
|
|
1745
|
+
|
|
1746
|
+
- ``check`` -- boolean (default: ``True``); check if `p` is prime
|
|
1747
|
+
|
|
1748
|
+
EXAMPLES::
|
|
1749
|
+
|
|
1750
|
+
sage: QQ(2).is_padic_square(7)
|
|
1751
|
+
True
|
|
1752
|
+
sage: QQ(98).is_padic_square(7)
|
|
1753
|
+
True
|
|
1754
|
+
sage: QQ(2).is_padic_square(5)
|
|
1755
|
+
False
|
|
1756
|
+
|
|
1757
|
+
TESTS::
|
|
1758
|
+
|
|
1759
|
+
sage: QQ(5/7).is_padic_square(int(2))
|
|
1760
|
+
False
|
|
1761
|
+
"""
|
|
1762
|
+
## Special case when self is zero
|
|
1763
|
+
if self.is_zero():
|
|
1764
|
+
return True
|
|
1765
|
+
|
|
1766
|
+
## Deal with p = infinity (i.e. the real numbers)
|
|
1767
|
+
import sage.rings.infinity
|
|
1768
|
+
if p == sage.rings.infinity.infinity:
|
|
1769
|
+
return (self > 0)
|
|
1770
|
+
|
|
1771
|
+
## Check that p is prime
|
|
1772
|
+
from sage.rings.integer_ring import ZZ
|
|
1773
|
+
p = ZZ(p)
|
|
1774
|
+
if check and not p.is_prime():
|
|
1775
|
+
raise ValueError('p must be "infinity" or a positive prime number.')
|
|
1776
|
+
|
|
1777
|
+
## Deal with finite primes
|
|
1778
|
+
e, m = self.val_unit(p)
|
|
1779
|
+
|
|
1780
|
+
if e % 2:
|
|
1781
|
+
return False
|
|
1782
|
+
|
|
1783
|
+
if p == 2:
|
|
1784
|
+
return ((m % 8) == 1)
|
|
1785
|
+
|
|
1786
|
+
from sage.arith.misc import kronecker as kronecker_symbol
|
|
1787
|
+
return (kronecker_symbol(m, p) == 1)
|
|
1788
|
+
|
|
1789
|
+
def val_unit(self, p):
|
|
1790
|
+
r"""
|
|
1791
|
+
Return a pair: the `p`-adic valuation of ``self``, and the `p`-adic
|
|
1792
|
+
unit of ``self``, as a :class:`Rational`.
|
|
1793
|
+
|
|
1794
|
+
We do not require the `p` be prime, but it must be at least 2. For
|
|
1795
|
+
more documentation see :meth:`Integer.val_unit()`.
|
|
1796
|
+
|
|
1797
|
+
INPUT:
|
|
1798
|
+
|
|
1799
|
+
- ``p`` -- a prime
|
|
1800
|
+
|
|
1801
|
+
OUTPUT:
|
|
1802
|
+
|
|
1803
|
+
- integer; the `p`-adic valuation of this rational
|
|
1804
|
+
|
|
1805
|
+
- ``Rational``; `p`-adic unit part of ``self``
|
|
1806
|
+
|
|
1807
|
+
EXAMPLES::
|
|
1808
|
+
|
|
1809
|
+
sage: (-4/17).val_unit(2)
|
|
1810
|
+
(2, -1/17)
|
|
1811
|
+
sage: (-4/17).val_unit(17)
|
|
1812
|
+
(-1, -4)
|
|
1813
|
+
sage: (0/1).val_unit(17)
|
|
1814
|
+
(+Infinity, 1)
|
|
1815
|
+
|
|
1816
|
+
AUTHORS:
|
|
1817
|
+
|
|
1818
|
+
- David Roe (2007-04-12)
|
|
1819
|
+
"""
|
|
1820
|
+
return self._val_unit(p)
|
|
1821
|
+
|
|
1822
|
+
# TODO -- change to use cpdef? If so, must fix
|
|
1823
|
+
# code in padics, etc. Do search_src('_val_unit').
|
|
1824
|
+
cdef _val_unit(Rational self, integer.Integer p):
|
|
1825
|
+
"""
|
|
1826
|
+
This is called by :meth:`val_unit()`.
|
|
1827
|
+
|
|
1828
|
+
EXAMPLES::
|
|
1829
|
+
|
|
1830
|
+
sage: (-4/17).val_unit(2) # indirect doctest
|
|
1831
|
+
(2, -1/17)
|
|
1832
|
+
"""
|
|
1833
|
+
cdef Rational u
|
|
1834
|
+
if mpz_cmp_ui(p.value, 2) < 0:
|
|
1835
|
+
raise ValueError("p must be at least 2.")
|
|
1836
|
+
if mpq_sgn(self.value) == 0:
|
|
1837
|
+
import sage.rings.infinity
|
|
1838
|
+
u = Rational.__new__(Rational)
|
|
1839
|
+
mpq_set_ui(u.value, 1, 1)
|
|
1840
|
+
return (sage.rings.infinity.infinity, u)
|
|
1841
|
+
cdef Integer v = Integer.__new__(Integer)
|
|
1842
|
+
u = Rational.__new__(Rational)
|
|
1843
|
+
sig_on()
|
|
1844
|
+
mpz_set_ui(v.value, mpz_remove(mpq_numref(u.value), mpq_numref(self.value), p.value))
|
|
1845
|
+
sig_off()
|
|
1846
|
+
if mpz_sgn(v.value) != 0:
|
|
1847
|
+
mpz_set(mpq_denref(u.value), mpq_denref(self.value))
|
|
1848
|
+
else:
|
|
1849
|
+
sig_on()
|
|
1850
|
+
mpz_set_ui(v.value, mpz_remove(mpq_denref(u.value), mpq_denref(self.value), p.value))
|
|
1851
|
+
sig_off()
|
|
1852
|
+
mpz_neg(v.value, v.value)
|
|
1853
|
+
return (v, u)
|
|
1854
|
+
|
|
1855
|
+
def prime_to_S_part(self, S=[]):
|
|
1856
|
+
r"""
|
|
1857
|
+
Return ``self`` with all powers of all primes in ``S`` removed.
|
|
1858
|
+
|
|
1859
|
+
INPUT:
|
|
1860
|
+
|
|
1861
|
+
- ``S`` -- list or tuple of primes
|
|
1862
|
+
|
|
1863
|
+
OUTPUT: rational
|
|
1864
|
+
|
|
1865
|
+
.. NOTE::
|
|
1866
|
+
|
|
1867
|
+
Primality of the entries in `S` is not checked.
|
|
1868
|
+
|
|
1869
|
+
EXAMPLES::
|
|
1870
|
+
|
|
1871
|
+
sage: QQ(3/4).prime_to_S_part()
|
|
1872
|
+
3/4
|
|
1873
|
+
sage: QQ(3/4).prime_to_S_part([2])
|
|
1874
|
+
3
|
|
1875
|
+
sage: QQ(-3/4).prime_to_S_part([3])
|
|
1876
|
+
-1/4
|
|
1877
|
+
sage: QQ(700/99).prime_to_S_part([2,3,5])
|
|
1878
|
+
7/11
|
|
1879
|
+
sage: QQ(-700/99).prime_to_S_part([2,3,5])
|
|
1880
|
+
-7/11
|
|
1881
|
+
sage: QQ(0).prime_to_S_part([2,3,5])
|
|
1882
|
+
0
|
|
1883
|
+
sage: QQ(-700/99).prime_to_S_part([])
|
|
1884
|
+
-700/99
|
|
1885
|
+
"""
|
|
1886
|
+
if self.is_zero():
|
|
1887
|
+
return self
|
|
1888
|
+
a = self
|
|
1889
|
+
for p in S:
|
|
1890
|
+
e, a = a.val_unit(p)
|
|
1891
|
+
return a
|
|
1892
|
+
|
|
1893
|
+
def sqrt(self, prec=None, extend=True, all=False):
|
|
1894
|
+
r"""
|
|
1895
|
+
The square root function.
|
|
1896
|
+
|
|
1897
|
+
INPUT:
|
|
1898
|
+
|
|
1899
|
+
- ``prec`` -- integer (default: ``None``); if ``None``, returns
|
|
1900
|
+
an exact square root; otherwise returns a numerical square root if
|
|
1901
|
+
necessary, to the given bits of precision.
|
|
1902
|
+
|
|
1903
|
+
- ``extend`` -- boolean (default: ``True``); if ``True``, return a
|
|
1904
|
+
square root in an extension ring, if necessary. Otherwise, raise a
|
|
1905
|
+
:exc:`ValueError` if the square is not in the base ring. Ignored if
|
|
1906
|
+
``prec`` is not ``None``.
|
|
1907
|
+
|
|
1908
|
+
- ``all`` -- boolean (default: ``False``); if ``True``, return all
|
|
1909
|
+
square roots of ``self`` (a list of length 0, 1, or 2)
|
|
1910
|
+
|
|
1911
|
+
EXAMPLES::
|
|
1912
|
+
|
|
1913
|
+
sage: x = 25/9
|
|
1914
|
+
sage: x.sqrt()
|
|
1915
|
+
5/3
|
|
1916
|
+
sage: sqrt(x)
|
|
1917
|
+
5/3
|
|
1918
|
+
sage: x = 64/4
|
|
1919
|
+
sage: x.sqrt()
|
|
1920
|
+
4
|
|
1921
|
+
sage: x = 100/1
|
|
1922
|
+
sage: x.sqrt()
|
|
1923
|
+
10
|
|
1924
|
+
sage: x.sqrt(all=True)
|
|
1925
|
+
[10, -10]
|
|
1926
|
+
sage: x = 81/5
|
|
1927
|
+
sage: x.sqrt() # needs sage.symbolic
|
|
1928
|
+
9*sqrt(1/5)
|
|
1929
|
+
sage: x = -81/3
|
|
1930
|
+
sage: x.sqrt() # needs sage.symbolic
|
|
1931
|
+
3*sqrt(-3)
|
|
1932
|
+
|
|
1933
|
+
::
|
|
1934
|
+
|
|
1935
|
+
sage: n = 2/3
|
|
1936
|
+
sage: n.sqrt() # needs sage.symbolic
|
|
1937
|
+
sqrt(2/3)
|
|
1938
|
+
|
|
1939
|
+
sage: # needs sage.rings.real_mpfr
|
|
1940
|
+
sage: n.sqrt(prec=10)
|
|
1941
|
+
0.82
|
|
1942
|
+
sage: n.sqrt(prec=100)
|
|
1943
|
+
0.81649658092772603273242802490
|
|
1944
|
+
sage: n.sqrt(prec=100)^2
|
|
1945
|
+
0.66666666666666666666666666667
|
|
1946
|
+
sage: n.sqrt(prec=53, all=True)
|
|
1947
|
+
[0.816496580927726, -0.816496580927726]
|
|
1948
|
+
sage: sqrt(-2/3, prec=53)
|
|
1949
|
+
0.816496580927726*I
|
|
1950
|
+
sage: sqrt(-2/3, prec=53, all=True)
|
|
1951
|
+
[0.816496580927726*I, -0.816496580927726*I]
|
|
1952
|
+
|
|
1953
|
+
sage: n.sqrt(extend=False)
|
|
1954
|
+
Traceback (most recent call last):
|
|
1955
|
+
...
|
|
1956
|
+
ValueError: square root of 2/3 not a rational number
|
|
1957
|
+
sage: n.sqrt(extend=False, all=True)
|
|
1958
|
+
[]
|
|
1959
|
+
sage: sqrt(-2/3, all=True) # needs sage.symbolic
|
|
1960
|
+
[sqrt(-2/3), -sqrt(-2/3)]
|
|
1961
|
+
|
|
1962
|
+
TESTS:
|
|
1963
|
+
|
|
1964
|
+
Ensure that :issue:`37153` is fixed, so that behaviour aligns
|
|
1965
|
+
with other rings and fields.
|
|
1966
|
+
See :issue:`9466` and :issue:`26509` for context::
|
|
1967
|
+
|
|
1968
|
+
sage: QQ(3).sqrt(extend=False, all=True)
|
|
1969
|
+
[]
|
|
1970
|
+
sage: QQ(-1).sqrt(extend=False, all=True)
|
|
1971
|
+
[]
|
|
1972
|
+
|
|
1973
|
+
AUTHORS:
|
|
1974
|
+
|
|
1975
|
+
- Naqi Jaffery (2006-03-05): some examples
|
|
1976
|
+
"""
|
|
1977
|
+
if prec is not None:
|
|
1978
|
+
from sage.misc.functional import _do_sqrt
|
|
1979
|
+
return _do_sqrt(self, prec=prec, all=all)
|
|
1980
|
+
|
|
1981
|
+
if mpq_sgn(self.value) == 0:
|
|
1982
|
+
return [self] if all else self
|
|
1983
|
+
|
|
1984
|
+
if mpq_sgn(self.value) < 0:
|
|
1985
|
+
if extend:
|
|
1986
|
+
from sage.misc.functional import _do_sqrt
|
|
1987
|
+
return _do_sqrt(self, prec=prec, all=all)
|
|
1988
|
+
if all:
|
|
1989
|
+
return []
|
|
1990
|
+
raise ValueError("square root of negative number not rational")
|
|
1991
|
+
|
|
1992
|
+
cdef Rational z = <Rational> Rational.__new__(Rational)
|
|
1993
|
+
cdef mpz_t tmp
|
|
1994
|
+
cdef int non_square = 0
|
|
1995
|
+
|
|
1996
|
+
sig_on()
|
|
1997
|
+
mpz_init(tmp)
|
|
1998
|
+
mpz_sqrtrem(mpq_numref(z.value), tmp, mpq_numref(self.value))
|
|
1999
|
+
if mpz_sgn(tmp) != 0:
|
|
2000
|
+
non_square = 1
|
|
2001
|
+
else:
|
|
2002
|
+
mpz_sqrtrem(mpq_denref(z.value), tmp, mpq_denref(self.value))
|
|
2003
|
+
if mpz_sgn(tmp) != 0:
|
|
2004
|
+
non_square = 1
|
|
2005
|
+
mpz_clear(tmp)
|
|
2006
|
+
sig_off()
|
|
2007
|
+
|
|
2008
|
+
if non_square:
|
|
2009
|
+
if extend:
|
|
2010
|
+
from sage.misc.functional import _do_sqrt
|
|
2011
|
+
return _do_sqrt(self, prec=prec, all=all)
|
|
2012
|
+
if all:
|
|
2013
|
+
return []
|
|
2014
|
+
raise ValueError("square root of %s not a rational number" % self)
|
|
2015
|
+
|
|
2016
|
+
if all:
|
|
2017
|
+
return [z, -z]
|
|
2018
|
+
return z
|
|
2019
|
+
|
|
2020
|
+
def period(self):
|
|
2021
|
+
r"""
|
|
2022
|
+
Return the period of the repeating part of the decimal expansion of
|
|
2023
|
+
this rational number.
|
|
2024
|
+
|
|
2025
|
+
ALGORITHM:
|
|
2026
|
+
|
|
2027
|
+
When a rational number `n/d` with `(n,d)=1` is
|
|
2028
|
+
expanded, the period begins after `s` terms and has length
|
|
2029
|
+
`t`, where `s` and `t` are the smallest numbers satisfying
|
|
2030
|
+
`10^s=10^{s+t} \mod d`. In general if `d=2^a 5^b m` where `m`
|
|
2031
|
+
is coprime to 10, then `s=\max(a,b)` and `t` is the order of
|
|
2032
|
+
10 modulo `m`.
|
|
2033
|
+
|
|
2034
|
+
EXAMPLES::
|
|
2035
|
+
|
|
2036
|
+
sage: (1/7).period() # needs sage.libs.pari
|
|
2037
|
+
6
|
|
2038
|
+
sage: RR(1/7) # needs sage.rings.real_mpfr
|
|
2039
|
+
0.142857142857143
|
|
2040
|
+
sage: (1/8).period() # needs sage.libs.pari
|
|
2041
|
+
1
|
|
2042
|
+
sage: RR(1/8) # needs sage.rings.real_mpfr
|
|
2043
|
+
0.125000000000000
|
|
2044
|
+
sage: RR(1/6) # needs sage.rings.real_mpfr
|
|
2045
|
+
0.166666666666667
|
|
2046
|
+
sage: (1/6).period() # needs sage.libs.pari
|
|
2047
|
+
1
|
|
2048
|
+
sage: x = 333/106
|
|
2049
|
+
sage: x.period() # needs sage.libs.pari
|
|
2050
|
+
13
|
|
2051
|
+
sage: RealField(200)(x) # needs sage.rings.real_mpfr
|
|
2052
|
+
3.1415094339622641509433962264150943396226415094339622641509
|
|
2053
|
+
"""
|
|
2054
|
+
cdef unsigned int alpha, beta
|
|
2055
|
+
d = self.denominator()
|
|
2056
|
+
alpha, d = d.val_unit(2)
|
|
2057
|
+
beta, d = d.val_unit(5)
|
|
2058
|
+
from sage.rings.finite_rings.integer_mod import Mod
|
|
2059
|
+
return Mod(10, d).multiplicative_order()
|
|
2060
|
+
|
|
2061
|
+
def nth_root(self, int n):
|
|
2062
|
+
r"""
|
|
2063
|
+
Compute the `n`-th root of ``self``, or raises a
|
|
2064
|
+
:exc:`ValueError` if ``self`` is not a perfect `n`-th power.
|
|
2065
|
+
|
|
2066
|
+
INPUT:
|
|
2067
|
+
|
|
2068
|
+
- ``n`` -- integer (must fit in C ``int`` type)
|
|
2069
|
+
|
|
2070
|
+
AUTHORS:
|
|
2071
|
+
|
|
2072
|
+
- David Harvey (2006-09-15)
|
|
2073
|
+
|
|
2074
|
+
EXAMPLES::
|
|
2075
|
+
|
|
2076
|
+
sage: (25/4).nth_root(2)
|
|
2077
|
+
5/2
|
|
2078
|
+
sage: (125/8).nth_root(3)
|
|
2079
|
+
5/2
|
|
2080
|
+
sage: (-125/8).nth_root(3)
|
|
2081
|
+
-5/2
|
|
2082
|
+
sage: (25/4).nth_root(-2)
|
|
2083
|
+
2/5
|
|
2084
|
+
|
|
2085
|
+
::
|
|
2086
|
+
|
|
2087
|
+
sage: (9/2).nth_root(2)
|
|
2088
|
+
Traceback (most recent call last):
|
|
2089
|
+
...
|
|
2090
|
+
ValueError: not a perfect 2nd power
|
|
2091
|
+
|
|
2092
|
+
::
|
|
2093
|
+
|
|
2094
|
+
sage: (-25/4).nth_root(2)
|
|
2095
|
+
Traceback (most recent call last):
|
|
2096
|
+
...
|
|
2097
|
+
ValueError: cannot take even root of negative number
|
|
2098
|
+
"""
|
|
2099
|
+
# TODO -- this could be quicker, by using GMP directly.
|
|
2100
|
+
cdef integer.Integer num
|
|
2101
|
+
cdef integer.Integer den
|
|
2102
|
+
cdef int negative
|
|
2103
|
+
|
|
2104
|
+
if n > 0:
|
|
2105
|
+
negative = 0
|
|
2106
|
+
elif n < 0:
|
|
2107
|
+
n = -n
|
|
2108
|
+
negative = 1
|
|
2109
|
+
else:
|
|
2110
|
+
raise ValueError("n cannot be zero")
|
|
2111
|
+
|
|
2112
|
+
num, exact = self.numerator().nth_root(n, 1)
|
|
2113
|
+
if not exact:
|
|
2114
|
+
raise ValueError("not a perfect %s power" % ZZ(n).ordinal_str())
|
|
2115
|
+
|
|
2116
|
+
den, exact = self.denominator().nth_root(n, 1)
|
|
2117
|
+
if not exact:
|
|
2118
|
+
raise ValueError("not a perfect %s power" % ZZ(n).ordinal_str())
|
|
2119
|
+
|
|
2120
|
+
if negative:
|
|
2121
|
+
return den / num
|
|
2122
|
+
else:
|
|
2123
|
+
return num / den
|
|
2124
|
+
|
|
2125
|
+
def is_nth_power(self, int n):
|
|
2126
|
+
r"""
|
|
2127
|
+
Return ``True`` if ``self`` is an `n`-th power, else ``False``.
|
|
2128
|
+
|
|
2129
|
+
INPUT:
|
|
2130
|
+
|
|
2131
|
+
- ``n`` -- integer (must fit in C ``int`` type)
|
|
2132
|
+
|
|
2133
|
+
.. NOTE::
|
|
2134
|
+
|
|
2135
|
+
Use this function when you need to test if a rational
|
|
2136
|
+
number is an `n`-th power, but do not need to know the value
|
|
2137
|
+
of its `n`-th root. If the value is needed, use :meth:`nth_root()`.
|
|
2138
|
+
|
|
2139
|
+
AUTHORS:
|
|
2140
|
+
|
|
2141
|
+
- John Cremona (2009-04-04)
|
|
2142
|
+
|
|
2143
|
+
EXAMPLES::
|
|
2144
|
+
|
|
2145
|
+
sage: QQ(25/4).is_nth_power(2)
|
|
2146
|
+
True
|
|
2147
|
+
sage: QQ(125/8).is_nth_power(3)
|
|
2148
|
+
True
|
|
2149
|
+
sage: QQ(-125/8).is_nth_power(3)
|
|
2150
|
+
True
|
|
2151
|
+
sage: QQ(25/4).is_nth_power(-2)
|
|
2152
|
+
True
|
|
2153
|
+
|
|
2154
|
+
sage: QQ(9/2).is_nth_power(2)
|
|
2155
|
+
False
|
|
2156
|
+
sage: QQ(-25).is_nth_power(2)
|
|
2157
|
+
False
|
|
2158
|
+
"""
|
|
2159
|
+
if n == 0:
|
|
2160
|
+
raise ValueError("n cannot be zero")
|
|
2161
|
+
if n < 0:
|
|
2162
|
+
n = -n
|
|
2163
|
+
if not n % 2 and self < 0:
|
|
2164
|
+
return False
|
|
2165
|
+
return self.numerator().nth_root(n, 1)[1]\
|
|
2166
|
+
and self.denominator().nth_root(n, 1)[1]
|
|
2167
|
+
|
|
2168
|
+
def str(self, int base=10):
|
|
2169
|
+
"""
|
|
2170
|
+
Return a string representation of ``self`` in the given ``base``.
|
|
2171
|
+
|
|
2172
|
+
INPUT:
|
|
2173
|
+
|
|
2174
|
+
- ``base`` -- integer (default: 10); base must be between 2 and 36
|
|
2175
|
+
|
|
2176
|
+
OUTPUT: string
|
|
2177
|
+
|
|
2178
|
+
EXAMPLES::
|
|
2179
|
+
|
|
2180
|
+
sage: (-4/17).str()
|
|
2181
|
+
'-4/17'
|
|
2182
|
+
sage: (-4/17).str(2)
|
|
2183
|
+
'-100/10001'
|
|
2184
|
+
|
|
2185
|
+
Note that the base must be at most 36.
|
|
2186
|
+
|
|
2187
|
+
::
|
|
2188
|
+
|
|
2189
|
+
sage: (-4/17).str(40)
|
|
2190
|
+
Traceback (most recent call last):
|
|
2191
|
+
...
|
|
2192
|
+
ValueError: base (=40) must be between 2 and 36
|
|
2193
|
+
sage: (-4/17).str(1)
|
|
2194
|
+
Traceback (most recent call last):
|
|
2195
|
+
...
|
|
2196
|
+
ValueError: base (=1) must be between 2 and 36
|
|
2197
|
+
"""
|
|
2198
|
+
if base < 2 or base > 36:
|
|
2199
|
+
raise ValueError("base (=%s) must be between 2 and 36" % base)
|
|
2200
|
+
cdef size_t n
|
|
2201
|
+
cdef char *s
|
|
2202
|
+
|
|
2203
|
+
n = mpz_sizeinbase (mpq_numref(self.value), base) \
|
|
2204
|
+
+ mpz_sizeinbase (mpq_denref(self.value), base) + 3
|
|
2205
|
+
s = <char *>PyMem_Malloc(n)
|
|
2206
|
+
if s == NULL:
|
|
2207
|
+
raise MemoryError("Unable to allocate enough memory for the string representation of an integer.")
|
|
2208
|
+
|
|
2209
|
+
sig_on()
|
|
2210
|
+
mpq_get_str(s, base, self.value)
|
|
2211
|
+
sig_off()
|
|
2212
|
+
k = char_to_str(s)
|
|
2213
|
+
PyMem_Free(s)
|
|
2214
|
+
return k
|
|
2215
|
+
|
|
2216
|
+
def __float__(self):
|
|
2217
|
+
"""
|
|
2218
|
+
Return floating point approximation to ``self`` as a Python float.
|
|
2219
|
+
|
|
2220
|
+
OUTPUT: float
|
|
2221
|
+
|
|
2222
|
+
EXAMPLES::
|
|
2223
|
+
|
|
2224
|
+
sage: (-4/17).__float__()
|
|
2225
|
+
-0.23529411764705882
|
|
2226
|
+
sage: float(-4/17)
|
|
2227
|
+
-0.23529411764705882
|
|
2228
|
+
sage: float(1/3)
|
|
2229
|
+
0.3333333333333333
|
|
2230
|
+
sage: float(1/10)
|
|
2231
|
+
0.1
|
|
2232
|
+
sage: n = QQ(902834098234908209348209834092834098); float(n)
|
|
2233
|
+
9.028340982349083e+35
|
|
2234
|
+
|
|
2235
|
+
TESTS:
|
|
2236
|
+
|
|
2237
|
+
Test that conversion agrees with `RR`::
|
|
2238
|
+
|
|
2239
|
+
sage: Q = [a/b for a in [-99..99] for b in [1..99]]
|
|
2240
|
+
sage: all(RDF(q) == RR(q) for q in Q)
|
|
2241
|
+
True
|
|
2242
|
+
|
|
2243
|
+
Test that the conversion has correct rounding on simple rationals::
|
|
2244
|
+
|
|
2245
|
+
sage: for p in [-100..100]: # needs sage.rings.real_mpfr
|
|
2246
|
+
....: for q in [1..100]:
|
|
2247
|
+
....: r = RDF(p/q)
|
|
2248
|
+
....: assert (RR(r).exact_rational() - p/q) <= r.ulp()/2
|
|
2249
|
+
|
|
2250
|
+
Test larger rationals::
|
|
2251
|
+
|
|
2252
|
+
sage: Q = continued_fraction(pi).convergents()[:100] # needs sage.symbolic
|
|
2253
|
+
sage: all(RDF(q) == RR(q) for q in Q)
|
|
2254
|
+
True
|
|
2255
|
+
|
|
2256
|
+
At some point, the continued fraction and direct conversion
|
|
2257
|
+
to ``RDF`` should agree::
|
|
2258
|
+
|
|
2259
|
+
sage: RDFpi = RDF(pi) # needs sage.symbolic
|
|
2260
|
+
sage: all(RDF(q) == RDFpi for q in Q[20:]) # needs sage.symbolic
|
|
2261
|
+
True
|
|
2262
|
+
"""
|
|
2263
|
+
return mpq_get_d_nearest(self.value)
|
|
2264
|
+
|
|
2265
|
+
def __hash__(self):
|
|
2266
|
+
"""
|
|
2267
|
+
Return hash of ``self``.
|
|
2268
|
+
|
|
2269
|
+
OUTPUT: integer
|
|
2270
|
+
|
|
2271
|
+
EXAMPLES::
|
|
2272
|
+
|
|
2273
|
+
sage: QQ(42).__hash__()
|
|
2274
|
+
42
|
|
2275
|
+
sage: QQ(1/42).__hash__()
|
|
2276
|
+
1488680910 # 32-bit
|
|
2277
|
+
-7658195599476688946 # 64-bit
|
|
2278
|
+
sage: n = ZZ.random_element(10^100)
|
|
2279
|
+
sage: hash(n) == hash(QQ(n)) or n
|
|
2280
|
+
True
|
|
2281
|
+
sage: hash(-n) == hash(-QQ(n)) or n
|
|
2282
|
+
True
|
|
2283
|
+
sage: hash(-4/17)
|
|
2284
|
+
-47583156 # 32-bit
|
|
2285
|
+
8709371129873690700 # 64-bit
|
|
2286
|
+
"""
|
|
2287
|
+
cdef Py_hash_t n = mpz_pythonhash(mpq_numref(self.value))
|
|
2288
|
+
cdef Py_hash_t d = mpz_pythonhash(mpq_denref(self.value))
|
|
2289
|
+
# The constant below is (1 + sqrt(5)) << 61
|
|
2290
|
+
return n + (d - 1) * <Py_hash_t>(7461864723258187525)
|
|
2291
|
+
|
|
2292
|
+
def __getitem__(self, int n):
|
|
2293
|
+
"""
|
|
2294
|
+
Return ``n``-th element of ``self``, viewed as a list. This is for
|
|
2295
|
+
consistency with how number field elements work.
|
|
2296
|
+
|
|
2297
|
+
INPUT:
|
|
2298
|
+
|
|
2299
|
+
- ``n`` -- integer (error if not 0 or -1)
|
|
2300
|
+
|
|
2301
|
+
OUTPUT: rational
|
|
2302
|
+
|
|
2303
|
+
EXAMPLES::
|
|
2304
|
+
|
|
2305
|
+
sage: (-4/17)[0]
|
|
2306
|
+
-4/17
|
|
2307
|
+
sage: (-4/17)[1]
|
|
2308
|
+
Traceback (most recent call last):
|
|
2309
|
+
...
|
|
2310
|
+
IndexError: index n (=1) out of range; it must be 0
|
|
2311
|
+
sage: (-4/17)[-1] # indexing from the right
|
|
2312
|
+
-4/17
|
|
2313
|
+
"""
|
|
2314
|
+
if n == 0 or n == -1:
|
|
2315
|
+
return self
|
|
2316
|
+
raise IndexError(f"index n (={n}) out of range; it must be 0")
|
|
2317
|
+
|
|
2318
|
+
################################################################
|
|
2319
|
+
# Optimized arithmetic
|
|
2320
|
+
################################################################
|
|
2321
|
+
def __add__(left, right):
|
|
2322
|
+
"""
|
|
2323
|
+
Return ``left`` plus ``right``.
|
|
2324
|
+
|
|
2325
|
+
EXAMPLES::
|
|
2326
|
+
|
|
2327
|
+
sage: (2/3) + (1/6)
|
|
2328
|
+
5/6
|
|
2329
|
+
sage: (1/3) + (1/2)
|
|
2330
|
+
5/6
|
|
2331
|
+
sage: (1/3) + 2
|
|
2332
|
+
7/3
|
|
2333
|
+
"""
|
|
2334
|
+
cdef Rational x
|
|
2335
|
+
if type(left) is type(right):
|
|
2336
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2337
|
+
mpq_add(x.value, (<Rational>left).value, (<Rational>right).value)
|
|
2338
|
+
return x
|
|
2339
|
+
elif type(right) is Integer:
|
|
2340
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2341
|
+
mpq_add_z(x.value, (<Rational>left).value, (<Integer>right).value)
|
|
2342
|
+
return x
|
|
2343
|
+
|
|
2344
|
+
return coercion_model.bin_op(left, right, operator.add)
|
|
2345
|
+
|
|
2346
|
+
cpdef _add_(self, right):
|
|
2347
|
+
"""
|
|
2348
|
+
Return ``right`` plus ``self``.
|
|
2349
|
+
|
|
2350
|
+
EXAMPLES::
|
|
2351
|
+
|
|
2352
|
+
sage: (2/3)._add_(1/6)
|
|
2353
|
+
5/6
|
|
2354
|
+
sage: (1/3)._add_(1/2)
|
|
2355
|
+
5/6
|
|
2356
|
+
"""
|
|
2357
|
+
cdef Rational x
|
|
2358
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2359
|
+
mpq_add(x.value, self.value, (<Rational>right).value)
|
|
2360
|
+
return x
|
|
2361
|
+
|
|
2362
|
+
def __sub__(left, right):
|
|
2363
|
+
"""
|
|
2364
|
+
Return ``left`` minus ``right``.
|
|
2365
|
+
|
|
2366
|
+
EXAMPLES::
|
|
2367
|
+
|
|
2368
|
+
sage: 11/3 - 5/4
|
|
2369
|
+
29/12
|
|
2370
|
+
|
|
2371
|
+
sage: (2/3) - 2
|
|
2372
|
+
-4/3
|
|
2373
|
+
sage: (-2/3) - 1
|
|
2374
|
+
-5/3
|
|
2375
|
+
sage: (2/3) - (-3)
|
|
2376
|
+
11/3
|
|
2377
|
+
sage: (-2/3) - (-3)
|
|
2378
|
+
7/3
|
|
2379
|
+
sage: 2/3 - polygen(QQ)
|
|
2380
|
+
-x + 2/3
|
|
2381
|
+
"""
|
|
2382
|
+
cdef Rational x
|
|
2383
|
+
if type(left) is type(right):
|
|
2384
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2385
|
+
mpq_sub(x.value, (<Rational>left).value, (<Rational>right).value)
|
|
2386
|
+
return x
|
|
2387
|
+
elif type(right) is Integer:
|
|
2388
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2389
|
+
mpz_mul(mpq_numref(x.value), mpq_denref((<Rational>left).value),
|
|
2390
|
+
(<Integer>right).value)
|
|
2391
|
+
mpz_sub(mpq_numref(x.value), mpq_numref((<Rational>left).value),
|
|
2392
|
+
mpq_numref(x.value))
|
|
2393
|
+
mpz_set(mpq_denref(x.value), mpq_denref((<Rational>left).value))
|
|
2394
|
+
return x
|
|
2395
|
+
|
|
2396
|
+
return coercion_model.bin_op(left, right, operator.sub)
|
|
2397
|
+
|
|
2398
|
+
cpdef _sub_(self, right):
|
|
2399
|
+
"""
|
|
2400
|
+
Return ``self`` minus ``right``.
|
|
2401
|
+
|
|
2402
|
+
EXAMPLES::
|
|
2403
|
+
|
|
2404
|
+
sage: (2/3)._sub_(1/6)
|
|
2405
|
+
1/2
|
|
2406
|
+
"""
|
|
2407
|
+
cdef Rational x
|
|
2408
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2409
|
+
mpq_sub(x.value, self.value, (<Rational>right).value)
|
|
2410
|
+
return x
|
|
2411
|
+
|
|
2412
|
+
cpdef _neg_(self):
|
|
2413
|
+
"""
|
|
2414
|
+
Negate ``self``.
|
|
2415
|
+
|
|
2416
|
+
EXAMPLES::
|
|
2417
|
+
|
|
2418
|
+
sage: -(2/3) # indirect doctest
|
|
2419
|
+
-2/3
|
|
2420
|
+
"""
|
|
2421
|
+
cdef Rational x
|
|
2422
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2423
|
+
mpq_neg(x.value, self.value)
|
|
2424
|
+
return x
|
|
2425
|
+
|
|
2426
|
+
def __mul__(left, right):
|
|
2427
|
+
"""
|
|
2428
|
+
Return ``left`` times ``right``.
|
|
2429
|
+
|
|
2430
|
+
EXAMPLES::
|
|
2431
|
+
|
|
2432
|
+
sage: (3/14) * 2/3
|
|
2433
|
+
1/7
|
|
2434
|
+
sage: (3/14) * 10
|
|
2435
|
+
15/7
|
|
2436
|
+
sage: 3/14 * polygen(QQ)
|
|
2437
|
+
3/14*x
|
|
2438
|
+
"""
|
|
2439
|
+
cdef Rational x
|
|
2440
|
+
if type(left) is type(right):
|
|
2441
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2442
|
+
mpq_mul(x.value, (<Rational>left).value, (<Rational>right).value)
|
|
2443
|
+
return x
|
|
2444
|
+
elif type(right) is Integer:
|
|
2445
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2446
|
+
mpq_mul_z(x.value, (<Rational>left).value, (<Integer>right).value)
|
|
2447
|
+
return x
|
|
2448
|
+
|
|
2449
|
+
return coercion_model.bin_op(left, right, operator.mul)
|
|
2450
|
+
|
|
2451
|
+
cpdef _mul_(self, right):
|
|
2452
|
+
"""
|
|
2453
|
+
Return ``self`` times ``right``.
|
|
2454
|
+
|
|
2455
|
+
EXAMPLES::
|
|
2456
|
+
|
|
2457
|
+
sage: (3/14)._mul_(2/3)
|
|
2458
|
+
1/7
|
|
2459
|
+
"""
|
|
2460
|
+
cdef Rational x
|
|
2461
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2462
|
+
if mpz_sizeinbase (mpq_numref(self.value), 2) > 100000 or \
|
|
2463
|
+
mpz_sizeinbase (mpq_denref(self.value), 2) > 100000:
|
|
2464
|
+
# We only use the signal handler (to enable ctrl-c out) in case
|
|
2465
|
+
# self is huge, so the product might actually take a while to compute.
|
|
2466
|
+
sig_on()
|
|
2467
|
+
mpq_mul(x.value, self.value, (<Rational>right).value)
|
|
2468
|
+
sig_off()
|
|
2469
|
+
else:
|
|
2470
|
+
mpq_mul(x.value, self.value, (<Rational>right).value)
|
|
2471
|
+
return x
|
|
2472
|
+
|
|
2473
|
+
def __truediv__(left, right):
|
|
2474
|
+
"""
|
|
2475
|
+
Return ``left`` divided by ``right``.
|
|
2476
|
+
|
|
2477
|
+
EXAMPLES::
|
|
2478
|
+
|
|
2479
|
+
sage: QQ((2,3)) / QQ((-5,4))
|
|
2480
|
+
-8/15
|
|
2481
|
+
sage: QQ((22,3)) / 4
|
|
2482
|
+
11/6
|
|
2483
|
+
sage: QQ((-2,3)) / (-4)
|
|
2484
|
+
1/6
|
|
2485
|
+
sage: QQ((2,3)) / QQ.zero()
|
|
2486
|
+
Traceback (most recent call last):
|
|
2487
|
+
...
|
|
2488
|
+
ZeroDivisionError: rational division by zero
|
|
2489
|
+
"""
|
|
2490
|
+
cdef Rational x
|
|
2491
|
+
if type(left) is type(right):
|
|
2492
|
+
if mpq_cmp_si((<Rational> right).value, 0, 1) == 0:
|
|
2493
|
+
raise ZeroDivisionError('rational division by zero')
|
|
2494
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2495
|
+
mpq_div(x.value, (<Rational>left).value, (<Rational>right).value)
|
|
2496
|
+
return x
|
|
2497
|
+
elif type(right) is Integer:
|
|
2498
|
+
if mpz_cmp_si((<Integer> right).value, 0) == 0:
|
|
2499
|
+
raise ZeroDivisionError('rational division by zero')
|
|
2500
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2501
|
+
mpq_div_zz(x.value, mpq_numref((<Rational>left).value), (<Integer>right).value)
|
|
2502
|
+
mpz_mul(mpq_denref(x.value), mpq_denref(x.value),
|
|
2503
|
+
mpq_denref((<Rational>left).value))
|
|
2504
|
+
return x
|
|
2505
|
+
|
|
2506
|
+
return coercion_model.bin_op(left, right, operator.truediv)
|
|
2507
|
+
|
|
2508
|
+
cpdef _div_(self, right):
|
|
2509
|
+
"""
|
|
2510
|
+
Return ``self`` divided by ``right``.
|
|
2511
|
+
|
|
2512
|
+
EXAMPLES::
|
|
2513
|
+
|
|
2514
|
+
sage: 2/3 # indirect doctest
|
|
2515
|
+
2/3
|
|
2516
|
+
sage: 3/0 # indirect doctest
|
|
2517
|
+
Traceback (most recent call last):
|
|
2518
|
+
...
|
|
2519
|
+
ZeroDivisionError: rational division by zero
|
|
2520
|
+
"""
|
|
2521
|
+
if mpq_cmp_si((<Rational> right).value, 0, 1) == 0:
|
|
2522
|
+
raise ZeroDivisionError('rational division by zero')
|
|
2523
|
+
cdef Rational x
|
|
2524
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2525
|
+
mpq_div(x.value, self.value, (<Rational>right).value)
|
|
2526
|
+
return x
|
|
2527
|
+
|
|
2528
|
+
################################################################
|
|
2529
|
+
# Other arithmetic operations.
|
|
2530
|
+
################################################################
|
|
2531
|
+
|
|
2532
|
+
def __invert__(self):
|
|
2533
|
+
"""
|
|
2534
|
+
Return the multiplicative inverse of ``self``.
|
|
2535
|
+
|
|
2536
|
+
OUTPUT: rational
|
|
2537
|
+
|
|
2538
|
+
EXAMPLES::
|
|
2539
|
+
|
|
2540
|
+
sage: (-4/17).__invert__()
|
|
2541
|
+
-17/4
|
|
2542
|
+
sage: ~(-4/17)
|
|
2543
|
+
-17/4
|
|
2544
|
+
"""
|
|
2545
|
+
if self.is_zero():
|
|
2546
|
+
raise ZeroDivisionError('rational division by zero')
|
|
2547
|
+
cdef Rational x
|
|
2548
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2549
|
+
mpq_inv(x.value, self.value)
|
|
2550
|
+
return x
|
|
2551
|
+
|
|
2552
|
+
cpdef _pow_(self, other):
|
|
2553
|
+
"""
|
|
2554
|
+
Raise ``self`` to the rational power ``other``.
|
|
2555
|
+
|
|
2556
|
+
EXAMPLES::
|
|
2557
|
+
|
|
2558
|
+
sage: (2/3)^5
|
|
2559
|
+
32/243
|
|
2560
|
+
sage: (-1/1)^(1/3) # needs sage.symbolic
|
|
2561
|
+
(-1)^(1/3)
|
|
2562
|
+
sage: (2/3)^(3/4) # needs sage.symbolic
|
|
2563
|
+
(2/3)^(3/4)
|
|
2564
|
+
sage: (-1/3)^0
|
|
2565
|
+
1
|
|
2566
|
+
sage: a = (0/1)^(0/1); a
|
|
2567
|
+
1
|
|
2568
|
+
sage: type(a)
|
|
2569
|
+
<class 'sage.rings.rational.Rational'>
|
|
2570
|
+
|
|
2571
|
+
If the result is rational, it is returned as a rational::
|
|
2572
|
+
|
|
2573
|
+
sage: a = (4/9)^(1/2); a
|
|
2574
|
+
2/3
|
|
2575
|
+
sage: parent(a)
|
|
2576
|
+
Rational Field
|
|
2577
|
+
sage: (-27/125)^(1/3) # needs sage.symbolic
|
|
2578
|
+
3/5*(-1)^(1/3)
|
|
2579
|
+
sage: (-27/125)^(1/2) # needs sage.symbolic
|
|
2580
|
+
3/5*sqrt(-3/5)
|
|
2581
|
+
|
|
2582
|
+
The result is normalized to have the rational power in the numerator::
|
|
2583
|
+
|
|
2584
|
+
sage: 2^(-1/2) # needs sage.symbolic
|
|
2585
|
+
1/2*sqrt(2)
|
|
2586
|
+
sage: 8^(-1/5) # needs sage.symbolic
|
|
2587
|
+
1/8*8^(4/5)
|
|
2588
|
+
sage: 3^(-3/2) # needs sage.symbolic
|
|
2589
|
+
1/9*sqrt(3)
|
|
2590
|
+
|
|
2591
|
+
TESTS::
|
|
2592
|
+
|
|
2593
|
+
sage: QQ(0)^(-1)
|
|
2594
|
+
Traceback (most recent call last):
|
|
2595
|
+
...
|
|
2596
|
+
ZeroDivisionError: rational division by zero
|
|
2597
|
+
|
|
2598
|
+
This works even if the base is a Python integer::
|
|
2599
|
+
|
|
2600
|
+
sage: int(2)^(1/2) # needs sage.symbolic
|
|
2601
|
+
sqrt(2)
|
|
2602
|
+
sage: a = int(2)^(3/1); a
|
|
2603
|
+
8
|
|
2604
|
+
sage: type(a)
|
|
2605
|
+
<class 'sage.rings.rational.Rational'>
|
|
2606
|
+
|
|
2607
|
+
The exponent must fit in a ``long`` unless the base is -1, 0, or 1::
|
|
2608
|
+
|
|
2609
|
+
sage: (1/2)^(2^100)
|
|
2610
|
+
Traceback (most recent call last):
|
|
2611
|
+
...
|
|
2612
|
+
OverflowError: exponent must be at most 2147483647 # 32-bit
|
|
2613
|
+
OverflowError: exponent must be at most 9223372036854775807 # 64-bit
|
|
2614
|
+
sage: (1/2)^(-2^100)
|
|
2615
|
+
Traceback (most recent call last):
|
|
2616
|
+
...
|
|
2617
|
+
OverflowError: exponent must be at most 2147483647 # 32-bit
|
|
2618
|
+
OverflowError: exponent must be at most 9223372036854775807 # 64-bit
|
|
2619
|
+
sage: QQ(-1)^(2^100) # needs sage.symbolic
|
|
2620
|
+
1
|
|
2621
|
+
"""
|
|
2622
|
+
n = <Rational?>other
|
|
2623
|
+
|
|
2624
|
+
# If the exponent happens to be an integer, we can use optimized code
|
|
2625
|
+
if mpz_cmp_ui(mpq_denref(n.value), 1) == 0:
|
|
2626
|
+
if mpz_fits_slong_p(mpq_numref(n.value)):
|
|
2627
|
+
return self._pow_long(mpz_get_si(mpq_numref(n.value)))
|
|
2628
|
+
|
|
2629
|
+
# Perhaps it can be done exactly
|
|
2630
|
+
c, d = rational_power_parts(self, n)
|
|
2631
|
+
if d == 1:
|
|
2632
|
+
# It was an exact power
|
|
2633
|
+
return c
|
|
2634
|
+
elif d == -1 and n.denominator() == 2:
|
|
2635
|
+
# Exact rational times a power of I
|
|
2636
|
+
from sage.rings.imaginary_unit import I
|
|
2637
|
+
return c * I ** (n.numerator() % 4)
|
|
2638
|
+
|
|
2639
|
+
# Result is c * d^n but we cannot simplify d^n further:
|
|
2640
|
+
# return a symbolic expression.
|
|
2641
|
+
# We use the hold=True keyword argument to prevent the
|
|
2642
|
+
# symbolics library from trying to simplify this expression
|
|
2643
|
+
# again. This would lead to infinite loops otherwise.
|
|
2644
|
+
from sage.symbolic.ring import SR
|
|
2645
|
+
return SR(c) * SR(d).power(n, hold=True)
|
|
2646
|
+
|
|
2647
|
+
cpdef _pow_int(self, n):
|
|
2648
|
+
"""
|
|
2649
|
+
Raise ``self`` to the integer power ``n``.
|
|
2650
|
+
|
|
2651
|
+
TESTS::
|
|
2652
|
+
|
|
2653
|
+
sage: a = QQ(3)._pow_int(2); a
|
|
2654
|
+
9
|
|
2655
|
+
sage: parent(a)
|
|
2656
|
+
Rational Field
|
|
2657
|
+
sage: a = (1/3)._pow_int(-2); a
|
|
2658
|
+
9
|
|
2659
|
+
sage: parent(a)
|
|
2660
|
+
Rational Field
|
|
2661
|
+
"""
|
|
2662
|
+
# This is only called whenever n does not fit in a long
|
|
2663
|
+
# (otherwise _pow_long would be called). So we don't have to
|
|
2664
|
+
# be particularly efficient here.
|
|
2665
|
+
return self._pow_(Rational(n))
|
|
2666
|
+
|
|
2667
|
+
cdef _pow_long(self, long n):
|
|
2668
|
+
"""
|
|
2669
|
+
TESTS::
|
|
2670
|
+
|
|
2671
|
+
sage: QQ(2/5) ^ 0
|
|
2672
|
+
1
|
|
2673
|
+
sage: QQ(2/5) ^ int(3)
|
|
2674
|
+
8/125
|
|
2675
|
+
sage: QQ(2/5) ^ (-3)
|
|
2676
|
+
125/8
|
|
2677
|
+
sage: QQ(2/5) ^ QQ(-3)
|
|
2678
|
+
125/8
|
|
2679
|
+
sage: QQ(-2/5) ^ int(0)
|
|
2680
|
+
1
|
|
2681
|
+
sage: QQ(-2/5) ^ 3
|
|
2682
|
+
-8/125
|
|
2683
|
+
sage: QQ(-2/5) ^ int(-3)
|
|
2684
|
+
-125/8
|
|
2685
|
+
sage: QQ(-2/5) ^ QQ(3)
|
|
2686
|
+
-8/125
|
|
2687
|
+
"""
|
|
2688
|
+
cdef Rational x = <Rational>Rational.__new__(Rational)
|
|
2689
|
+
|
|
2690
|
+
if n == 0:
|
|
2691
|
+
mpq_set_si(x.value, 1, 1)
|
|
2692
|
+
elif n > 0:
|
|
2693
|
+
sig_on()
|
|
2694
|
+
mpz_pow_ui(mpq_numref(x.value), mpq_numref(self.value), n)
|
|
2695
|
+
mpz_pow_ui(mpq_denref(x.value), mpq_denref(self.value), n)
|
|
2696
|
+
sig_off()
|
|
2697
|
+
else: # n < 0:
|
|
2698
|
+
if mpz_sgn(mpq_numref(self.value)) == 0:
|
|
2699
|
+
raise ZeroDivisionError("rational division by zero")
|
|
2700
|
+
sig_on()
|
|
2701
|
+
mpz_pow_ui(mpq_denref(x.value), mpq_numref(self.value), -<unsigned long>n)
|
|
2702
|
+
mpz_pow_ui(mpq_numref(x.value), mpq_denref(self.value), -<unsigned long>n)
|
|
2703
|
+
# Fix signs
|
|
2704
|
+
if mpz_sgn(mpq_denref(x.value)) < 0:
|
|
2705
|
+
mpz_neg(mpq_numref(x.value), mpq_numref(x.value))
|
|
2706
|
+
mpz_neg(mpq_denref(x.value), mpq_denref(x.value))
|
|
2707
|
+
sig_off()
|
|
2708
|
+
return x
|
|
2709
|
+
|
|
2710
|
+
def __pos__(self):
|
|
2711
|
+
"""
|
|
2712
|
+
Return ``self``.
|
|
2713
|
+
|
|
2714
|
+
OUTPUT: rational
|
|
2715
|
+
|
|
2716
|
+
EXAMPLES::
|
|
2717
|
+
|
|
2718
|
+
sage: (-4/17).__pos__()
|
|
2719
|
+
-4/17
|
|
2720
|
+
sage: +(-4/17)
|
|
2721
|
+
-4/17
|
|
2722
|
+
"""
|
|
2723
|
+
return self
|
|
2724
|
+
|
|
2725
|
+
def __neg__(self):
|
|
2726
|
+
"""
|
|
2727
|
+
Return the negative of ``self``.
|
|
2728
|
+
|
|
2729
|
+
OUTPUT: rational
|
|
2730
|
+
|
|
2731
|
+
EXAMPLES::
|
|
2732
|
+
|
|
2733
|
+
sage: (-4/17).__neg__()
|
|
2734
|
+
4/17
|
|
2735
|
+
sage: - (-4/17)
|
|
2736
|
+
4/17
|
|
2737
|
+
"""
|
|
2738
|
+
cdef Rational x
|
|
2739
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2740
|
+
mpq_neg(x.value, self.value)
|
|
2741
|
+
return x
|
|
2742
|
+
|
|
2743
|
+
def __bool__(self):
|
|
2744
|
+
"""
|
|
2745
|
+
Return ``True`` if this rational number is nonzero.
|
|
2746
|
+
|
|
2747
|
+
OUTPUT: boolean
|
|
2748
|
+
|
|
2749
|
+
EXAMPLES::
|
|
2750
|
+
|
|
2751
|
+
sage: bool(0/5)
|
|
2752
|
+
False
|
|
2753
|
+
sage: bool(-4/17)
|
|
2754
|
+
True
|
|
2755
|
+
"""
|
|
2756
|
+
# A rational number is zero iff its numerator is zero.
|
|
2757
|
+
return mpq_sgn(self.value) != 0
|
|
2758
|
+
|
|
2759
|
+
def __abs__(self):
|
|
2760
|
+
"""
|
|
2761
|
+
Return the absolute value of this rational number.
|
|
2762
|
+
|
|
2763
|
+
OUTPUT: rational
|
|
2764
|
+
|
|
2765
|
+
EXAMPLES::
|
|
2766
|
+
|
|
2767
|
+
sage: (-4/17).__abs__()
|
|
2768
|
+
4/17
|
|
2769
|
+
sage: abs(-4/17)
|
|
2770
|
+
4/17
|
|
2771
|
+
"""
|
|
2772
|
+
cdef Rational x
|
|
2773
|
+
x = <Rational> Rational.__new__(Rational)
|
|
2774
|
+
mpq_abs(x.value, self.value)
|
|
2775
|
+
return x
|
|
2776
|
+
|
|
2777
|
+
def sign(self):
|
|
2778
|
+
"""
|
|
2779
|
+
Return the sign of this rational number, which is -1, 0, or 1
|
|
2780
|
+
depending on whether this number is negative, zero, or positive
|
|
2781
|
+
respectively.
|
|
2782
|
+
|
|
2783
|
+
OUTPUT: integer
|
|
2784
|
+
|
|
2785
|
+
EXAMPLES::
|
|
2786
|
+
|
|
2787
|
+
sage: (2/3).sign()
|
|
2788
|
+
1
|
|
2789
|
+
sage: (0/3).sign()
|
|
2790
|
+
0
|
|
2791
|
+
sage: (-1/6).sign()
|
|
2792
|
+
-1
|
|
2793
|
+
"""
|
|
2794
|
+
return smallInteger(mpq_sgn(self.value))
|
|
2795
|
+
|
|
2796
|
+
def mod_ui(Rational self, unsigned long int n):
|
|
2797
|
+
"""
|
|
2798
|
+
Return the remainder upon division of ``self`` by the unsigned long
|
|
2799
|
+
integer ``n``.
|
|
2800
|
+
|
|
2801
|
+
INPUT:
|
|
2802
|
+
|
|
2803
|
+
- ``n`` -- an unsigned long integer
|
|
2804
|
+
|
|
2805
|
+
OUTPUT: integer
|
|
2806
|
+
|
|
2807
|
+
EXAMPLES::
|
|
2808
|
+
|
|
2809
|
+
sage: (-4/17).mod_ui(3)
|
|
2810
|
+
1
|
|
2811
|
+
sage: (-4/17).mod_ui(17)
|
|
2812
|
+
Traceback (most recent call last):
|
|
2813
|
+
...
|
|
2814
|
+
ArithmeticError: The inverse of 0 modulo 17 is not defined.
|
|
2815
|
+
"""
|
|
2816
|
+
cdef unsigned int num, den, a
|
|
2817
|
+
|
|
2818
|
+
# Documentation from GMP manual:
|
|
2819
|
+
# "For the ui variants the return value is the remainder, and
|
|
2820
|
+
# in fact returning the remainder is all the div_ui functions do."
|
|
2821
|
+
sig_on()
|
|
2822
|
+
num = mpz_fdiv_ui(mpq_numref(self.value), n)
|
|
2823
|
+
den = mpz_fdiv_ui(mpq_denref(self.value), n)
|
|
2824
|
+
sig_off()
|
|
2825
|
+
return int((num * ai.inverse_mod_int(den, n)) % n)
|
|
2826
|
+
|
|
2827
|
+
def __mod__(x, y):
|
|
2828
|
+
"""
|
|
2829
|
+
Return the remainder of division of ``x`` by ``y``, where ``y`` is
|
|
2830
|
+
something that can be coerced to an integer.
|
|
2831
|
+
|
|
2832
|
+
INPUT:
|
|
2833
|
+
|
|
2834
|
+
- ``other`` -- object that coerces to an integer
|
|
2835
|
+
|
|
2836
|
+
OUTPUT: integer
|
|
2837
|
+
|
|
2838
|
+
EXAMPLES::
|
|
2839
|
+
|
|
2840
|
+
sage: (-4/17).__mod__(3/1)
|
|
2841
|
+
1
|
|
2842
|
+
|
|
2843
|
+
TESTS:
|
|
2844
|
+
|
|
2845
|
+
Check that :issue:`14870` is fixed::
|
|
2846
|
+
|
|
2847
|
+
sage: int(4) % QQ(3)
|
|
2848
|
+
1
|
|
2849
|
+
"""
|
|
2850
|
+
cdef Rational rat
|
|
2851
|
+
if not isinstance(x, Rational):
|
|
2852
|
+
rat = Rational(x)
|
|
2853
|
+
else:
|
|
2854
|
+
rat = x
|
|
2855
|
+
cdef other = integer.Integer(y)
|
|
2856
|
+
if not other:
|
|
2857
|
+
raise ZeroDivisionError("Rational modulo by zero")
|
|
2858
|
+
n = rat.numer() % other
|
|
2859
|
+
d = rat.denom() % other
|
|
2860
|
+
d = d.inverse_mod(other)
|
|
2861
|
+
return (n * d) % other
|
|
2862
|
+
|
|
2863
|
+
def norm(self):
|
|
2864
|
+
r"""
|
|
2865
|
+
Return the norm from `\QQ` to `\QQ` of `x` (which is just `x`). This
|
|
2866
|
+
was added for compatibility with :class:`NumberField`.
|
|
2867
|
+
|
|
2868
|
+
OUTPUT: ``Rational`` -- reference to ``self``
|
|
2869
|
+
|
|
2870
|
+
EXAMPLES::
|
|
2871
|
+
|
|
2872
|
+
sage: (1/3).norm()
|
|
2873
|
+
1/3
|
|
2874
|
+
|
|
2875
|
+
AUTHORS:
|
|
2876
|
+
|
|
2877
|
+
- Craig Citro
|
|
2878
|
+
"""
|
|
2879
|
+
return self
|
|
2880
|
+
|
|
2881
|
+
def relative_norm(self):
|
|
2882
|
+
"""
|
|
2883
|
+
Return the norm from Q to Q of x (which is just x). This was added for
|
|
2884
|
+
compatibility with NumberFields.
|
|
2885
|
+
|
|
2886
|
+
EXAMPLES::
|
|
2887
|
+
|
|
2888
|
+
sage: (6/5).relative_norm()
|
|
2889
|
+
6/5
|
|
2890
|
+
|
|
2891
|
+
sage: QQ(7/5).relative_norm()
|
|
2892
|
+
7/5
|
|
2893
|
+
"""
|
|
2894
|
+
return self
|
|
2895
|
+
|
|
2896
|
+
def absolute_norm(self):
|
|
2897
|
+
"""
|
|
2898
|
+
Return the norm from Q to Q of x (which is just x). This was added for
|
|
2899
|
+
compatibility with NumberFields.
|
|
2900
|
+
|
|
2901
|
+
EXAMPLES::
|
|
2902
|
+
|
|
2903
|
+
sage: (6/5).absolute_norm()
|
|
2904
|
+
6/5
|
|
2905
|
+
|
|
2906
|
+
sage: QQ(7/5).absolute_norm()
|
|
2907
|
+
7/5
|
|
2908
|
+
"""
|
|
2909
|
+
return self
|
|
2910
|
+
|
|
2911
|
+
def trace(self):
|
|
2912
|
+
r"""
|
|
2913
|
+
Return the trace from `\QQ` to `\QQ` of `x` (which is just `x`). This
|
|
2914
|
+
was added for compatibility with :class:`NumberFields`.
|
|
2915
|
+
|
|
2916
|
+
OUTPUT: ``Rational`` -- reference to ``self``
|
|
2917
|
+
|
|
2918
|
+
EXAMPLES::
|
|
2919
|
+
|
|
2920
|
+
sage: (1/3).trace()
|
|
2921
|
+
1/3
|
|
2922
|
+
|
|
2923
|
+
AUTHORS:
|
|
2924
|
+
|
|
2925
|
+
- Craig Citro
|
|
2926
|
+
"""
|
|
2927
|
+
return self
|
|
2928
|
+
|
|
2929
|
+
def charpoly(self, var='x'):
|
|
2930
|
+
"""
|
|
2931
|
+
Return the characteristic polynomial of this rational number. This
|
|
2932
|
+
will always be just ``var - self``; this is really here so that code
|
|
2933
|
+
written for number fields won't crash when applied to rational
|
|
2934
|
+
numbers.
|
|
2935
|
+
|
|
2936
|
+
INPUT:
|
|
2937
|
+
|
|
2938
|
+
- ``var`` -- string
|
|
2939
|
+
|
|
2940
|
+
OUTPUT: polynomial
|
|
2941
|
+
|
|
2942
|
+
EXAMPLES::
|
|
2943
|
+
|
|
2944
|
+
sage: (1/3).charpoly('x')
|
|
2945
|
+
x - 1/3
|
|
2946
|
+
|
|
2947
|
+
The default is ``var='x'``. (:issue:`20967`)::
|
|
2948
|
+
|
|
2949
|
+
sage: a = QQ(2); a.charpoly('x')
|
|
2950
|
+
x - 2
|
|
2951
|
+
|
|
2952
|
+
|
|
2953
|
+
AUTHORS:
|
|
2954
|
+
|
|
2955
|
+
- Craig Citro
|
|
2956
|
+
"""
|
|
2957
|
+
QQ = self.parent()
|
|
2958
|
+
return QQ[var]([-self,1])
|
|
2959
|
+
|
|
2960
|
+
def minpoly(self, var='x'):
|
|
2961
|
+
"""
|
|
2962
|
+
Return the minimal polynomial of this rational number. This will
|
|
2963
|
+
always be just ``x - self``; this is really here so that code written
|
|
2964
|
+
for number fields won't crash when applied to rational numbers.
|
|
2965
|
+
|
|
2966
|
+
INPUT:
|
|
2967
|
+
|
|
2968
|
+
- ``var`` -- string
|
|
2969
|
+
|
|
2970
|
+
OUTPUT: polynomial
|
|
2971
|
+
|
|
2972
|
+
EXAMPLES::
|
|
2973
|
+
|
|
2974
|
+
sage: (1/3).minpoly()
|
|
2975
|
+
x - 1/3
|
|
2976
|
+
sage: (1/3).minpoly('y')
|
|
2977
|
+
y - 1/3
|
|
2978
|
+
|
|
2979
|
+
AUTHORS:
|
|
2980
|
+
|
|
2981
|
+
- Craig Citro
|
|
2982
|
+
"""
|
|
2983
|
+
QQ = self.parent()
|
|
2984
|
+
return QQ[var]([-self,1])
|
|
2985
|
+
|
|
2986
|
+
def _integer_(self, Z=None):
|
|
2987
|
+
"""
|
|
2988
|
+
Return ``self`` coerced to an integer. Of course this rational number
|
|
2989
|
+
must have a denominator of 1.
|
|
2990
|
+
|
|
2991
|
+
OUTPUT: integer
|
|
2992
|
+
|
|
2993
|
+
EXAMPLES::
|
|
2994
|
+
|
|
2995
|
+
sage: (-4/17)._integer_()
|
|
2996
|
+
Traceback (most recent call last):
|
|
2997
|
+
...
|
|
2998
|
+
TypeError: no conversion of this rational to integer
|
|
2999
|
+
sage: (-4/1)._integer_()
|
|
3000
|
+
-4
|
|
3001
|
+
"""
|
|
3002
|
+
if not mpz_cmp_si(mpq_denref(self.value), 1) == 0:
|
|
3003
|
+
raise TypeError("no conversion of this rational to integer")
|
|
3004
|
+
cdef Integer n = Integer.__new__(Integer)
|
|
3005
|
+
n.set_from_mpz(mpq_numref(self.value))
|
|
3006
|
+
return n
|
|
3007
|
+
|
|
3008
|
+
def numerator(self):
|
|
3009
|
+
"""
|
|
3010
|
+
Return the numerator of this rational number.
|
|
3011
|
+
:meth:`numer` is an alias of :meth:`numerator`.
|
|
3012
|
+
|
|
3013
|
+
EXAMPLES::
|
|
3014
|
+
|
|
3015
|
+
sage: x = 5/11
|
|
3016
|
+
sage: x.numerator()
|
|
3017
|
+
5
|
|
3018
|
+
|
|
3019
|
+
sage: x = 9/3
|
|
3020
|
+
sage: x.numerator()
|
|
3021
|
+
3
|
|
3022
|
+
|
|
3023
|
+
sage: x = -5/11
|
|
3024
|
+
sage: x.numer()
|
|
3025
|
+
-5
|
|
3026
|
+
"""
|
|
3027
|
+
cdef Integer n = Integer.__new__(Integer)
|
|
3028
|
+
n.set_from_mpz(mpq_numref(self.value))
|
|
3029
|
+
return n
|
|
3030
|
+
|
|
3031
|
+
#Define an alias for numerator
|
|
3032
|
+
numer = numerator
|
|
3033
|
+
|
|
3034
|
+
def __int__(self):
|
|
3035
|
+
"""
|
|
3036
|
+
Convert this rational to a Python ``int``.
|
|
3037
|
+
|
|
3038
|
+
This truncates ``self`` if ``self`` has a denominator (which is
|
|
3039
|
+
consistent with Python's ``int(floats)``).
|
|
3040
|
+
|
|
3041
|
+
EXAMPLES::
|
|
3042
|
+
|
|
3043
|
+
sage: int(7/1)
|
|
3044
|
+
7
|
|
3045
|
+
sage: int(7/2)
|
|
3046
|
+
3
|
|
3047
|
+
"""
|
|
3048
|
+
cdef mpz_t x
|
|
3049
|
+
if mpz_cmp_si(mpq_denref(self.value),1) != 0:
|
|
3050
|
+
mpz_init(x)
|
|
3051
|
+
mpz_tdiv_q(x, mpq_numref(self.value), mpq_denref(self.value))
|
|
3052
|
+
n = mpz_get_pylong(x)
|
|
3053
|
+
mpz_clear(x)
|
|
3054
|
+
return n
|
|
3055
|
+
else:
|
|
3056
|
+
return mpz_get_pylong(mpq_numref(self.value))
|
|
3057
|
+
|
|
3058
|
+
def denominator(self):
|
|
3059
|
+
"""
|
|
3060
|
+
Return the denominator of this rational number.
|
|
3061
|
+
:meth:`denom` is an alias of :meth:`denominator`.
|
|
3062
|
+
|
|
3063
|
+
EXAMPLES::
|
|
3064
|
+
|
|
3065
|
+
sage: x = -5/11
|
|
3066
|
+
sage: x.denominator()
|
|
3067
|
+
11
|
|
3068
|
+
|
|
3069
|
+
sage: x = 9/3
|
|
3070
|
+
sage: x.denominator()
|
|
3071
|
+
1
|
|
3072
|
+
|
|
3073
|
+
sage: x = 5/13
|
|
3074
|
+
sage: x.denom()
|
|
3075
|
+
13
|
|
3076
|
+
"""
|
|
3077
|
+
cdef Integer n = Integer.__new__(Integer)
|
|
3078
|
+
n.set_from_mpz(mpq_denref(self.value))
|
|
3079
|
+
return n
|
|
3080
|
+
|
|
3081
|
+
#Define an alias for denominator
|
|
3082
|
+
denom = denominator
|
|
3083
|
+
|
|
3084
|
+
def as_integer_ratio(self):
|
|
3085
|
+
"""
|
|
3086
|
+
Return the pair ``(self.numerator(), self.denominator())``.
|
|
3087
|
+
|
|
3088
|
+
EXAMPLES::
|
|
3089
|
+
|
|
3090
|
+
sage: x = -12/29
|
|
3091
|
+
sage: x.as_integer_ratio()
|
|
3092
|
+
(-12, 29)
|
|
3093
|
+
"""
|
|
3094
|
+
n = <Integer>Integer.__new__(Integer)
|
|
3095
|
+
d = <Integer>Integer.__new__(Integer)
|
|
3096
|
+
n.set_from_mpz(mpq_numref(self.value))
|
|
3097
|
+
d.set_from_mpz(mpq_denref(self.value))
|
|
3098
|
+
return (n, d)
|
|
3099
|
+
|
|
3100
|
+
def factor(self):
|
|
3101
|
+
"""
|
|
3102
|
+
Return the factorization of this rational number.
|
|
3103
|
+
|
|
3104
|
+
OUTPUT: factorization
|
|
3105
|
+
|
|
3106
|
+
EXAMPLES::
|
|
3107
|
+
|
|
3108
|
+
sage: (-4/17).factor()
|
|
3109
|
+
-1 * 2^2 * 17^-1
|
|
3110
|
+
|
|
3111
|
+
Trying to factor 0 gives an arithmetic error::
|
|
3112
|
+
|
|
3113
|
+
sage: (0/1).factor()
|
|
3114
|
+
Traceback (most recent call last):
|
|
3115
|
+
...
|
|
3116
|
+
ArithmeticError: factorization of 0 is not defined
|
|
3117
|
+
"""
|
|
3118
|
+
from sage.structure.factorization import Factorization
|
|
3119
|
+
return self.numerator().factor() * \
|
|
3120
|
+
Factorization([(p, -e) for p, e in self.denominator().factor()])
|
|
3121
|
+
|
|
3122
|
+
def support(self):
|
|
3123
|
+
"""
|
|
3124
|
+
Return a sorted list of the primes where this rational number has
|
|
3125
|
+
nonzero valuation.
|
|
3126
|
+
|
|
3127
|
+
OUTPUT: the set of primes appearing in the factorization of this
|
|
3128
|
+
rational with nonzero exponent, as a sorted list.
|
|
3129
|
+
|
|
3130
|
+
EXAMPLES::
|
|
3131
|
+
|
|
3132
|
+
sage: (-4/17).support()
|
|
3133
|
+
[2, 17]
|
|
3134
|
+
|
|
3135
|
+
Trying to find the support of 0 gives an arithmetic error::
|
|
3136
|
+
|
|
3137
|
+
sage: (0/1).support()
|
|
3138
|
+
Traceback (most recent call last):
|
|
3139
|
+
...
|
|
3140
|
+
ArithmeticError: Support of 0 not defined.
|
|
3141
|
+
"""
|
|
3142
|
+
if self.is_zero():
|
|
3143
|
+
raise ArithmeticError("Support of 0 not defined.")
|
|
3144
|
+
from sage.arith.misc import prime_factors
|
|
3145
|
+
|
|
3146
|
+
return prime_factors(self)
|
|
3147
|
+
|
|
3148
|
+
def log(self, m=None, prec=None):
|
|
3149
|
+
r"""
|
|
3150
|
+
Return the log of ``self``.
|
|
3151
|
+
|
|
3152
|
+
INPUT:
|
|
3153
|
+
|
|
3154
|
+
- ``m`` -- the base (default: natural log base e)
|
|
3155
|
+
|
|
3156
|
+
- ``prec`` -- integer (optional); the precision in bits
|
|
3157
|
+
|
|
3158
|
+
OUTPUT:
|
|
3159
|
+
|
|
3160
|
+
When ``prec`` is not given, the log as an element in symbolic
|
|
3161
|
+
ring unless the logarithm is exact. Otherwise the log is a
|
|
3162
|
+
:class:`RealField` approximation to ``prec`` bit precision.
|
|
3163
|
+
|
|
3164
|
+
EXAMPLES::
|
|
3165
|
+
|
|
3166
|
+
sage: (124/345).log(5) # needs sage.symbolic
|
|
3167
|
+
log(124/345)/log(5)
|
|
3168
|
+
sage: (124/345).log(5, 100) # needs sage.rings.real_mpfr
|
|
3169
|
+
-0.63578895682825611710391773754
|
|
3170
|
+
sage: log(QQ(125)) # needs sage.symbolic
|
|
3171
|
+
3*log(5)
|
|
3172
|
+
sage: log(QQ(125), 5)
|
|
3173
|
+
3
|
|
3174
|
+
sage: log(QQ(125), 3) # needs sage.symbolic
|
|
3175
|
+
3*log(5)/log(3)
|
|
3176
|
+
sage: QQ(8).log(1/2)
|
|
3177
|
+
-3
|
|
3178
|
+
sage: (1/8).log(1/2)
|
|
3179
|
+
3
|
|
3180
|
+
sage: (1/2).log(1/8)
|
|
3181
|
+
1/3
|
|
3182
|
+
sage: (1/2).log(8)
|
|
3183
|
+
-1/3
|
|
3184
|
+
sage: (16/81).log(8/27) # needs sage.libs.pari
|
|
3185
|
+
4/3
|
|
3186
|
+
sage: (8/27).log(16/81) # needs sage.libs.pari
|
|
3187
|
+
3/4
|
|
3188
|
+
sage: log(27/8, 16/81) # needs sage.libs.pari
|
|
3189
|
+
-3/4
|
|
3190
|
+
sage: log(16/81, 27/8) # needs sage.libs.pari
|
|
3191
|
+
-4/3
|
|
3192
|
+
sage: (125/8).log(5/2) # needs sage.libs.pari
|
|
3193
|
+
3
|
|
3194
|
+
sage: (125/8).log(5/2, prec=53) # needs sage.rings.real_mpfr
|
|
3195
|
+
3.00000000000000
|
|
3196
|
+
|
|
3197
|
+
TESTS::
|
|
3198
|
+
|
|
3199
|
+
sage: (25/2).log(5/2) # needs sage.symbolic
|
|
3200
|
+
log(25/2)/log(5/2)
|
|
3201
|
+
sage: (-1/2).log(3) # needs sage.symbolic
|
|
3202
|
+
(I*pi + log(1/2))/log(3)
|
|
3203
|
+
"""
|
|
3204
|
+
cdef int self_sgn
|
|
3205
|
+
if self.denom().is_one():
|
|
3206
|
+
return ZZ(self.numer()).log(m, prec)
|
|
3207
|
+
if m is not None and m <= 0:
|
|
3208
|
+
raise ValueError("log base must be positive")
|
|
3209
|
+
self_sgn = mpz_sgn(mpq_numref(self.value))
|
|
3210
|
+
if self_sgn < 0 and prec is None:
|
|
3211
|
+
from sage.symbolic.ring import SR
|
|
3212
|
+
return SR(self).log(m)
|
|
3213
|
+
if prec:
|
|
3214
|
+
if self_sgn >= 0:
|
|
3215
|
+
from sage.rings.real_mpfr import RealField
|
|
3216
|
+
return RealField(prec)(self).log(m)
|
|
3217
|
+
else:
|
|
3218
|
+
from sage.rings.complex_mpfr import ComplexField
|
|
3219
|
+
return ComplexField(prec)(self).log(m)
|
|
3220
|
+
|
|
3221
|
+
from sage.functions.log import function_log
|
|
3222
|
+
if m is None:
|
|
3223
|
+
return function_log(self, dont_call_method_on_arg=True)
|
|
3224
|
+
|
|
3225
|
+
anum = self.numer()
|
|
3226
|
+
aden = self.denom()
|
|
3227
|
+
mrat = Rational(m)
|
|
3228
|
+
bnum = mrat.numer()
|
|
3229
|
+
bden = mrat.denom()
|
|
3230
|
+
|
|
3231
|
+
anp = anum.perfect_power()
|
|
3232
|
+
bnp = bnum.perfect_power()
|
|
3233
|
+
adp = aden.perfect_power()
|
|
3234
|
+
bdp = bden.perfect_power()
|
|
3235
|
+
|
|
3236
|
+
if anum.is_one():
|
|
3237
|
+
a_exp=adp[1]
|
|
3238
|
+
a_base=1/adp[0]
|
|
3239
|
+
# we already know that aden!=0
|
|
3240
|
+
else:
|
|
3241
|
+
a_exp=anp[1].gcd(adp[1])
|
|
3242
|
+
a_base=(anp[0]**(anp[1]//a_exp))/(adp[0]**(adp[1]//a_exp))
|
|
3243
|
+
|
|
3244
|
+
if bnum.is_one():
|
|
3245
|
+
b_exp=bdp[1]
|
|
3246
|
+
b_base=1/bdp[0]
|
|
3247
|
+
elif bden.is_one():
|
|
3248
|
+
b_exp=bnp[1]
|
|
3249
|
+
b_base=bnp[0]
|
|
3250
|
+
else:
|
|
3251
|
+
b_exp=bnp[1].gcd(bdp[1])
|
|
3252
|
+
b_base=(bnp[0]**(bnp[1]//b_exp))/(bdp[0]**(bdp[1]//b_exp))
|
|
3253
|
+
|
|
3254
|
+
if a_base == b_base:
|
|
3255
|
+
return a_exp/b_exp
|
|
3256
|
+
elif a_base*b_base == 1:
|
|
3257
|
+
return -a_exp/b_exp
|
|
3258
|
+
|
|
3259
|
+
return (function_log(self, dont_call_method_on_arg=True) /
|
|
3260
|
+
function_log(m, dont_call_method_on_arg=True))
|
|
3261
|
+
|
|
3262
|
+
def gamma(self, *, prec=None):
|
|
3263
|
+
"""
|
|
3264
|
+
Return the gamma function evaluated at ``self``. This value is exact
|
|
3265
|
+
for integers and half-integers, and returns a symbolic value
|
|
3266
|
+
otherwise. For a numerical approximation, use keyword ``prec``.
|
|
3267
|
+
|
|
3268
|
+
EXAMPLES::
|
|
3269
|
+
|
|
3270
|
+
sage: # needs sage.symbolic
|
|
3271
|
+
sage: gamma(1/2)
|
|
3272
|
+
sqrt(pi)
|
|
3273
|
+
sage: gamma(7/2)
|
|
3274
|
+
15/8*sqrt(pi)
|
|
3275
|
+
sage: gamma(-3/2)
|
|
3276
|
+
4/3*sqrt(pi)
|
|
3277
|
+
sage: gamma(6/1)
|
|
3278
|
+
120
|
|
3279
|
+
sage: gamma(1/3)
|
|
3280
|
+
gamma(1/3)
|
|
3281
|
+
|
|
3282
|
+
This function accepts an optional precision argument::
|
|
3283
|
+
|
|
3284
|
+
sage: (1/3).gamma(prec=100) # needs sage.rings.real_mpfr
|
|
3285
|
+
2.6789385347077476336556929410
|
|
3286
|
+
sage: (1/2).gamma(prec=100) # needs sage.rings.real_mpfr
|
|
3287
|
+
1.7724538509055160272981674833
|
|
3288
|
+
|
|
3289
|
+
TESTS:
|
|
3290
|
+
|
|
3291
|
+
This is not the incomplete gamma function! ::
|
|
3292
|
+
|
|
3293
|
+
sage: (1/2).gamma(5)
|
|
3294
|
+
Traceback (most recent call last):
|
|
3295
|
+
...
|
|
3296
|
+
TypeError: ...gamma() takes exactly 0 positional arguments (1 given)
|
|
3297
|
+
"""
|
|
3298
|
+
if prec:
|
|
3299
|
+
return self.n(prec).gamma()
|
|
3300
|
+
else:
|
|
3301
|
+
if mpz_cmp_ui(mpq_denref(self.value), 1) == 0:
|
|
3302
|
+
return integer.Integer(self).gamma()
|
|
3303
|
+
elif mpz_cmp_ui(mpq_denref(self.value), 2) == 0:
|
|
3304
|
+
numer = self.numer()
|
|
3305
|
+
rat_part = Rational((numer-2).multifactorial(2)) >> ((numer-1)//2)
|
|
3306
|
+
from sage.symbolic.constants import pi
|
|
3307
|
+
from sage.misc.functional import sqrt
|
|
3308
|
+
return sqrt(pi) * rat_part
|
|
3309
|
+
else:
|
|
3310
|
+
from sage.symbolic.ring import SR
|
|
3311
|
+
return SR(self).gamma()
|
|
3312
|
+
|
|
3313
|
+
def floor(self):
|
|
3314
|
+
"""
|
|
3315
|
+
Return the floor of this rational number as an integer.
|
|
3316
|
+
|
|
3317
|
+
OUTPUT: integer
|
|
3318
|
+
|
|
3319
|
+
EXAMPLES::
|
|
3320
|
+
|
|
3321
|
+
sage: n = 5/3; n.floor()
|
|
3322
|
+
1
|
|
3323
|
+
sage: n = -17/19; n.floor()
|
|
3324
|
+
-1
|
|
3325
|
+
sage: n = -7/2; n.floor()
|
|
3326
|
+
-4
|
|
3327
|
+
sage: n = 7/2; n.floor()
|
|
3328
|
+
3
|
|
3329
|
+
sage: n = 10/2; n.floor()
|
|
3330
|
+
5
|
|
3331
|
+
"""
|
|
3332
|
+
cdef integer.Integer n
|
|
3333
|
+
n = integer.Integer()
|
|
3334
|
+
mpz_fdiv_q(n.value, mpq_numref(self.value), mpq_denref(self.value))
|
|
3335
|
+
return n
|
|
3336
|
+
|
|
3337
|
+
def ceil(self):
|
|
3338
|
+
"""
|
|
3339
|
+
Return the ceiling of this rational number.
|
|
3340
|
+
|
|
3341
|
+
OUTPUT: integer
|
|
3342
|
+
|
|
3343
|
+
If this rational number is an integer, this returns this number,
|
|
3344
|
+
otherwise it returns the floor of this number +1.
|
|
3345
|
+
|
|
3346
|
+
EXAMPLES::
|
|
3347
|
+
|
|
3348
|
+
sage: n = 5/3; n.ceil()
|
|
3349
|
+
2
|
|
3350
|
+
sage: n = -17/19; n.ceil()
|
|
3351
|
+
0
|
|
3352
|
+
sage: n = -7/2; n.ceil()
|
|
3353
|
+
-3
|
|
3354
|
+
sage: n = 7/2; n.ceil()
|
|
3355
|
+
4
|
|
3356
|
+
sage: n = 10/2; n.ceil()
|
|
3357
|
+
5
|
|
3358
|
+
"""
|
|
3359
|
+
cdef integer.Integer n
|
|
3360
|
+
n = integer.Integer()
|
|
3361
|
+
mpz_cdiv_q(n.value, mpq_numref(self.value), mpq_denref(self.value))
|
|
3362
|
+
return n
|
|
3363
|
+
|
|
3364
|
+
def trunc(self):
|
|
3365
|
+
"""
|
|
3366
|
+
Round this rational number to the nearest integer toward zero.
|
|
3367
|
+
|
|
3368
|
+
EXAMPLES::
|
|
3369
|
+
|
|
3370
|
+
sage: (5/3).trunc()
|
|
3371
|
+
1
|
|
3372
|
+
sage: (-5/3).trunc()
|
|
3373
|
+
-1
|
|
3374
|
+
sage: QQ(42).trunc()
|
|
3375
|
+
42
|
|
3376
|
+
sage: QQ(-42).trunc()
|
|
3377
|
+
-42
|
|
3378
|
+
"""
|
|
3379
|
+
cdef integer.Integer n
|
|
3380
|
+
n = integer.Integer()
|
|
3381
|
+
mpz_tdiv_q(n.value, mpq_numref(self.value), mpq_denref(self.value))
|
|
3382
|
+
return n
|
|
3383
|
+
|
|
3384
|
+
def round(Rational self, mode="even"):
|
|
3385
|
+
"""
|
|
3386
|
+
Return the nearest integer to ``self``, rounding to even by default.
|
|
3387
|
+
|
|
3388
|
+
INPUT:
|
|
3389
|
+
|
|
3390
|
+
- ``self`` -- a rational number
|
|
3391
|
+
|
|
3392
|
+
- ``mode`` -- a rounding mode for half integers:
|
|
3393
|
+
|
|
3394
|
+
- ``'toward'`` rounds toward zero
|
|
3395
|
+
- ``'away'`` (default) rounds away from zero
|
|
3396
|
+
- ``'up'`` rounds up
|
|
3397
|
+
- ``'down'`` rounds down
|
|
3398
|
+
- ``'even'`` rounds toward the even integer
|
|
3399
|
+
- ``'odd'`` rounds toward the odd integer
|
|
3400
|
+
|
|
3401
|
+
OUTPUT: integer
|
|
3402
|
+
|
|
3403
|
+
EXAMPLES::
|
|
3404
|
+
|
|
3405
|
+
sage: (9/2).round()
|
|
3406
|
+
4
|
|
3407
|
+
sage: n = 4/3; n.round()
|
|
3408
|
+
1
|
|
3409
|
+
sage: n = -17/4; n.round()
|
|
3410
|
+
-4
|
|
3411
|
+
sage: n = -5/2; n.round()
|
|
3412
|
+
-2
|
|
3413
|
+
sage: n.round("away")
|
|
3414
|
+
-3
|
|
3415
|
+
sage: n.round("up")
|
|
3416
|
+
-2
|
|
3417
|
+
sage: n.round("down")
|
|
3418
|
+
-3
|
|
3419
|
+
sage: n.round("even")
|
|
3420
|
+
-2
|
|
3421
|
+
sage: n.round("odd")
|
|
3422
|
+
-3
|
|
3423
|
+
"""
|
|
3424
|
+
if not (mode in ['toward', 'away', 'up', 'down', 'even', 'odd']):
|
|
3425
|
+
raise ValueError("rounding mode must be one of 'toward', 'away', 'up', 'down', 'even', or 'odd'")
|
|
3426
|
+
if self.denominator() == 1:
|
|
3427
|
+
from sage.rings.integer import Integer
|
|
3428
|
+
return Integer(self)
|
|
3429
|
+
if self.denominator() == 2:
|
|
3430
|
+
# round down:
|
|
3431
|
+
if (mode == "down") or \
|
|
3432
|
+
(mode == "toward" and self > 0) or \
|
|
3433
|
+
(mode == "away" and self < 0) or \
|
|
3434
|
+
(mode == "even" and self.numerator() % 4 == 1) or \
|
|
3435
|
+
(mode == "odd" and self.numerator() % 4 == 3):
|
|
3436
|
+
return self.numerator() // self.denominator()
|
|
3437
|
+
else:
|
|
3438
|
+
return self.numerator() // self.denominator() + 1
|
|
3439
|
+
else:
|
|
3440
|
+
q, r = self.numerator().quo_rem(self.denominator())
|
|
3441
|
+
if r < self.denominator() / 2:
|
|
3442
|
+
return q
|
|
3443
|
+
else:
|
|
3444
|
+
return q+1
|
|
3445
|
+
|
|
3446
|
+
__round__ = round
|
|
3447
|
+
|
|
3448
|
+
def real(self):
|
|
3449
|
+
"""
|
|
3450
|
+
Return the real part of ``self``, which is ``self``.
|
|
3451
|
+
|
|
3452
|
+
EXAMPLES::
|
|
3453
|
+
|
|
3454
|
+
sage: (1/2).real()
|
|
3455
|
+
1/2
|
|
3456
|
+
"""
|
|
3457
|
+
return self
|
|
3458
|
+
|
|
3459
|
+
def imag(self):
|
|
3460
|
+
"""
|
|
3461
|
+
Return the imaginary part of ``self``, which is zero.
|
|
3462
|
+
|
|
3463
|
+
EXAMPLES::
|
|
3464
|
+
|
|
3465
|
+
sage: (1/239).imag()
|
|
3466
|
+
0
|
|
3467
|
+
"""
|
|
3468
|
+
return self._parent(0)
|
|
3469
|
+
|
|
3470
|
+
def height(self):
|
|
3471
|
+
"""
|
|
3472
|
+
The max absolute value of the numerator and denominator of ``self``, as
|
|
3473
|
+
an :class:`Integer`.
|
|
3474
|
+
|
|
3475
|
+
OUTPUT: integer
|
|
3476
|
+
|
|
3477
|
+
EXAMPLES::
|
|
3478
|
+
|
|
3479
|
+
sage: a = 2/3
|
|
3480
|
+
sage: a.height()
|
|
3481
|
+
3
|
|
3482
|
+
sage: a = 34/3
|
|
3483
|
+
sage: a.height()
|
|
3484
|
+
34
|
|
3485
|
+
sage: a = -97/4
|
|
3486
|
+
sage: a.height()
|
|
3487
|
+
97
|
|
3488
|
+
|
|
3489
|
+
AUTHORS:
|
|
3490
|
+
|
|
3491
|
+
- Naqi Jaffery (2006-03-05): examples
|
|
3492
|
+
|
|
3493
|
+
.. NOTE::
|
|
3494
|
+
|
|
3495
|
+
For the logarithmic height, use :meth:`global_height()`.
|
|
3496
|
+
"""
|
|
3497
|
+
x = abs(self.numer())
|
|
3498
|
+
if x > self.denom():
|
|
3499
|
+
return x
|
|
3500
|
+
return self.denom()
|
|
3501
|
+
|
|
3502
|
+
def _lcm(self, Rational other):
|
|
3503
|
+
"""
|
|
3504
|
+
Return the least common multiple, in the rational numbers, of ``self``
|
|
3505
|
+
and ``other``. This function returns either 0 or 1 (as a rational
|
|
3506
|
+
number).
|
|
3507
|
+
|
|
3508
|
+
INPUT:
|
|
3509
|
+
|
|
3510
|
+
- ``other`` -- Rational
|
|
3511
|
+
|
|
3512
|
+
OUTPUT: ``Rational`` -- 0 or 1
|
|
3513
|
+
|
|
3514
|
+
EXAMPLES::
|
|
3515
|
+
|
|
3516
|
+
sage: (2/3)._lcm(3/5)
|
|
3517
|
+
1
|
|
3518
|
+
sage: (0/1)._lcm(0/1)
|
|
3519
|
+
0
|
|
3520
|
+
sage: type((2/3)._lcm(3/5))
|
|
3521
|
+
<class 'sage.rings.rational.Rational'>
|
|
3522
|
+
"""
|
|
3523
|
+
if mpz_cmp_si(mpq_numref(self.value), 0) == 0 and \
|
|
3524
|
+
mpz_cmp_si(mpq_numref(other.value), 0) == 0:
|
|
3525
|
+
return Rational(0)
|
|
3526
|
+
return Rational(1)
|
|
3527
|
+
|
|
3528
|
+
def additive_order(self):
|
|
3529
|
+
"""
|
|
3530
|
+
Return the additive order of ``self``.
|
|
3531
|
+
|
|
3532
|
+
OUTPUT: integer or infinity
|
|
3533
|
+
|
|
3534
|
+
EXAMPLES::
|
|
3535
|
+
|
|
3536
|
+
sage: QQ(0).additive_order()
|
|
3537
|
+
1
|
|
3538
|
+
sage: QQ(1).additive_order()
|
|
3539
|
+
+Infinity
|
|
3540
|
+
"""
|
|
3541
|
+
import sage.rings.infinity
|
|
3542
|
+
if self.is_zero():
|
|
3543
|
+
return integer.Integer(1)
|
|
3544
|
+
else:
|
|
3545
|
+
return sage.rings.infinity.infinity
|
|
3546
|
+
|
|
3547
|
+
def multiplicative_order(self):
|
|
3548
|
+
"""
|
|
3549
|
+
Return the multiplicative order of ``self``.
|
|
3550
|
+
|
|
3551
|
+
OUTPUT: integer or ``infinity``
|
|
3552
|
+
|
|
3553
|
+
EXAMPLES::
|
|
3554
|
+
|
|
3555
|
+
sage: QQ(1).multiplicative_order()
|
|
3556
|
+
1
|
|
3557
|
+
sage: QQ('1/-1').multiplicative_order()
|
|
3558
|
+
2
|
|
3559
|
+
sage: QQ(0).multiplicative_order()
|
|
3560
|
+
+Infinity
|
|
3561
|
+
sage: QQ('2/3').multiplicative_order()
|
|
3562
|
+
+Infinity
|
|
3563
|
+
sage: QQ('1/2').multiplicative_order()
|
|
3564
|
+
+Infinity
|
|
3565
|
+
"""
|
|
3566
|
+
import sage.rings.infinity
|
|
3567
|
+
if self.is_one():
|
|
3568
|
+
return integer.Integer(1)
|
|
3569
|
+
elif mpz_cmpabs(mpq_numref(self.value),mpq_denref(self.value)) == 0:
|
|
3570
|
+
# if the numerator and the denominator are equal in absolute value,
|
|
3571
|
+
# then the rational number is -1
|
|
3572
|
+
return integer.Integer(2)
|
|
3573
|
+
else:
|
|
3574
|
+
return sage.rings.infinity.infinity
|
|
3575
|
+
|
|
3576
|
+
def is_one(self):
|
|
3577
|
+
r"""
|
|
3578
|
+
Determine if a rational number is one.
|
|
3579
|
+
|
|
3580
|
+
OUTPUT: boolean
|
|
3581
|
+
|
|
3582
|
+
EXAMPLES::
|
|
3583
|
+
|
|
3584
|
+
sage: QQ(1/2).is_one()
|
|
3585
|
+
False
|
|
3586
|
+
sage: QQ(4/4).is_one()
|
|
3587
|
+
True
|
|
3588
|
+
"""
|
|
3589
|
+
# A rational number is equal to 1 iff its numerator and denominator are equal
|
|
3590
|
+
return mpz_cmp(mpq_numref(self.value),mpq_denref(self.value)) == 0
|
|
3591
|
+
|
|
3592
|
+
def is_integral(self):
|
|
3593
|
+
r"""
|
|
3594
|
+
Determine if a rational number is integral (i.e., is in
|
|
3595
|
+
`\ZZ`).
|
|
3596
|
+
|
|
3597
|
+
OUTPUT: boolean
|
|
3598
|
+
|
|
3599
|
+
EXAMPLES::
|
|
3600
|
+
|
|
3601
|
+
sage: QQ(1/2).is_integral()
|
|
3602
|
+
False
|
|
3603
|
+
sage: QQ(4/4).is_integral()
|
|
3604
|
+
True
|
|
3605
|
+
"""
|
|
3606
|
+
return mpz_cmp_si(mpq_denref(self.value), 1) == 0
|
|
3607
|
+
|
|
3608
|
+
def is_rational(self):
|
|
3609
|
+
r"""
|
|
3610
|
+
Return ``True`` since this is a rational number.
|
|
3611
|
+
|
|
3612
|
+
EXAMPLES::
|
|
3613
|
+
|
|
3614
|
+
sage: (3/4).is_rational()
|
|
3615
|
+
True
|
|
3616
|
+
"""
|
|
3617
|
+
return True
|
|
3618
|
+
|
|
3619
|
+
# Function alias for checking if the number is a integer. Added to solve issue 15500
|
|
3620
|
+
is_integer = is_integral
|
|
3621
|
+
|
|
3622
|
+
def is_S_integral(self, S=[]):
|
|
3623
|
+
r"""
|
|
3624
|
+
Determine if the rational number is ``S``-integral.
|
|
3625
|
+
|
|
3626
|
+
``x`` is ``S``-integral if ``x.valuation(p)>=0`` for all ``p`` not in
|
|
3627
|
+
``S``, i.e., the denominator of ``x`` is divisible only by the primes
|
|
3628
|
+
in ``S``.
|
|
3629
|
+
|
|
3630
|
+
INPUT:
|
|
3631
|
+
|
|
3632
|
+
- ``S`` -- list or tuple of primes
|
|
3633
|
+
|
|
3634
|
+
OUTPUT: boolean
|
|
3635
|
+
|
|
3636
|
+
.. NOTE::
|
|
3637
|
+
|
|
3638
|
+
Primality of the entries in ``S`` is not checked.
|
|
3639
|
+
|
|
3640
|
+
EXAMPLES::
|
|
3641
|
+
|
|
3642
|
+
sage: QQ(1/2).is_S_integral()
|
|
3643
|
+
False
|
|
3644
|
+
sage: QQ(1/2).is_S_integral([2])
|
|
3645
|
+
True
|
|
3646
|
+
sage: [a for a in range(1,11) if QQ(101/a).is_S_integral([2,5])]
|
|
3647
|
+
[1, 2, 4, 5, 8, 10]
|
|
3648
|
+
"""
|
|
3649
|
+
if self.is_integral():
|
|
3650
|
+
return True
|
|
3651
|
+
return self.prime_to_S_part(S).is_integral()
|
|
3652
|
+
|
|
3653
|
+
def is_S_unit(self, S=None):
|
|
3654
|
+
r"""
|
|
3655
|
+
Determine if the rational number is an ``S``-unit.
|
|
3656
|
+
|
|
3657
|
+
``x`` is an ``S``-unit if ``x.valuation(p)==0`` for all ``p`` not in
|
|
3658
|
+
``S``, i.e., the numerator and denominator of ``x`` are divisible only
|
|
3659
|
+
by the primes in `S`.
|
|
3660
|
+
|
|
3661
|
+
INPUT:
|
|
3662
|
+
|
|
3663
|
+
- ``S`` -- list or tuple of primes
|
|
3664
|
+
|
|
3665
|
+
OUTPUT: boolean
|
|
3666
|
+
|
|
3667
|
+
.. NOTE::
|
|
3668
|
+
|
|
3669
|
+
Primality of the entries in ``S`` is not checked.
|
|
3670
|
+
|
|
3671
|
+
EXAMPLES::
|
|
3672
|
+
|
|
3673
|
+
sage: QQ(1/2).is_S_unit()
|
|
3674
|
+
False
|
|
3675
|
+
sage: QQ(1/2).is_S_unit([2])
|
|
3676
|
+
True
|
|
3677
|
+
sage: [a for a in range(1,11) if QQ(10/a).is_S_unit([2,5])]
|
|
3678
|
+
[1, 2, 4, 5, 8, 10]
|
|
3679
|
+
"""
|
|
3680
|
+
a = self.abs()
|
|
3681
|
+
if a == 1:
|
|
3682
|
+
return True
|
|
3683
|
+
if S is None:
|
|
3684
|
+
return False
|
|
3685
|
+
return a.prime_to_S_part(S) == 1
|
|
3686
|
+
|
|
3687
|
+
cdef _lshift(self, long int exp):
|
|
3688
|
+
r"""
|
|
3689
|
+
Return ``self * 2^exp``.
|
|
3690
|
+
"""
|
|
3691
|
+
cdef Rational x
|
|
3692
|
+
x = <Rational> Rational.__new__(Rational)
|
|
3693
|
+
sig_on()
|
|
3694
|
+
if exp < 0:
|
|
3695
|
+
mpq_div_2exp(x.value,self.value,-exp)
|
|
3696
|
+
else:
|
|
3697
|
+
mpq_mul_2exp(x.value,self.value,exp)
|
|
3698
|
+
sig_off()
|
|
3699
|
+
return x
|
|
3700
|
+
|
|
3701
|
+
def __lshift__(x, y):
|
|
3702
|
+
"""
|
|
3703
|
+
Left shift operator ``x << y``.
|
|
3704
|
+
|
|
3705
|
+
INPUT:
|
|
3706
|
+
|
|
3707
|
+
- ``x``, ``y`` -- integer or rational
|
|
3708
|
+
|
|
3709
|
+
OUTPUT: rational
|
|
3710
|
+
|
|
3711
|
+
EXAMPLES::
|
|
3712
|
+
|
|
3713
|
+
sage: (2/3).__lshift__(4/1)
|
|
3714
|
+
32/3
|
|
3715
|
+
sage: (2/3).__lshift__(4/7)
|
|
3716
|
+
Traceback (most recent call last):
|
|
3717
|
+
...
|
|
3718
|
+
ValueError: denominator must be 1
|
|
3719
|
+
sage: (2).__lshift__(4/1)
|
|
3720
|
+
32
|
|
3721
|
+
sage: (2/3).__lshift__(4)
|
|
3722
|
+
32/3
|
|
3723
|
+
sage: (2/3) << (4/1)
|
|
3724
|
+
32/3
|
|
3725
|
+
"""
|
|
3726
|
+
if isinstance(x, Rational):
|
|
3727
|
+
if isinstance(y, (int, integer.Integer)):
|
|
3728
|
+
return (<Rational>x)._lshift(y)
|
|
3729
|
+
if isinstance(y, Rational):
|
|
3730
|
+
if mpz_cmp_si(mpq_denref((<Rational>y).value), 1) != 0:
|
|
3731
|
+
raise ValueError("denominator must be 1")
|
|
3732
|
+
return (<Rational>x)._lshift(y)
|
|
3733
|
+
return coercion_model.bin_op(x, y, operator.lshift)
|
|
3734
|
+
|
|
3735
|
+
cdef _rshift(self, long int exp):
|
|
3736
|
+
r"""
|
|
3737
|
+
Return ``self / 2^exp``.
|
|
3738
|
+
"""
|
|
3739
|
+
cdef Rational x
|
|
3740
|
+
x = <Rational> Rational.__new__(Rational)
|
|
3741
|
+
sig_on()
|
|
3742
|
+
if exp < 0:
|
|
3743
|
+
mpq_mul_2exp(x.value,self.value,-exp)
|
|
3744
|
+
else:
|
|
3745
|
+
mpq_div_2exp(x.value,self.value,exp)
|
|
3746
|
+
sig_off()
|
|
3747
|
+
return x
|
|
3748
|
+
|
|
3749
|
+
def __rshift__(x, y):
|
|
3750
|
+
"""
|
|
3751
|
+
Right shift operator ``x >> y``.
|
|
3752
|
+
|
|
3753
|
+
INPUT:
|
|
3754
|
+
|
|
3755
|
+
- ``x``, ``y`` -- integer or rational
|
|
3756
|
+
|
|
3757
|
+
OUTPUT: rational
|
|
3758
|
+
|
|
3759
|
+
EXAMPLES::
|
|
3760
|
+
|
|
3761
|
+
sage: (2/3).__rshift__(4/1)
|
|
3762
|
+
1/24
|
|
3763
|
+
sage: (2/3).__rshift__(4/7)
|
|
3764
|
+
Traceback (most recent call last):
|
|
3765
|
+
...
|
|
3766
|
+
ValueError: denominator must be 1
|
|
3767
|
+
sage: (2).__rshift__(4/1)
|
|
3768
|
+
0
|
|
3769
|
+
sage: (2/1).__rshift__(4)
|
|
3770
|
+
1/8
|
|
3771
|
+
sage: (2/1) >>(4/1)
|
|
3772
|
+
1/8
|
|
3773
|
+
"""
|
|
3774
|
+
if isinstance(x, Rational):
|
|
3775
|
+
if isinstance(y, (int, integer.Integer)):
|
|
3776
|
+
return (<Rational>x)._rshift(y)
|
|
3777
|
+
if isinstance(y, Rational):
|
|
3778
|
+
if mpz_cmp_si(mpq_denref((<Rational>y).value), 1) != 0:
|
|
3779
|
+
raise ValueError("denominator must be 1")
|
|
3780
|
+
return (<Rational>x)._rshift(y)
|
|
3781
|
+
return coercion_model.bin_op(x, y, operator.rshift)
|
|
3782
|
+
|
|
3783
|
+
def conjugate(self):
|
|
3784
|
+
"""
|
|
3785
|
+
Return the complex conjugate of this rational number, which is
|
|
3786
|
+
the number itself.
|
|
3787
|
+
|
|
3788
|
+
EXAMPLES::
|
|
3789
|
+
|
|
3790
|
+
sage: n = 23/11
|
|
3791
|
+
sage: n.conjugate()
|
|
3792
|
+
23/11
|
|
3793
|
+
"""
|
|
3794
|
+
return self
|
|
3795
|
+
|
|
3796
|
+
##################################################
|
|
3797
|
+
# Support for interfaces
|
|
3798
|
+
##################################################
|
|
3799
|
+
|
|
3800
|
+
def __pari__(self):
|
|
3801
|
+
"""
|
|
3802
|
+
Return the PARI version of this rational number.
|
|
3803
|
+
|
|
3804
|
+
EXAMPLES::
|
|
3805
|
+
|
|
3806
|
+
sage: n = 9390823/17
|
|
3807
|
+
sage: m = n.__pari__(); m # needs sage.libs.pari
|
|
3808
|
+
9390823/17
|
|
3809
|
+
sage: type(m) # needs sage.libs.pari
|
|
3810
|
+
<class 'cypari2.gen.Gen'>
|
|
3811
|
+
sage: m.type() # needs sage.libs.pari
|
|
3812
|
+
't_FRAC'
|
|
3813
|
+
"""
|
|
3814
|
+
global new_gen_from_rational
|
|
3815
|
+
if new_gen_from_rational is None:
|
|
3816
|
+
from sage.libs.pari.convert_sage import new_gen_from_rational
|
|
3817
|
+
return new_gen_from_rational(self)
|
|
3818
|
+
|
|
3819
|
+
def _interface_init_(self, I=None):
|
|
3820
|
+
"""
|
|
3821
|
+
Return representation of this rational suitable for coercing into
|
|
3822
|
+
almost any computer algebra system.
|
|
3823
|
+
|
|
3824
|
+
OUTPUT: string
|
|
3825
|
+
|
|
3826
|
+
EXAMPLES::
|
|
3827
|
+
|
|
3828
|
+
sage: (2/3)._interface_init_()
|
|
3829
|
+
'2/3'
|
|
3830
|
+
sage: kash(3/1).Type() # optional - kash
|
|
3831
|
+
elt-fld^rat
|
|
3832
|
+
sage: magma(3/1).Type() # optional - magma
|
|
3833
|
+
FldRatElt
|
|
3834
|
+
"""
|
|
3835
|
+
return '%s/%s' % (self.numerator(), self.denominator())
|
|
3836
|
+
|
|
3837
|
+
def _sage_input_(self, sib, coerced):
|
|
3838
|
+
r"""
|
|
3839
|
+
Produce an expression which will reproduce this value when evaluated.
|
|
3840
|
+
|
|
3841
|
+
EXAMPLES::
|
|
3842
|
+
|
|
3843
|
+
sage: sage_input(QQ(1), verify=True)
|
|
3844
|
+
# Verified
|
|
3845
|
+
QQ(1)
|
|
3846
|
+
sage: sage_input(-22/7, verify=True)
|
|
3847
|
+
# Verified
|
|
3848
|
+
-22/7
|
|
3849
|
+
sage: sage_input(-22/7, preparse=False)
|
|
3850
|
+
-ZZ(22)/7
|
|
3851
|
+
sage: sage_input(10^-50, verify=True)
|
|
3852
|
+
# Verified
|
|
3853
|
+
1/100000000000000000000000000000000000000000000000000
|
|
3854
|
+
sage: from sage.misc.sage_input import SageInputBuilder
|
|
3855
|
+
sage: (-2/37)._sage_input_(SageInputBuilder(preparse=False), False)
|
|
3856
|
+
{unop:- {binop:/ {call: {atomic:ZZ}({atomic:2})} {atomic:37}}}
|
|
3857
|
+
sage: QQ(5)._sage_input_(SageInputBuilder(preparse=False), True)
|
|
3858
|
+
{atomic:5}
|
|
3859
|
+
"""
|
|
3860
|
+
|
|
3861
|
+
# This code is extensively described in the docstring
|
|
3862
|
+
# for sage_input.py.
|
|
3863
|
+
|
|
3864
|
+
num = self.numerator()
|
|
3865
|
+
neg = (num < 0)
|
|
3866
|
+
if neg: num = -num
|
|
3867
|
+
if self.denominator() == 1:
|
|
3868
|
+
if coerced:
|
|
3869
|
+
v = sib.int(num)
|
|
3870
|
+
else:
|
|
3871
|
+
v = sib.name('QQ')(sib.int(num))
|
|
3872
|
+
else:
|
|
3873
|
+
v = sib(num)/sib.int(self.denominator())
|
|
3874
|
+
if neg: v = -v
|
|
3875
|
+
return v
|
|
3876
|
+
|
|
3877
|
+
|
|
3878
|
+
# The except value is just some random double, it doesn't matter what it is.
|
|
3879
|
+
cdef double mpq_get_d_nearest(mpq_t x) except? -648555075988944.5:
|
|
3880
|
+
"""
|
|
3881
|
+
Convert a ``mpq_t`` to a ``double``, with round-to-nearest-even.
|
|
3882
|
+
This differs from ``mpq_get_d()`` which does round-to-zero.
|
|
3883
|
+
|
|
3884
|
+
TESTS::
|
|
3885
|
+
|
|
3886
|
+
sage: q = QQ(); float(q)
|
|
3887
|
+
0.0
|
|
3888
|
+
sage: q = 2^-10000; float(q)
|
|
3889
|
+
0.0
|
|
3890
|
+
sage: float(-q)
|
|
3891
|
+
-0.0
|
|
3892
|
+
sage: q = 2^10000/1; float(q)
|
|
3893
|
+
inf
|
|
3894
|
+
sage: float(-q)
|
|
3895
|
+
-inf
|
|
3896
|
+
|
|
3897
|
+
::
|
|
3898
|
+
|
|
3899
|
+
sage: q = 2^-1075; float(q)
|
|
3900
|
+
0.0
|
|
3901
|
+
sage: float(-q)
|
|
3902
|
+
-0.0
|
|
3903
|
+
sage: q = 2^52 / 2^1074; float(q) # Smallest normal double
|
|
3904
|
+
2.2250738585072014e-308
|
|
3905
|
+
sage: float(-q)
|
|
3906
|
+
-2.2250738585072014e-308
|
|
3907
|
+
sage: q = (2^52 + 1/2) / 2^1074; float(q)
|
|
3908
|
+
2.2250738585072014e-308
|
|
3909
|
+
sage: float(-q)
|
|
3910
|
+
-2.2250738585072014e-308
|
|
3911
|
+
sage: q = (2^52 + 1) / 2^1074; float(q) # Next normal double
|
|
3912
|
+
2.225073858507202e-308
|
|
3913
|
+
sage: float(-q)
|
|
3914
|
+
-2.225073858507202e-308
|
|
3915
|
+
sage: q = (2^52 - 1) / 2^1074; float(q) # Largest denormal double
|
|
3916
|
+
2.225073858507201e-308
|
|
3917
|
+
sage: float(-q)
|
|
3918
|
+
-2.225073858507201e-308
|
|
3919
|
+
sage: q = 1 / 2^1074; float(q) # Smallest denormal double
|
|
3920
|
+
5e-324
|
|
3921
|
+
sage: float(-q)
|
|
3922
|
+
-5e-324
|
|
3923
|
+
sage: q = (1/2) / 2^1074; float(q)
|
|
3924
|
+
0.0
|
|
3925
|
+
sage: float(-q)
|
|
3926
|
+
-0.0
|
|
3927
|
+
sage: q = (3/2) / 2^1074; float(q)
|
|
3928
|
+
1e-323
|
|
3929
|
+
sage: float(-q)
|
|
3930
|
+
-1e-323
|
|
3931
|
+
sage: q = (2/3) / 2^1074; float(q)
|
|
3932
|
+
5e-324
|
|
3933
|
+
sage: float(-q)
|
|
3934
|
+
-5e-324
|
|
3935
|
+
sage: q = (1/3) / 2^1074; float(q)
|
|
3936
|
+
0.0
|
|
3937
|
+
sage: float(-q)
|
|
3938
|
+
-0.0
|
|
3939
|
+
sage: q = (2^53 - 1) * 2^971/1; float(q) # Largest double
|
|
3940
|
+
1.7976931348623157e+308
|
|
3941
|
+
sage: float(-q)
|
|
3942
|
+
-1.7976931348623157e+308
|
|
3943
|
+
sage: q = (2^53) * 2^971/1; float(q)
|
|
3944
|
+
inf
|
|
3945
|
+
sage: float(-q)
|
|
3946
|
+
-inf
|
|
3947
|
+
sage: q = (2^53 - 1/2) * 2^971/1; float(q)
|
|
3948
|
+
inf
|
|
3949
|
+
sage: float(-q)
|
|
3950
|
+
-inf
|
|
3951
|
+
sage: q = (2^53 - 2/3) * 2^971/1; float(q)
|
|
3952
|
+
1.7976931348623157e+308
|
|
3953
|
+
sage: float(-q)
|
|
3954
|
+
-1.7976931348623157e+308
|
|
3955
|
+
|
|
3956
|
+
AUTHORS:
|
|
3957
|
+
|
|
3958
|
+
- Paul Zimmermann, Jeroen Demeyer (:issue:`14416`)
|
|
3959
|
+
"""
|
|
3960
|
+
cdef mpz_ptr a = mpq_numref(x)
|
|
3961
|
+
cdef mpz_ptr b = mpq_denref(x)
|
|
3962
|
+
cdef int resultsign = mpz_sgn(a)
|
|
3963
|
+
|
|
3964
|
+
if resultsign == 0:
|
|
3965
|
+
return 0.0
|
|
3966
|
+
|
|
3967
|
+
cdef Py_ssize_t sa = mpz_sizeinbase(a, 2)
|
|
3968
|
+
cdef Py_ssize_t sb = mpz_sizeinbase(b, 2)
|
|
3969
|
+
|
|
3970
|
+
# Easy case: both numerator and denominator are exactly
|
|
3971
|
+
# representable as doubles.
|
|
3972
|
+
if sa <= 53 and sb <= 53:
|
|
3973
|
+
return mpz_get_d(a) / mpz_get_d(b)
|
|
3974
|
+
|
|
3975
|
+
# General case
|
|
3976
|
+
|
|
3977
|
+
# We should shift a right by this amount
|
|
3978
|
+
cdef Py_ssize_t shift = sa - sb - 54
|
|
3979
|
+
|
|
3980
|
+
# At this point, we know that q0 = a/b / 2^shift satisfies
|
|
3981
|
+
# 2^53 < q0 < 2^55.
|
|
3982
|
+
# The end result d = q0 * 2^shift (rounded).
|
|
3983
|
+
|
|
3984
|
+
# Check for obvious overflow/underflow before shifting
|
|
3985
|
+
if shift <= -1130: # |d| < 2^-1075
|
|
3986
|
+
if resultsign < 0:
|
|
3987
|
+
return -0.0
|
|
3988
|
+
else:
|
|
3989
|
+
return 0.0
|
|
3990
|
+
elif shift >= 971: # |d| > 2^1024
|
|
3991
|
+
if resultsign < 0:
|
|
3992
|
+
return float('-inf')
|
|
3993
|
+
else:
|
|
3994
|
+
return float('inf')
|
|
3995
|
+
|
|
3996
|
+
sig_on()
|
|
3997
|
+
|
|
3998
|
+
# Compute q = trunc(a / 2^shift) and let remainder_is_zero be True
|
|
3999
|
+
# if and only if no truncation occurred.
|
|
4000
|
+
cdef mpz_t q, r
|
|
4001
|
+
mpz_init(q)
|
|
4002
|
+
mpz_init(r)
|
|
4003
|
+
cdef int remainder_is_zero
|
|
4004
|
+
if shift > 0:
|
|
4005
|
+
remainder_is_zero = mpz_divisible_2exp_p(a, shift)
|
|
4006
|
+
mpz_tdiv_q_2exp(q, a, shift)
|
|
4007
|
+
else:
|
|
4008
|
+
mpz_mul_2exp(q, a, -shift)
|
|
4009
|
+
remainder_is_zero = True
|
|
4010
|
+
|
|
4011
|
+
# Now divide by b to get q = trunc(a/b / 2^shift).
|
|
4012
|
+
# remainder_is_zero is True if and only if no truncation occurred
|
|
4013
|
+
# (in neither division).
|
|
4014
|
+
mpz_tdiv_qr(q, r, q, b)
|
|
4015
|
+
if remainder_is_zero:
|
|
4016
|
+
remainder_is_zero = (mpz_cmp_ui(r, 0) == 0)
|
|
4017
|
+
|
|
4018
|
+
# Convert abs(q) to a 64-bit integer.
|
|
4019
|
+
cdef mp_limb_t* q_limbs = (<mpz_ptr>q)._mp_d
|
|
4020
|
+
cdef uint64_t q64
|
|
4021
|
+
if sizeof(mp_limb_t) >= 8:
|
|
4022
|
+
q64 = q_limbs[0]
|
|
4023
|
+
else:
|
|
4024
|
+
assert sizeof(mp_limb_t) == 4
|
|
4025
|
+
q64 = q_limbs[1]
|
|
4026
|
+
q64 = (q64 << 32) + q_limbs[0]
|
|
4027
|
+
|
|
4028
|
+
mpz_clear(q)
|
|
4029
|
+
mpz_clear(r)
|
|
4030
|
+
sig_off()
|
|
4031
|
+
|
|
4032
|
+
# The quotient q64 has 54 or 55 bits, but we need exactly 54.
|
|
4033
|
+
# Shift it down by 1 one if needed.
|
|
4034
|
+
cdef Py_ssize_t add_shift
|
|
4035
|
+
if q64 < (1ULL << 54):
|
|
4036
|
+
add_shift = 0
|
|
4037
|
+
else:
|
|
4038
|
+
add_shift = 1
|
|
4039
|
+
|
|
4040
|
+
if (shift + add_shift) < -1075:
|
|
4041
|
+
# The result will be denormal, ensure the final shift is -1075
|
|
4042
|
+
# to avoid a double rounding.
|
|
4043
|
+
add_shift = -1075 - shift
|
|
4044
|
+
|
|
4045
|
+
# Add add_shift to shift and let q = trunc(a/b / 2^shift)
|
|
4046
|
+
# for the new shift value.
|
|
4047
|
+
cdef uint64_t mask
|
|
4048
|
+
if add_shift:
|
|
4049
|
+
assert add_shift > 0
|
|
4050
|
+
assert add_shift < 64
|
|
4051
|
+
shift += add_shift
|
|
4052
|
+
# We do an additional division of q by 2^add_shift.
|
|
4053
|
+
if remainder_is_zero:
|
|
4054
|
+
mask = ((1ULL << add_shift)-1)
|
|
4055
|
+
remainder_is_zero = ((q64 & mask) == 0)
|
|
4056
|
+
q64 = q64 >> add_shift
|
|
4057
|
+
|
|
4058
|
+
# Round q64 from 54 to 53 bits of precision.
|
|
4059
|
+
if ((q64 & 1) == 0):
|
|
4060
|
+
# Round towards zero
|
|
4061
|
+
pass
|
|
4062
|
+
else:
|
|
4063
|
+
if not remainder_is_zero:
|
|
4064
|
+
# Remainder is nonzero: round away from zero
|
|
4065
|
+
q64 += 1
|
|
4066
|
+
else:
|
|
4067
|
+
# Halfway case: round to even
|
|
4068
|
+
q64 += (q64 & 2) - 1
|
|
4069
|
+
|
|
4070
|
+
# The conversion of q64 to double is *exact*.
|
|
4071
|
+
# This is because q64 is even and satisfies q64 <= 2^54,
|
|
4072
|
+
# (with 2^53 <= q64 <= 2^54 unless in the denormal case).
|
|
4073
|
+
cdef double d = <double>q64
|
|
4074
|
+
if resultsign < 0:
|
|
4075
|
+
d = -d
|
|
4076
|
+
return ldexp(d, shift)
|
|
4077
|
+
|
|
4078
|
+
|
|
4079
|
+
@cython.binding(True)
|
|
4080
|
+
def make_rational(s):
|
|
4081
|
+
"""
|
|
4082
|
+
Make a rational number from ``s`` (a string in base 32).
|
|
4083
|
+
|
|
4084
|
+
INPUT:
|
|
4085
|
+
|
|
4086
|
+
- ``s`` -- string in base 32
|
|
4087
|
+
|
|
4088
|
+
OUTPUT: rational
|
|
4089
|
+
|
|
4090
|
+
EXAMPLES::
|
|
4091
|
+
|
|
4092
|
+
sage: (-7/15).str(32)
|
|
4093
|
+
'-7/f'
|
|
4094
|
+
sage: sage.rings.rational.make_rational('-7/f')
|
|
4095
|
+
-7/15
|
|
4096
|
+
"""
|
|
4097
|
+
r = Rational()
|
|
4098
|
+
mpq_set_str(r.value, str_to_bytes(s), 32)
|
|
4099
|
+
return r
|
|
4100
|
+
|
|
4101
|
+
|
|
4102
|
+
cdef class Z_to_Q(Morphism):
|
|
4103
|
+
r"""
|
|
4104
|
+
A morphism from `\ZZ` to `\QQ`.
|
|
4105
|
+
"""
|
|
4106
|
+
|
|
4107
|
+
def __init__(self):
|
|
4108
|
+
"""
|
|
4109
|
+
Create morphism from integers to rationals.
|
|
4110
|
+
|
|
4111
|
+
EXAMPLES::
|
|
4112
|
+
|
|
4113
|
+
sage: sage.rings.rational.Z_to_Q()
|
|
4114
|
+
Natural morphism:
|
|
4115
|
+
From: Integer Ring
|
|
4116
|
+
To: Rational Field
|
|
4117
|
+
"""
|
|
4118
|
+
from sage.rings import integer_ring
|
|
4119
|
+
from sage.rings import rational_field
|
|
4120
|
+
import sage.categories.homset
|
|
4121
|
+
Morphism.__init__(self, sage.categories.homset.Hom(integer_ring.ZZ, rational_field.QQ))
|
|
4122
|
+
|
|
4123
|
+
cpdef Element _call_(self, x):
|
|
4124
|
+
"""
|
|
4125
|
+
Return the image of the morphism on ``x``.
|
|
4126
|
+
|
|
4127
|
+
EXAMPLES::
|
|
4128
|
+
|
|
4129
|
+
sage: sage.rings.rational.Z_to_Q()(2) # indirect doctest
|
|
4130
|
+
2
|
|
4131
|
+
"""
|
|
4132
|
+
cdef Rational rat
|
|
4133
|
+
rat = <Rational> Rational.__new__(Rational)
|
|
4134
|
+
mpq_set_z(rat.value, (<integer.Integer>x).value)
|
|
4135
|
+
return rat
|
|
4136
|
+
|
|
4137
|
+
def _repr_type(self):
|
|
4138
|
+
"""
|
|
4139
|
+
Return string that describes the type of morphism.
|
|
4140
|
+
|
|
4141
|
+
EXAMPLES::
|
|
4142
|
+
|
|
4143
|
+
sage: sage.rings.rational.Z_to_Q()._repr_type()
|
|
4144
|
+
'Natural'
|
|
4145
|
+
"""
|
|
4146
|
+
return "Natural"
|
|
4147
|
+
|
|
4148
|
+
def section(self):
|
|
4149
|
+
"""
|
|
4150
|
+
Return a section of this morphism.
|
|
4151
|
+
|
|
4152
|
+
EXAMPLES::
|
|
4153
|
+
|
|
4154
|
+
sage: f = QQ.coerce_map_from(ZZ).section(); f
|
|
4155
|
+
Generic map:
|
|
4156
|
+
From: Rational Field
|
|
4157
|
+
To: Integer Ring
|
|
4158
|
+
|
|
4159
|
+
This map is a morphism in the category of sets with partial
|
|
4160
|
+
maps (see :issue:`15618`)::
|
|
4161
|
+
|
|
4162
|
+
sage: f.parent()
|
|
4163
|
+
Set of Morphisms from Rational Field to Integer Ring
|
|
4164
|
+
in Category of sets with partial maps
|
|
4165
|
+
"""
|
|
4166
|
+
from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
|
|
4167
|
+
return Q_to_Z(self._codomain.Hom(self.domain(), category=SetsWithPartialMaps()))
|
|
4168
|
+
|
|
4169
|
+
def is_surjective(self):
|
|
4170
|
+
r"""
|
|
4171
|
+
Return whether this morphism is surjective.
|
|
4172
|
+
|
|
4173
|
+
EXAMPLES::
|
|
4174
|
+
|
|
4175
|
+
sage: QQ.coerce_map_from(ZZ).is_surjective()
|
|
4176
|
+
False
|
|
4177
|
+
"""
|
|
4178
|
+
return False
|
|
4179
|
+
|
|
4180
|
+
cdef class Q_to_Z(Map):
|
|
4181
|
+
r"""
|
|
4182
|
+
A morphism from `\QQ` to `\ZZ`.
|
|
4183
|
+
|
|
4184
|
+
TESTS::
|
|
4185
|
+
|
|
4186
|
+
sage: type(ZZ.convert_map_from(QQ))
|
|
4187
|
+
<class 'sage.rings.rational.Q_to_Z'>
|
|
4188
|
+
"""
|
|
4189
|
+
cpdef Element _call_(self, x):
|
|
4190
|
+
"""
|
|
4191
|
+
A fast map from the rationals to the integers.
|
|
4192
|
+
|
|
4193
|
+
EXAMPLES::
|
|
4194
|
+
|
|
4195
|
+
sage: f = sage.rings.rational.Q_to_Z(QQ, ZZ)
|
|
4196
|
+
sage: f(1/2) # indirect doctest
|
|
4197
|
+
Traceback (most recent call last):
|
|
4198
|
+
...
|
|
4199
|
+
TypeError: no conversion of this rational to integer
|
|
4200
|
+
sage: f(4/2) # indirect doctest
|
|
4201
|
+
2
|
|
4202
|
+
"""
|
|
4203
|
+
if not mpz_cmp_si(mpq_denref((<Rational>x).value), 1) == 0:
|
|
4204
|
+
raise TypeError("no conversion of this rational to integer")
|
|
4205
|
+
cdef Integer n = Integer.__new__(Integer)
|
|
4206
|
+
n.set_from_mpz(mpq_numref((<Rational>x).value))
|
|
4207
|
+
return n
|
|
4208
|
+
|
|
4209
|
+
def section(self):
|
|
4210
|
+
"""
|
|
4211
|
+
Return a section of this morphism.
|
|
4212
|
+
|
|
4213
|
+
EXAMPLES::
|
|
4214
|
+
|
|
4215
|
+
sage: sage.rings.rational.Q_to_Z(QQ, ZZ).section()
|
|
4216
|
+
Natural morphism:
|
|
4217
|
+
From: Integer Ring
|
|
4218
|
+
To: Rational Field
|
|
4219
|
+
"""
|
|
4220
|
+
return Z_to_Q()
|
|
4221
|
+
|
|
4222
|
+
|
|
4223
|
+
cdef class int_to_Q(Morphism):
|
|
4224
|
+
r"""
|
|
4225
|
+
A morphism from Python 3 ``int`` to `\QQ`.
|
|
4226
|
+
"""
|
|
4227
|
+
def __init__(self):
|
|
4228
|
+
"""
|
|
4229
|
+
Initialize ``self``.
|
|
4230
|
+
|
|
4231
|
+
EXAMPLES::
|
|
4232
|
+
|
|
4233
|
+
sage: sage.rings.rational.int_to_Q()
|
|
4234
|
+
Native morphism:
|
|
4235
|
+
From: Set of Python objects of class 'int'
|
|
4236
|
+
To: Rational Field
|
|
4237
|
+
"""
|
|
4238
|
+
from sage.rings import rational_field
|
|
4239
|
+
import sage.categories.homset
|
|
4240
|
+
from sage.sets.pythonclass import Set_PythonType
|
|
4241
|
+
Morphism.__init__(self, sage.categories.homset.Hom(
|
|
4242
|
+
Set_PythonType(int), rational_field.QQ))
|
|
4243
|
+
|
|
4244
|
+
cpdef Element _call_(self, a):
|
|
4245
|
+
"""
|
|
4246
|
+
Return the image of the morphism on ``a``.
|
|
4247
|
+
|
|
4248
|
+
EXAMPLES::
|
|
4249
|
+
|
|
4250
|
+
sage: f = sage.rings.rational.int_to_Q()
|
|
4251
|
+
sage: f(4^100)
|
|
4252
|
+
1606938044258990275541962092341162602522202993782792835301376
|
|
4253
|
+
"""
|
|
4254
|
+
|
|
4255
|
+
cdef Rational rat
|
|
4256
|
+
cdef long a_long
|
|
4257
|
+
cdef int err = 0
|
|
4258
|
+
|
|
4259
|
+
rat = <Rational> Rational.__new__(Rational)
|
|
4260
|
+
|
|
4261
|
+
integer_check_long_py(a, &a_long, &err)
|
|
4262
|
+
|
|
4263
|
+
if not err:
|
|
4264
|
+
mpq_set_si(rat.value, a_long, 1)
|
|
4265
|
+
else:
|
|
4266
|
+
mpz_set_pylong(mpq_numref(rat.value), a)
|
|
4267
|
+
|
|
4268
|
+
return rat
|
|
4269
|
+
|
|
4270
|
+
def _repr_type(self):
|
|
4271
|
+
"""
|
|
4272
|
+
Return string that describes the type of morphism.
|
|
4273
|
+
|
|
4274
|
+
EXAMPLES::
|
|
4275
|
+
|
|
4276
|
+
sage: sage.rings.rational.int_to_Q()._repr_type()
|
|
4277
|
+
'Native'
|
|
4278
|
+
"""
|
|
4279
|
+
return "Native"
|
|
4280
|
+
|
|
4281
|
+
|
|
4282
|
+
# Support Python's numbers abstract base class
|
|
4283
|
+
import numbers
|
|
4284
|
+
numbers.Rational.register(Rational)
|