passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_categories-10.6.32.dist-info/METADATA +156 -0
- passagemath_categories-10.6.32.dist-info/RECORD +719 -0
- passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
- passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_categories.py +28 -0
- sage/arith/all.py +38 -0
- sage/arith/constants.pxd +27 -0
- sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/functions.pxd +4 -0
- sage/arith/functions.pyx +221 -0
- sage/arith/misc.py +6552 -0
- sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/multi_modular.pxd +39 -0
- sage/arith/multi_modular.pyx +994 -0
- sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/rational_reconstruction.pxd +4 -0
- sage/arith/rational_reconstruction.pyx +115 -0
- sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/srange.pyx +571 -0
- sage/calculus/all__sagemath_categories.py +2 -0
- sage/calculus/functional.py +481 -0
- sage/calculus/functions.py +151 -0
- sage/categories/additive_groups.py +73 -0
- sage/categories/additive_magmas.py +1044 -0
- sage/categories/additive_monoids.py +114 -0
- sage/categories/additive_semigroups.py +184 -0
- sage/categories/affine_weyl_groups.py +238 -0
- sage/categories/algebra_ideals.py +95 -0
- sage/categories/algebra_modules.py +96 -0
- sage/categories/algebras.py +349 -0
- sage/categories/algebras_with_basis.py +377 -0
- sage/categories/all.py +160 -0
- sage/categories/aperiodic_semigroups.py +29 -0
- sage/categories/associative_algebras.py +47 -0
- sage/categories/bialgebras.py +101 -0
- sage/categories/bialgebras_with_basis.py +414 -0
- sage/categories/bimodules.py +206 -0
- sage/categories/chain_complexes.py +268 -0
- sage/categories/classical_crystals.py +480 -0
- sage/categories/coalgebras.py +405 -0
- sage/categories/coalgebras_with_basis.py +232 -0
- sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/coercion_methods.pyx +52 -0
- sage/categories/commutative_additive_groups.py +104 -0
- sage/categories/commutative_additive_monoids.py +45 -0
- sage/categories/commutative_additive_semigroups.py +48 -0
- sage/categories/commutative_algebra_ideals.py +87 -0
- sage/categories/commutative_algebras.py +94 -0
- sage/categories/commutative_ring_ideals.py +58 -0
- sage/categories/commutative_rings.py +736 -0
- sage/categories/complete_discrete_valuation.py +293 -0
- sage/categories/complex_reflection_groups.py +145 -0
- sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
- sage/categories/coxeter_group_algebras.py +186 -0
- sage/categories/coxeter_groups.py +3402 -0
- sage/categories/crystals.py +2628 -0
- sage/categories/cw_complexes.py +216 -0
- sage/categories/dedekind_domains.py +137 -0
- sage/categories/discrete_valuation.py +325 -0
- sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
- sage/categories/division_rings.py +114 -0
- sage/categories/domains.py +95 -0
- sage/categories/drinfeld_modules.py +789 -0
- sage/categories/dual.py +42 -0
- sage/categories/enumerated_sets.py +1146 -0
- sage/categories/euclidean_domains.py +271 -0
- sage/categories/examples/algebras_with_basis.py +102 -0
- sage/categories/examples/all.py +1 -0
- sage/categories/examples/commutative_additive_monoids.py +130 -0
- sage/categories/examples/commutative_additive_semigroups.py +199 -0
- sage/categories/examples/coxeter_groups.py +8 -0
- sage/categories/examples/crystals.py +236 -0
- sage/categories/examples/cw_complexes.py +163 -0
- sage/categories/examples/facade_sets.py +187 -0
- sage/categories/examples/filtered_algebras_with_basis.py +204 -0
- sage/categories/examples/filtered_modules_with_basis.py +154 -0
- sage/categories/examples/finite_coxeter_groups.py +252 -0
- sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
- sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
- sage/categories/examples/finite_enumerated_sets.py +208 -0
- sage/categories/examples/finite_monoids.py +150 -0
- sage/categories/examples/finite_semigroups.py +190 -0
- sage/categories/examples/finite_weyl_groups.py +191 -0
- sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
- sage/categories/examples/graded_modules_with_basis.py +168 -0
- sage/categories/examples/graphs.py +122 -0
- sage/categories/examples/hopf_algebras_with_basis.py +145 -0
- sage/categories/examples/infinite_enumerated_sets.py +190 -0
- sage/categories/examples/lie_algebras.py +352 -0
- sage/categories/examples/lie_algebras_with_basis.py +196 -0
- sage/categories/examples/magmas.py +162 -0
- sage/categories/examples/manifolds.py +94 -0
- sage/categories/examples/monoids.py +144 -0
- sage/categories/examples/posets.py +178 -0
- sage/categories/examples/semigroups.py +580 -0
- sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/examples/semigroups_cython.pyx +221 -0
- sage/categories/examples/semirings.py +249 -0
- sage/categories/examples/sets_cat.py +706 -0
- sage/categories/examples/sets_with_grading.py +101 -0
- sage/categories/examples/with_realizations.py +542 -0
- sage/categories/fields.py +991 -0
- sage/categories/filtered_algebras.py +63 -0
- sage/categories/filtered_algebras_with_basis.py +548 -0
- sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
- sage/categories/filtered_modules.py +210 -0
- sage/categories/filtered_modules_with_basis.py +1209 -0
- sage/categories/finite_complex_reflection_groups.py +1506 -0
- sage/categories/finite_coxeter_groups.py +1138 -0
- sage/categories/finite_crystals.py +103 -0
- sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
- sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
- sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
- sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
- sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
- sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
- sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
- sage/categories/finite_enumerated_sets.py +769 -0
- sage/categories/finite_fields.py +252 -0
- sage/categories/finite_groups.py +256 -0
- sage/categories/finite_lattice_posets.py +242 -0
- sage/categories/finite_monoids.py +316 -0
- sage/categories/finite_permutation_groups.py +339 -0
- sage/categories/finite_posets.py +1994 -0
- sage/categories/finite_semigroups.py +136 -0
- sage/categories/finite_sets.py +93 -0
- sage/categories/finite_weyl_groups.py +39 -0
- sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
- sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
- sage/categories/finitely_generated_magmas.py +57 -0
- sage/categories/finitely_generated_semigroups.py +214 -0
- sage/categories/function_fields.py +76 -0
- sage/categories/g_sets.py +77 -0
- sage/categories/gcd_domains.py +65 -0
- sage/categories/generalized_coxeter_groups.py +94 -0
- sage/categories/graded_algebras.py +85 -0
- sage/categories/graded_algebras_with_basis.py +258 -0
- sage/categories/graded_bialgebras.py +32 -0
- sage/categories/graded_bialgebras_with_basis.py +32 -0
- sage/categories/graded_coalgebras.py +65 -0
- sage/categories/graded_coalgebras_with_basis.py +51 -0
- sage/categories/graded_hopf_algebras.py +41 -0
- sage/categories/graded_hopf_algebras_with_basis.py +169 -0
- sage/categories/graded_lie_algebras.py +91 -0
- sage/categories/graded_lie_algebras_with_basis.py +44 -0
- sage/categories/graded_lie_conformal_algebras.py +74 -0
- sage/categories/graded_modules.py +133 -0
- sage/categories/graded_modules_with_basis.py +329 -0
- sage/categories/graphs.py +138 -0
- sage/categories/group_algebras.py +430 -0
- sage/categories/groupoid.py +94 -0
- sage/categories/groups.py +667 -0
- sage/categories/h_trivial_semigroups.py +64 -0
- sage/categories/hecke_modules.py +185 -0
- sage/categories/highest_weight_crystals.py +980 -0
- sage/categories/hopf_algebras.py +219 -0
- sage/categories/hopf_algebras_with_basis.py +309 -0
- sage/categories/infinite_enumerated_sets.py +115 -0
- sage/categories/integral_domains.py +203 -0
- sage/categories/j_trivial_semigroups.py +29 -0
- sage/categories/kac_moody_algebras.py +82 -0
- sage/categories/kahler_algebras.py +203 -0
- sage/categories/l_trivial_semigroups.py +63 -0
- sage/categories/lambda_bracket_algebras.py +280 -0
- sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
- sage/categories/lattice_posets.py +89 -0
- sage/categories/left_modules.py +49 -0
- sage/categories/lie_algebras.py +1070 -0
- sage/categories/lie_algebras_with_basis.py +261 -0
- sage/categories/lie_conformal_algebras.py +350 -0
- sage/categories/lie_conformal_algebras_with_basis.py +147 -0
- sage/categories/lie_groups.py +73 -0
- sage/categories/loop_crystals.py +1290 -0
- sage/categories/magmas.py +1189 -0
- sage/categories/magmas_and_additive_magmas.py +149 -0
- sage/categories/magmatic_algebras.py +365 -0
- sage/categories/manifolds.py +352 -0
- sage/categories/matrix_algebras.py +40 -0
- sage/categories/metric_spaces.py +387 -0
- sage/categories/modular_abelian_varieties.py +78 -0
- sage/categories/modules.py +989 -0
- sage/categories/modules_with_basis.py +2794 -0
- sage/categories/monoid_algebras.py +38 -0
- sage/categories/monoids.py +739 -0
- sage/categories/noetherian_rings.py +87 -0
- sage/categories/number_fields.py +242 -0
- sage/categories/ore_modules.py +189 -0
- sage/categories/partially_ordered_monoids.py +49 -0
- sage/categories/permutation_groups.py +63 -0
- sage/categories/pointed_sets.py +42 -0
- sage/categories/polyhedra.py +74 -0
- sage/categories/poor_man_map.py +270 -0
- sage/categories/posets.py +722 -0
- sage/categories/principal_ideal_domains.py +270 -0
- sage/categories/quantum_group_representations.py +543 -0
- sage/categories/quotient_fields.py +728 -0
- sage/categories/r_trivial_semigroups.py +45 -0
- sage/categories/regular_crystals.py +898 -0
- sage/categories/regular_supercrystals.py +170 -0
- sage/categories/right_modules.py +49 -0
- sage/categories/ring_ideals.py +74 -0
- sage/categories/rings.py +1904 -0
- sage/categories/rngs.py +175 -0
- sage/categories/schemes.py +393 -0
- sage/categories/semigroups.py +1060 -0
- sage/categories/semirings.py +71 -0
- sage/categories/semisimple_algebras.py +114 -0
- sage/categories/sets_with_grading.py +235 -0
- sage/categories/shephard_groups.py +43 -0
- sage/categories/signed_tensor.py +120 -0
- sage/categories/simplicial_complexes.py +134 -0
- sage/categories/simplicial_sets.py +1206 -0
- sage/categories/super_algebras.py +149 -0
- sage/categories/super_algebras_with_basis.py +144 -0
- sage/categories/super_hopf_algebras_with_basis.py +126 -0
- sage/categories/super_lie_conformal_algebras.py +193 -0
- sage/categories/super_modules.py +229 -0
- sage/categories/super_modules_with_basis.py +193 -0
- sage/categories/supercommutative_algebras.py +99 -0
- sage/categories/supercrystals.py +406 -0
- sage/categories/tensor.py +110 -0
- sage/categories/topological_spaces.py +170 -0
- sage/categories/triangular_kac_moody_algebras.py +439 -0
- sage/categories/tutorial.py +58 -0
- sage/categories/unique_factorization_domains.py +318 -0
- sage/categories/unital_algebras.py +426 -0
- sage/categories/vector_bundles.py +159 -0
- sage/categories/vector_spaces.py +357 -0
- sage/categories/weyl_groups.py +853 -0
- sage/combinat/all__sagemath_categories.py +34 -0
- sage/combinat/backtrack.py +180 -0
- sage/combinat/combinat.py +2269 -0
- sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/combinat_cython.pxd +6 -0
- sage/combinat/combinat_cython.pyx +390 -0
- sage/combinat/combination.py +796 -0
- sage/combinat/combinatorial_map.py +416 -0
- sage/combinat/composition.py +2192 -0
- sage/combinat/dlx.py +510 -0
- sage/combinat/integer_lists/__init__.py +7 -0
- sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/base.pxd +16 -0
- sage/combinat/integer_lists/base.pyx +713 -0
- sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/invlex.pxd +4 -0
- sage/combinat/integer_lists/invlex.pyx +1650 -0
- sage/combinat/integer_lists/lists.py +328 -0
- sage/combinat/integer_lists/nn.py +48 -0
- sage/combinat/integer_vector.py +1818 -0
- sage/combinat/integer_vector_weighted.py +413 -0
- sage/combinat/matrices/all__sagemath_categories.py +5 -0
- sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/matrices/dancing_links.pyx +1159 -0
- sage/combinat/matrices/dancing_links_c.h +380 -0
- sage/combinat/matrices/dlxcpp.py +136 -0
- sage/combinat/partition.py +10070 -0
- sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/partitions.pyx +743 -0
- sage/combinat/permutation.py +10168 -0
- sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/permutation_cython.pxd +11 -0
- sage/combinat/permutation_cython.pyx +407 -0
- sage/combinat/q_analogues.py +1090 -0
- sage/combinat/ranker.py +268 -0
- sage/combinat/subset.py +1561 -0
- sage/combinat/subsets_hereditary.py +202 -0
- sage/combinat/subsets_pairwise.py +184 -0
- sage/combinat/tools.py +63 -0
- sage/combinat/tuple.py +348 -0
- sage/data_structures/all.py +2 -0
- sage/data_structures/all__sagemath_categories.py +2 -0
- sage/data_structures/binary_matrix.pxd +138 -0
- sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/binary_search.pxd +3 -0
- sage/data_structures/binary_search.pyx +66 -0
- sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset.pxd +40 -0
- sage/data_structures/bitset.pyx +2385 -0
- sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset_base.pxd +926 -0
- sage/data_structures/bitset_base.pyx +117 -0
- sage/data_structures/bitset_intrinsics.h +487 -0
- sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/blas_dict.pxd +12 -0
- sage/data_structures/blas_dict.pyx +469 -0
- sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/list_of_pairs.pxd +16 -0
- sage/data_structures/list_of_pairs.pyx +122 -0
- sage/data_structures/mutable_poset.py +3312 -0
- sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/pairing_heap.h +346 -0
- sage/data_structures/pairing_heap.pxd +88 -0
- sage/data_structures/pairing_heap.pyx +1464 -0
- sage/data_structures/sparse_bitset.pxd +62 -0
- sage/data_structures/stream.py +5070 -0
- sage/databases/all__sagemath_categories.py +7 -0
- sage/databases/sql_db.py +2236 -0
- sage/ext/all__sagemath_categories.py +3 -0
- sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_callable.pxd +4 -0
- sage/ext/fast_callable.pyx +2746 -0
- sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_eval.pxd +1 -0
- sage/ext/fast_eval.pyx +102 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_categories.py +2 -0
- sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_el.pxd +18 -0
- sage/ext/interpreters/wrapper_el.pyx +148 -0
- sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_py.pxd +17 -0
- sage/ext/interpreters/wrapper_py.pyx +133 -0
- sage/functions/airy.py +937 -0
- sage/functions/all.py +97 -0
- sage/functions/bessel.py +2102 -0
- sage/functions/error.py +784 -0
- sage/functions/exp_integral.py +1529 -0
- sage/functions/gamma.py +1087 -0
- sage/functions/generalized.py +672 -0
- sage/functions/hyperbolic.py +747 -0
- sage/functions/hypergeometric.py +1156 -0
- sage/functions/jacobi.py +1705 -0
- sage/functions/log.py +1402 -0
- sage/functions/min_max.py +338 -0
- sage/functions/orthogonal_polys.py +3106 -0
- sage/functions/other.py +2303 -0
- sage/functions/piecewise.py +1505 -0
- sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/functions/prime_pi.pyx +262 -0
- sage/functions/special.py +1212 -0
- sage/functions/spike_function.py +278 -0
- sage/functions/transcendental.py +690 -0
- sage/functions/trig.py +1062 -0
- sage/functions/wigner.py +726 -0
- sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/geometry/abc.pyx +82 -0
- sage/geometry/all__sagemath_categories.py +1 -0
- sage/groups/all__sagemath_categories.py +11 -0
- sage/groups/generic.py +1733 -0
- sage/groups/groups_catalog.py +113 -0
- sage/groups/perm_gps/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/all.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
- sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
- sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
- sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
- sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
- sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
- sage/interfaces/abc.py +140 -0
- sage/interfaces/all.py +58 -0
- sage/interfaces/all__sagemath_categories.py +1 -0
- sage/interfaces/expect.py +1643 -0
- sage/interfaces/interface.py +1682 -0
- sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/process.pxd +5 -0
- sage/interfaces/process.pyx +288 -0
- sage/interfaces/quit.py +167 -0
- sage/interfaces/sage0.py +604 -0
- sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/sagespawn.pyx +308 -0
- sage/interfaces/tab_completion.py +101 -0
- sage/misc/all__sagemath_categories.py +78 -0
- sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/allocator.pxd +6 -0
- sage/misc/allocator.pyx +47 -0
- sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/binary_tree.pxd +29 -0
- sage/misc/binary_tree.pyx +537 -0
- sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/callable_dict.pyx +89 -0
- sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/citation.pyx +159 -0
- sage/misc/converting_dict.py +293 -0
- sage/misc/defaults.py +129 -0
- sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/derivative.pyx +223 -0
- sage/misc/functional.py +2005 -0
- sage/misc/html.py +589 -0
- sage/misc/latex.py +2673 -0
- sage/misc/latex_macros.py +236 -0
- sage/misc/latex_standalone.py +1833 -0
- sage/misc/map_threaded.py +38 -0
- sage/misc/mathml.py +76 -0
- sage/misc/method_decorator.py +88 -0
- sage/misc/mrange.py +755 -0
- sage/misc/multireplace.py +41 -0
- sage/misc/object_multiplexer.py +92 -0
- sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/parser.pyx +1107 -0
- sage/misc/random_testing.py +264 -0
- sage/misc/rest_index_of_methods.py +377 -0
- sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/search.pxd +2 -0
- sage/misc/search.pyx +68 -0
- sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/stopgap.pyx +95 -0
- sage/misc/table.py +853 -0
- sage/monoids/all__sagemath_categories.py +1 -0
- sage/monoids/indexed_free_monoid.py +1071 -0
- sage/monoids/monoid.py +82 -0
- sage/numerical/all__sagemath_categories.py +1 -0
- sage/numerical/backends/all__sagemath_categories.py +1 -0
- sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_backend.pxd +61 -0
- sage/numerical/backends/generic_backend.pyx +1893 -0
- sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_sdp_backend.pxd +38 -0
- sage/numerical/backends/generic_sdp_backend.pyx +755 -0
- sage/parallel/all.py +6 -0
- sage/parallel/decorate.py +575 -0
- sage/parallel/map_reduce.py +1997 -0
- sage/parallel/multiprocessing_sage.py +76 -0
- sage/parallel/ncpus.py +35 -0
- sage/parallel/parallelism.py +364 -0
- sage/parallel/reference.py +47 -0
- sage/parallel/use_fork.py +333 -0
- sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/abc.pxd +31 -0
- sage/rings/abc.pyx +526 -0
- sage/rings/algebraic_closure_finite_field.py +1154 -0
- sage/rings/all__sagemath_categories.py +91 -0
- sage/rings/big_oh.py +227 -0
- sage/rings/continued_fraction.py +2754 -0
- sage/rings/continued_fraction_gosper.py +220 -0
- sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/factorint.pyx +295 -0
- sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fast_arith.pxd +21 -0
- sage/rings/fast_arith.pyx +535 -0
- sage/rings/finite_rings/all__sagemath_categories.py +9 -0
- sage/rings/finite_rings/conway_polynomials.py +542 -0
- sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_base.pxd +12 -0
- sage/rings/finite_rings/element_base.pyx +1176 -0
- sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/finite_field_base.pxd +7 -0
- sage/rings/finite_rings/finite_field_base.pyx +2171 -0
- sage/rings/finite_rings/finite_field_constructor.py +827 -0
- sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
- sage/rings/finite_rings/galois_group.py +154 -0
- sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field.pxd +23 -0
- sage/rings/finite_rings/hom_finite_field.pyx +856 -0
- sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
- sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
- sage/rings/finite_rings/homset.py +357 -0
- sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/integer_mod.pxd +56 -0
- sage/rings/finite_rings/integer_mod.pyx +4586 -0
- sage/rings/finite_rings/integer_mod_limits.h +11 -0
- sage/rings/finite_rings/integer_mod_ring.py +2044 -0
- sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field.pxd +30 -0
- sage/rings/finite_rings/residue_field.pyx +1811 -0
- sage/rings/finite_rings/stdint.pxd +19 -0
- sage/rings/fraction_field.py +1452 -0
- sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fraction_field_element.pyx +1357 -0
- sage/rings/function_field/all.py +7 -0
- sage/rings/function_field/all__sagemath_categories.py +2 -0
- sage/rings/function_field/constructor.py +218 -0
- sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element.pxd +11 -0
- sage/rings/function_field/element.pyx +1008 -0
- sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element_rational.pyx +513 -0
- sage/rings/function_field/extensions.py +230 -0
- sage/rings/function_field/function_field.py +1468 -0
- sage/rings/function_field/function_field_rational.py +1005 -0
- sage/rings/function_field/ideal.py +1155 -0
- sage/rings/function_field/ideal_rational.py +629 -0
- sage/rings/function_field/jacobian_base.py +826 -0
- sage/rings/function_field/jacobian_hess.py +1053 -0
- sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
- sage/rings/function_field/maps.py +1039 -0
- sage/rings/function_field/order.py +281 -0
- sage/rings/function_field/order_basis.py +586 -0
- sage/rings/function_field/order_rational.py +576 -0
- sage/rings/function_field/place.py +426 -0
- sage/rings/function_field/place_rational.py +181 -0
- sage/rings/generic.py +320 -0
- sage/rings/homset.py +332 -0
- sage/rings/ideal.py +1885 -0
- sage/rings/ideal_monoid.py +215 -0
- sage/rings/infinity.py +1890 -0
- sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer.pxd +45 -0
- sage/rings/integer.pyx +7874 -0
- sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer_ring.pxd +8 -0
- sage/rings/integer_ring.pyx +1693 -0
- sage/rings/laurent_series_ring.py +931 -0
- sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/laurent_series_ring_element.pxd +11 -0
- sage/rings/laurent_series_ring_element.pyx +1927 -0
- sage/rings/lazy_series.py +7815 -0
- sage/rings/lazy_series_ring.py +4356 -0
- sage/rings/localization.py +1043 -0
- sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/morphism.pxd +39 -0
- sage/rings/morphism.pyx +3299 -0
- sage/rings/multi_power_series_ring.py +1145 -0
- sage/rings/multi_power_series_ring_element.py +2184 -0
- sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/noncommutative_ideals.pyx +423 -0
- sage/rings/number_field/all__sagemath_categories.py +1 -0
- sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_base.pxd +8 -0
- sage/rings/number_field/number_field_base.pyx +507 -0
- sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_element_base.pxd +6 -0
- sage/rings/number_field/number_field_element_base.pyx +36 -0
- sage/rings/number_field/number_field_ideal.py +3550 -0
- sage/rings/padics/all__sagemath_categories.py +4 -0
- sage/rings/padics/local_generic.py +1670 -0
- sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/local_generic_element.pxd +5 -0
- sage/rings/padics/local_generic_element.pyx +1017 -0
- sage/rings/padics/misc.py +256 -0
- sage/rings/padics/padic_generic.py +1911 -0
- sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer.pxd +38 -0
- sage/rings/padics/pow_computer.pyx +671 -0
- sage/rings/padics/precision_error.py +24 -0
- sage/rings/polynomial/all__sagemath_categories.py +25 -0
- sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/commutative_polynomial.pxd +6 -0
- sage/rings/polynomial/commutative_polynomial.pyx +24 -0
- sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/cyclotomic.pyx +404 -0
- sage/rings/polynomial/flatten.py +711 -0
- sage/rings/polynomial/ideal.py +102 -0
- sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
- sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
- sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial.pxd +18 -0
- sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
- sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
- sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
- sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
- sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial.pxd +12 -0
- sage/rings/polynomial/multi_polynomial.pyx +3082 -0
- sage/rings/polynomial/multi_polynomial_element.py +2570 -0
- sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
- sage/rings/polynomial/multi_polynomial_ring.py +947 -0
- sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
- sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
- sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polydict.pxd +45 -0
- sage/rings/polynomial/polydict.pyx +2701 -0
- sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_compiled.pxd +59 -0
- sage/rings/polynomial/polynomial_compiled.pyx +509 -0
- sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_element.pxd +64 -0
- sage/rings/polynomial/polynomial_element.pyx +13255 -0
- sage/rings/polynomial/polynomial_element_generic.py +1637 -0
- sage/rings/polynomial/polynomial_fateman.py +97 -0
- sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
- sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
- sage/rings/polynomial/polynomial_ring.py +3784 -0
- sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
- sage/rings/polynomial/polynomial_singular_interface.py +549 -0
- sage/rings/polynomial/symmetric_ideal.py +989 -0
- sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/symmetric_reduction.pxd +8 -0
- sage/rings/polynomial/symmetric_reduction.pyx +669 -0
- sage/rings/polynomial/term_order.py +2279 -0
- sage/rings/polynomial/toy_buchberger.py +449 -0
- sage/rings/polynomial/toy_d_basis.py +387 -0
- sage/rings/polynomial/toy_variety.py +362 -0
- sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_mpoly.pxd +9 -0
- sage/rings/power_series_mpoly.pyx +161 -0
- sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_poly.pxd +10 -0
- sage/rings/power_series_poly.pyx +1317 -0
- sage/rings/power_series_ring.py +1441 -0
- sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_ring_element.pxd +12 -0
- sage/rings/power_series_ring_element.pyx +3028 -0
- sage/rings/puiseux_series_ring.py +487 -0
- sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/puiseux_series_ring_element.pxd +7 -0
- sage/rings/puiseux_series_ring_element.pyx +1055 -0
- sage/rings/qqbar_decorators.py +167 -0
- sage/rings/quotient_ring.py +1598 -0
- sage/rings/quotient_ring_element.py +979 -0
- sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/rational.pxd +20 -0
- sage/rings/rational.pyx +4284 -0
- sage/rings/rational_field.py +1730 -0
- sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_double.pxd +16 -0
- sage/rings/real_double.pyx +2218 -0
- sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_lazy.pxd +30 -0
- sage/rings/real_lazy.pyx +1773 -0
- sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/ring.pxd +30 -0
- sage/rings/ring.pyx +850 -0
- sage/rings/semirings/all.py +3 -0
- sage/rings/semirings/non_negative_integer_semiring.py +107 -0
- sage/rings/semirings/tropical_mpolynomial.py +972 -0
- sage/rings/semirings/tropical_polynomial.py +997 -0
- sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/semirings/tropical_semiring.pyx +676 -0
- sage/rings/semirings/tropical_variety.py +1701 -0
- sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/sum_of_squares.pxd +3 -0
- sage/rings/sum_of_squares.pyx +336 -0
- sage/rings/tests.py +504 -0
- sage/schemes/affine/affine_homset.py +508 -0
- sage/schemes/affine/affine_morphism.py +1574 -0
- sage/schemes/affine/affine_point.py +460 -0
- sage/schemes/affine/affine_rational_point.py +308 -0
- sage/schemes/affine/affine_space.py +1264 -0
- sage/schemes/affine/affine_subscheme.py +592 -0
- sage/schemes/affine/all.py +25 -0
- sage/schemes/all__sagemath_categories.py +5 -0
- sage/schemes/generic/algebraic_scheme.py +2092 -0
- sage/schemes/generic/all.py +5 -0
- sage/schemes/generic/ambient_space.py +400 -0
- sage/schemes/generic/divisor.py +465 -0
- sage/schemes/generic/divisor_group.py +313 -0
- sage/schemes/generic/glue.py +84 -0
- sage/schemes/generic/homset.py +820 -0
- sage/schemes/generic/hypersurface.py +234 -0
- sage/schemes/generic/morphism.py +2107 -0
- sage/schemes/generic/point.py +237 -0
- sage/schemes/generic/scheme.py +1190 -0
- sage/schemes/generic/spec.py +199 -0
- sage/schemes/product_projective/all.py +6 -0
- sage/schemes/product_projective/homset.py +236 -0
- sage/schemes/product_projective/morphism.py +517 -0
- sage/schemes/product_projective/point.py +568 -0
- sage/schemes/product_projective/rational_point.py +550 -0
- sage/schemes/product_projective/space.py +1301 -0
- sage/schemes/product_projective/subscheme.py +466 -0
- sage/schemes/projective/all.py +24 -0
- sage/schemes/projective/proj_bdd_height.py +453 -0
- sage/schemes/projective/projective_homset.py +718 -0
- sage/schemes/projective/projective_morphism.py +2792 -0
- sage/schemes/projective/projective_point.py +1484 -0
- sage/schemes/projective/projective_rational_point.py +569 -0
- sage/schemes/projective/projective_space.py +2571 -0
- sage/schemes/projective/projective_subscheme.py +1574 -0
- sage/sets/all.py +17 -0
- sage/sets/cartesian_product.py +376 -0
- sage/sets/condition_set.py +525 -0
- sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/disjoint_set.pxd +36 -0
- sage/sets/disjoint_set.pyx +998 -0
- sage/sets/disjoint_union_enumerated_sets.py +625 -0
- sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/family.pxd +12 -0
- sage/sets/family.pyx +1556 -0
- sage/sets/finite_enumerated_set.py +406 -0
- sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/finite_set_map_cy.pxd +34 -0
- sage/sets/finite_set_map_cy.pyx +708 -0
- sage/sets/finite_set_maps.py +591 -0
- sage/sets/image_set.py +448 -0
- sage/sets/integer_range.py +829 -0
- sage/sets/non_negative_integers.py +241 -0
- sage/sets/positive_integers.py +93 -0
- sage/sets/primes.py +188 -0
- sage/sets/real_set.py +2760 -0
- sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/recursively_enumerated_set.pxd +31 -0
- sage/sets/recursively_enumerated_set.pyx +2082 -0
- sage/sets/set.py +2083 -0
- sage/sets/set_from_iterator.py +1021 -0
- sage/sets/totally_ordered_finite_set.py +329 -0
- sage/symbolic/all__sagemath_categories.py +1 -0
- sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/function.pxd +29 -0
- sage/symbolic/function.pyx +1488 -0
- sage/symbolic/symbols.py +56 -0
- sage/tests/all__sagemath_categories.py +1 -0
- sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/cython.pyx +37 -0
- sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/stl_vector.pyx +171 -0
- sage/typeset/all.py +6 -0
- sage/typeset/ascii_art.py +295 -0
- sage/typeset/character_art.py +789 -0
- sage/typeset/character_art_factory.py +572 -0
- sage/typeset/symbols.py +334 -0
- sage/typeset/unicode_art.py +183 -0
- sage/typeset/unicode_characters.py +101 -0
|
@@ -0,0 +1,2218 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
r"""
|
|
3
|
+
Double precision floating point real numbers
|
|
4
|
+
|
|
5
|
+
EXAMPLES:
|
|
6
|
+
|
|
7
|
+
We create the real double vector space of dimension `3`::
|
|
8
|
+
|
|
9
|
+
sage: V = RDF^3; V # needs sage.modules
|
|
10
|
+
Vector space of dimension 3 over Real Double Field
|
|
11
|
+
|
|
12
|
+
Notice that this space is unique::
|
|
13
|
+
|
|
14
|
+
sage: V is RDF^3 # needs sage.modules
|
|
15
|
+
True
|
|
16
|
+
sage: V is FreeModule(RDF, 3) # needs sage.modules
|
|
17
|
+
True
|
|
18
|
+
sage: V is VectorSpace(RDF, 3) # needs sage.modules
|
|
19
|
+
True
|
|
20
|
+
|
|
21
|
+
Also, you can instantly create a space of large dimension::
|
|
22
|
+
|
|
23
|
+
sage: V = RDF^10000 # needs sage.modules
|
|
24
|
+
|
|
25
|
+
TESTS:
|
|
26
|
+
|
|
27
|
+
Test NumPy conversions::
|
|
28
|
+
|
|
29
|
+
sage: RDF(1).__array_interface__
|
|
30
|
+
{'typestr': '=f8'}
|
|
31
|
+
sage: import numpy # needs numpy
|
|
32
|
+
sage: numpy.array([RDF.pi()]).dtype # needs numpy
|
|
33
|
+
dtype('float64')
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
# ****************************************************************************
|
|
37
|
+
# This program is free software: you can redistribute it and/or modify
|
|
38
|
+
# it under the terms of the GNU General Public License as published by
|
|
39
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
40
|
+
# (at your option) any later version.
|
|
41
|
+
# https://www.gnu.org/licenses/
|
|
42
|
+
# ****************************************************************************
|
|
43
|
+
|
|
44
|
+
cimport libc.math
|
|
45
|
+
from libc.string cimport memcpy
|
|
46
|
+
from cpython.object cimport *
|
|
47
|
+
from cpython.float cimport *
|
|
48
|
+
|
|
49
|
+
cdef extern from "Python.h":
|
|
50
|
+
void Py_SET_REFCNT(PyObject*, Py_ssize_t) nogil
|
|
51
|
+
|
|
52
|
+
from sage.ext.stdsage cimport PY_NEW
|
|
53
|
+
from sage.cpython.python_debug cimport if_Py_TRACE_REFS_then_PyObject_INIT
|
|
54
|
+
|
|
55
|
+
import math
|
|
56
|
+
|
|
57
|
+
import sage.arith.misc
|
|
58
|
+
import sage.rings.integer
|
|
59
|
+
import sage.rings.rational
|
|
60
|
+
|
|
61
|
+
from sage.rings.integer cimport Integer
|
|
62
|
+
from sage.rings.integer_ring import ZZ
|
|
63
|
+
|
|
64
|
+
from sage.categories.morphism cimport Morphism
|
|
65
|
+
from sage.structure.coerce cimport is_numpy_type
|
|
66
|
+
from sage.misc.randstate cimport randstate, current_randstate
|
|
67
|
+
from sage.structure.richcmp cimport rich_to_bool
|
|
68
|
+
from sage.arith.constants cimport *
|
|
69
|
+
|
|
70
|
+
cimport gmpy2
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
new_gen_from_real_double_element = None
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField):
|
|
77
|
+
"""
|
|
78
|
+
An approximation to the field of real numbers using double
|
|
79
|
+
precision floating point numbers. Answers derived from calculations
|
|
80
|
+
in this approximation may differ from what they would be if those
|
|
81
|
+
calculations were performed in the true field of real numbers. This
|
|
82
|
+
is due to the rounding errors inherent to finite precision
|
|
83
|
+
calculations.
|
|
84
|
+
|
|
85
|
+
EXAMPLES::
|
|
86
|
+
|
|
87
|
+
sage: RR == RDF # needs sage.rings.real_mpfr
|
|
88
|
+
False
|
|
89
|
+
sage: RDF == RealDoubleField() # RDF is the shorthand
|
|
90
|
+
True
|
|
91
|
+
|
|
92
|
+
::
|
|
93
|
+
|
|
94
|
+
sage: RDF(1)
|
|
95
|
+
1.0
|
|
96
|
+
sage: RDF(2/3)
|
|
97
|
+
0.6666666666666666
|
|
98
|
+
|
|
99
|
+
A :exc:`TypeError` is raised if the coercion doesn't make sense::
|
|
100
|
+
|
|
101
|
+
sage: RDF(QQ['x'].0)
|
|
102
|
+
Traceback (most recent call last):
|
|
103
|
+
...
|
|
104
|
+
TypeError: cannot convert nonconstant polynomial
|
|
105
|
+
sage: RDF(QQ['x'](3))
|
|
106
|
+
3.0
|
|
107
|
+
|
|
108
|
+
One can convert back and forth between double precision real
|
|
109
|
+
numbers and higher-precision ones, though of course there may be
|
|
110
|
+
loss of precision::
|
|
111
|
+
|
|
112
|
+
sage: # needs sage.rings.real_mpfr
|
|
113
|
+
sage: a = RealField(200)(2).sqrt(); a
|
|
114
|
+
1.4142135623730950488016887242096980785696718753769480731767
|
|
115
|
+
sage: b = RDF(a); b
|
|
116
|
+
1.4142135623730951
|
|
117
|
+
sage: a.parent()(b)
|
|
118
|
+
1.4142135623730951454746218587388284504413604736328125000000
|
|
119
|
+
sage: a.parent()(b) == b
|
|
120
|
+
True
|
|
121
|
+
sage: b == RR(a)
|
|
122
|
+
True
|
|
123
|
+
|
|
124
|
+
TESTS::
|
|
125
|
+
|
|
126
|
+
sage: RDF.is_finite()
|
|
127
|
+
False
|
|
128
|
+
"""
|
|
129
|
+
def __init__(self):
|
|
130
|
+
"""
|
|
131
|
+
Initialize ``self``.
|
|
132
|
+
|
|
133
|
+
TESTS::
|
|
134
|
+
|
|
135
|
+
sage: R = RealDoubleField()
|
|
136
|
+
sage: TestSuite(R).run()
|
|
137
|
+
"""
|
|
138
|
+
from sage.categories.fields import Fields
|
|
139
|
+
Field.__init__(self, self,
|
|
140
|
+
category=Fields().Infinite().Metric().Complete())
|
|
141
|
+
self._populate_coercion_lists_(init_no_parent=True,
|
|
142
|
+
convert_method_name='_real_double_')
|
|
143
|
+
|
|
144
|
+
_element_constructor_ = RealDoubleElement
|
|
145
|
+
|
|
146
|
+
def __reduce__(self):
|
|
147
|
+
"""
|
|
148
|
+
For pickling.
|
|
149
|
+
|
|
150
|
+
EXAMPLES::
|
|
151
|
+
|
|
152
|
+
sage: loads(dumps(RDF)) is RDF
|
|
153
|
+
True
|
|
154
|
+
"""
|
|
155
|
+
return RealDoubleField, ()
|
|
156
|
+
|
|
157
|
+
cpdef bint is_exact(self) except -2:
|
|
158
|
+
"""
|
|
159
|
+
Return ``False``, because doubles are not exact.
|
|
160
|
+
|
|
161
|
+
EXAMPLES::
|
|
162
|
+
|
|
163
|
+
sage: RDF.is_exact()
|
|
164
|
+
False
|
|
165
|
+
"""
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
def _latex_(self):
|
|
169
|
+
r"""
|
|
170
|
+
Return a latex representation of ``self``.
|
|
171
|
+
|
|
172
|
+
EXAMPLES::
|
|
173
|
+
|
|
174
|
+
sage: latex(RDF) # indirect doctest
|
|
175
|
+
\Bold{R}
|
|
176
|
+
"""
|
|
177
|
+
return "\\Bold{R}"
|
|
178
|
+
|
|
179
|
+
def _sage_input_(self, sib, coerced):
|
|
180
|
+
r"""
|
|
181
|
+
Produce an expression which will reproduce this value when evaluated.
|
|
182
|
+
|
|
183
|
+
EXAMPLES::
|
|
184
|
+
|
|
185
|
+
sage: sage_input(RDF, verify=True)
|
|
186
|
+
# Verified
|
|
187
|
+
RDF
|
|
188
|
+
sage: from sage.misc.sage_input import SageInputBuilder
|
|
189
|
+
sage: RDF._sage_input_(SageInputBuilder(), False)
|
|
190
|
+
{atomic:RDF}
|
|
191
|
+
"""
|
|
192
|
+
return sib.name('RDF')
|
|
193
|
+
|
|
194
|
+
def __repr__(self):
|
|
195
|
+
"""
|
|
196
|
+
Return a string representation of ``self``.
|
|
197
|
+
|
|
198
|
+
EXAMPLES::
|
|
199
|
+
|
|
200
|
+
sage: RealDoubleField() # indirect doctest
|
|
201
|
+
Real Double Field
|
|
202
|
+
sage: RDF
|
|
203
|
+
Real Double Field
|
|
204
|
+
"""
|
|
205
|
+
return "Real Double Field"
|
|
206
|
+
|
|
207
|
+
def _repr_option(self, key):
|
|
208
|
+
"""
|
|
209
|
+
Metadata about the :meth:`_repr_` output.
|
|
210
|
+
|
|
211
|
+
See :meth:`sage.structure.parent._repr_option` for details.
|
|
212
|
+
|
|
213
|
+
EXAMPLES::
|
|
214
|
+
|
|
215
|
+
sage: RDF._repr_option('element_is_atomic')
|
|
216
|
+
True
|
|
217
|
+
"""
|
|
218
|
+
if key == 'element_is_atomic':
|
|
219
|
+
return True
|
|
220
|
+
return super()._repr_option(key)
|
|
221
|
+
|
|
222
|
+
def __richcmp__(self, x, op):
|
|
223
|
+
"""
|
|
224
|
+
Compare ``self`` to ``x``.
|
|
225
|
+
|
|
226
|
+
EXAMPLES::
|
|
227
|
+
|
|
228
|
+
sage: RDF == 5
|
|
229
|
+
False
|
|
230
|
+
sage: loads(dumps(RDF)) == RDF
|
|
231
|
+
True
|
|
232
|
+
"""
|
|
233
|
+
if isinstance(x, RealDoubleField_class):
|
|
234
|
+
return rich_to_bool(op, 0)
|
|
235
|
+
if op == Py_NE:
|
|
236
|
+
return True
|
|
237
|
+
return NotImplemented
|
|
238
|
+
|
|
239
|
+
def construction(self):
|
|
240
|
+
r"""
|
|
241
|
+
Return the functorial construction of ``self``, namely, completion of
|
|
242
|
+
the rational numbers with respect to the prime at `\infty`.
|
|
243
|
+
|
|
244
|
+
Also preserves other information that makes this field unique (i.e.
|
|
245
|
+
the Real Double Field).
|
|
246
|
+
|
|
247
|
+
EXAMPLES::
|
|
248
|
+
|
|
249
|
+
sage: c, S = RDF.construction(); S
|
|
250
|
+
Rational Field
|
|
251
|
+
sage: RDF == c(S)
|
|
252
|
+
True
|
|
253
|
+
"""
|
|
254
|
+
from sage.categories.pushout import CompletionFunctor
|
|
255
|
+
return (CompletionFunctor(sage.rings.infinity.Infinity,
|
|
256
|
+
53,
|
|
257
|
+
{'type': 'RDF'}),
|
|
258
|
+
sage.rings.rational_field.QQ)
|
|
259
|
+
|
|
260
|
+
def complex_field(self):
|
|
261
|
+
"""
|
|
262
|
+
Return the complex field with the same precision as ``self``, i.e.,
|
|
263
|
+
the complex double field.
|
|
264
|
+
|
|
265
|
+
EXAMPLES::
|
|
266
|
+
|
|
267
|
+
sage: RDF.complex_field() # needs sage.rings.complex_double
|
|
268
|
+
Complex Double Field
|
|
269
|
+
"""
|
|
270
|
+
from sage.rings.complex_double import CDF
|
|
271
|
+
return CDF
|
|
272
|
+
|
|
273
|
+
def algebraic_closure(self):
|
|
274
|
+
"""
|
|
275
|
+
Return the algebraic closure of ``self``, i.e., the complex double
|
|
276
|
+
field.
|
|
277
|
+
|
|
278
|
+
EXAMPLES::
|
|
279
|
+
|
|
280
|
+
sage: RDF.algebraic_closure() # needs sage.rings.complex_double
|
|
281
|
+
Complex Double Field
|
|
282
|
+
"""
|
|
283
|
+
from sage.rings.complex_double import CDF
|
|
284
|
+
return CDF
|
|
285
|
+
|
|
286
|
+
cpdef _coerce_map_from_(self, S):
|
|
287
|
+
"""
|
|
288
|
+
Canonical coercion of ``S`` to the real double field.
|
|
289
|
+
|
|
290
|
+
The rings that canonically coerce to the real double field are:
|
|
291
|
+
|
|
292
|
+
- the real double field itself
|
|
293
|
+
- int, long, integer, and rational rings
|
|
294
|
+
- numpy integers and floatings
|
|
295
|
+
- the real lazy field
|
|
296
|
+
- the MPFR real field with at least 53 bits of precision
|
|
297
|
+
|
|
298
|
+
EXAMPLES::
|
|
299
|
+
|
|
300
|
+
sage: RDF.coerce(5) # indirect doctest
|
|
301
|
+
5.0
|
|
302
|
+
sage: RDF.coerce(9499294r)
|
|
303
|
+
9499294.0
|
|
304
|
+
sage: RDF.coerce(61/3)
|
|
305
|
+
20.333333333333332
|
|
306
|
+
sage: parent(RDF(3) + CDF(5)) # needs sage.rings.complex_double
|
|
307
|
+
Complex Double Field
|
|
308
|
+
sage: parent(CDF(5) + RDF(3)) # needs sage.rings.complex_double
|
|
309
|
+
Complex Double Field
|
|
310
|
+
sage: CDF.gen(0) + 5.0 # needs sage.rings.complex_double
|
|
311
|
+
5.0 + 1.0*I
|
|
312
|
+
sage: RLF(2/3) + RDF(1)
|
|
313
|
+
1.6666666666666665
|
|
314
|
+
|
|
315
|
+
sage: import numpy # needs numpy
|
|
316
|
+
sage: RDF.coerce(numpy.int8('1')) # needs numpy
|
|
317
|
+
1.0
|
|
318
|
+
sage: RDF.coerce(numpy.float64('1')) # needs numpy
|
|
319
|
+
1.0
|
|
320
|
+
|
|
321
|
+
sage: RDF.coerce(pi) # needs sage.symbolic
|
|
322
|
+
Traceback (most recent call last):
|
|
323
|
+
...
|
|
324
|
+
TypeError: no canonical coercion from Symbolic Ring to Real Double Field
|
|
325
|
+
|
|
326
|
+
Test that :issue:`15695` is fixed (see also :issue:`18076`)::
|
|
327
|
+
|
|
328
|
+
sage: 1j + numpy.float64(2) # needs numpy
|
|
329
|
+
2.00000000000000 + 1.00000000000000*I
|
|
330
|
+
sage: parent(_) # needs numpy
|
|
331
|
+
Complex Field with 53 bits of precision
|
|
332
|
+
"""
|
|
333
|
+
if S is int or S is float:
|
|
334
|
+
return ToRDF(S)
|
|
335
|
+
|
|
336
|
+
from sage.rings.rational_field import QQ
|
|
337
|
+
try:
|
|
338
|
+
from sage.rings.real_lazy import RLF
|
|
339
|
+
except ImportError:
|
|
340
|
+
RLF = None
|
|
341
|
+
|
|
342
|
+
if S is ZZ or S is QQ or S is RLF:
|
|
343
|
+
return ToRDF(S)
|
|
344
|
+
|
|
345
|
+
if isinstance(S, sage.rings.abc.RealField):
|
|
346
|
+
if S.prec() >= 53:
|
|
347
|
+
return ToRDF(S)
|
|
348
|
+
else:
|
|
349
|
+
return None
|
|
350
|
+
elif is_numpy_type(S):
|
|
351
|
+
import numpy
|
|
352
|
+
if issubclass(S, numpy.integer) or issubclass(S, numpy.floating):
|
|
353
|
+
return ToRDF(S)
|
|
354
|
+
else:
|
|
355
|
+
return None
|
|
356
|
+
|
|
357
|
+
try:
|
|
358
|
+
from sage.rings.real_mpfr import RR
|
|
359
|
+
except ImportError:
|
|
360
|
+
pass
|
|
361
|
+
else:
|
|
362
|
+
connecting = RR._internal_coerce_map_from(S)
|
|
363
|
+
if connecting is not None:
|
|
364
|
+
return ToRDF(RR) * connecting
|
|
365
|
+
|
|
366
|
+
def _magma_init_(self, magma):
|
|
367
|
+
r"""
|
|
368
|
+
Return a string representation of ``self`` in the Magma language.
|
|
369
|
+
|
|
370
|
+
EXAMPLES:
|
|
371
|
+
|
|
372
|
+
Magma handles precision in decimal digits, so we lose a bit::
|
|
373
|
+
|
|
374
|
+
sage: magma(RDF) # indirect doctest # optional - magma
|
|
375
|
+
Real field of precision 15
|
|
376
|
+
sage: 10^15 < 2^53 < 10^16
|
|
377
|
+
True
|
|
378
|
+
|
|
379
|
+
When we convert back from Magma, we convert to a generic real field
|
|
380
|
+
that has 53 bits of precision::
|
|
381
|
+
|
|
382
|
+
sage: magma(RDF).sage() # optional - magma
|
|
383
|
+
Real Field with 53 bits of precision
|
|
384
|
+
"""
|
|
385
|
+
return "RealField(%s : Bits := true)" % self.prec()
|
|
386
|
+
|
|
387
|
+
def _fricas_init_(self):
|
|
388
|
+
r"""
|
|
389
|
+
Return the FriCAS representation of the real double field.
|
|
390
|
+
|
|
391
|
+
EXAMPLES::
|
|
392
|
+
|
|
393
|
+
sage: fricas(RDF) # indirect doctest # optional - fricas
|
|
394
|
+
DoubleFloat
|
|
395
|
+
"""
|
|
396
|
+
return "DoubleFloat"
|
|
397
|
+
|
|
398
|
+
def _polymake_init_(self):
|
|
399
|
+
r"""
|
|
400
|
+
Return the polymake representation of the real double field.
|
|
401
|
+
|
|
402
|
+
EXAMPLES::
|
|
403
|
+
|
|
404
|
+
sage: polymake(RDF) # indirect doctest # optional - jupymake
|
|
405
|
+
Float
|
|
406
|
+
"""
|
|
407
|
+
return '"Float"'
|
|
408
|
+
|
|
409
|
+
def precision(self):
|
|
410
|
+
"""
|
|
411
|
+
Return the precision of this real double field in bits.
|
|
412
|
+
|
|
413
|
+
Always returns 53.
|
|
414
|
+
|
|
415
|
+
EXAMPLES::
|
|
416
|
+
|
|
417
|
+
sage: RDF.precision()
|
|
418
|
+
53
|
|
419
|
+
"""
|
|
420
|
+
return 53
|
|
421
|
+
|
|
422
|
+
prec = precision
|
|
423
|
+
|
|
424
|
+
def to_prec(self, prec):
|
|
425
|
+
"""
|
|
426
|
+
Return the real field to the specified precision. As doubles have
|
|
427
|
+
fixed precision, this will only return a real double field if ``prec``
|
|
428
|
+
is exactly 53.
|
|
429
|
+
|
|
430
|
+
EXAMPLES::
|
|
431
|
+
|
|
432
|
+
sage: RDF.to_prec(52) # needs sage.rings.real_mpfr
|
|
433
|
+
Real Field with 52 bits of precision
|
|
434
|
+
sage: RDF.to_prec(53)
|
|
435
|
+
Real Double Field
|
|
436
|
+
"""
|
|
437
|
+
if prec == 53:
|
|
438
|
+
return self
|
|
439
|
+
from sage.rings.real_mpfr import RealField
|
|
440
|
+
return RealField(prec)
|
|
441
|
+
|
|
442
|
+
def gen(self, n=0):
|
|
443
|
+
"""
|
|
444
|
+
Return the generator of the real double field.
|
|
445
|
+
|
|
446
|
+
EXAMPLES::
|
|
447
|
+
|
|
448
|
+
sage: RDF.0
|
|
449
|
+
1.0
|
|
450
|
+
sage: RDF.gens()
|
|
451
|
+
(1.0,)
|
|
452
|
+
"""
|
|
453
|
+
if n != 0:
|
|
454
|
+
raise ValueError("only 1 generator")
|
|
455
|
+
return RealDoubleElement(1)
|
|
456
|
+
|
|
457
|
+
def ngens(self):
|
|
458
|
+
"""
|
|
459
|
+
Return the number of generators which is always 1.
|
|
460
|
+
|
|
461
|
+
EXAMPLES::
|
|
462
|
+
|
|
463
|
+
sage: RDF.ngens()
|
|
464
|
+
1
|
|
465
|
+
"""
|
|
466
|
+
return 1
|
|
467
|
+
|
|
468
|
+
def characteristic(self):
|
|
469
|
+
"""
|
|
470
|
+
Return 0, since the field of real numbers has characteristic 0.
|
|
471
|
+
|
|
472
|
+
EXAMPLES::
|
|
473
|
+
|
|
474
|
+
sage: RDF.characteristic()
|
|
475
|
+
0
|
|
476
|
+
"""
|
|
477
|
+
return Integer(0)
|
|
478
|
+
|
|
479
|
+
cdef _new_c(self, double value):
|
|
480
|
+
cdef RealDoubleElement x
|
|
481
|
+
x = PY_NEW(RealDoubleElement)
|
|
482
|
+
x._value = value
|
|
483
|
+
return x
|
|
484
|
+
|
|
485
|
+
def random_element(self, double min=-1, double max=1):
|
|
486
|
+
"""
|
|
487
|
+
Return a random element of this real double field in the interval
|
|
488
|
+
``[min, max]``.
|
|
489
|
+
|
|
490
|
+
EXAMPLES::
|
|
491
|
+
|
|
492
|
+
sage: RDF.random_element().parent() is RDF
|
|
493
|
+
True
|
|
494
|
+
sage: -1 <= RDF.random_element() <= 1
|
|
495
|
+
True
|
|
496
|
+
sage: 100 <= RDF.random_element(min=100, max=110) <= 110
|
|
497
|
+
True
|
|
498
|
+
"""
|
|
499
|
+
cdef randstate rstate = current_randstate()
|
|
500
|
+
|
|
501
|
+
return self._new_c((max-min)*rstate.c_rand_double() + min)
|
|
502
|
+
|
|
503
|
+
def name(self):
|
|
504
|
+
"""
|
|
505
|
+
The name of ``self``.
|
|
506
|
+
|
|
507
|
+
EXAMPLES::
|
|
508
|
+
|
|
509
|
+
sage: RDF.name()
|
|
510
|
+
'RealDoubleField'
|
|
511
|
+
"""
|
|
512
|
+
return "RealDoubleField"
|
|
513
|
+
|
|
514
|
+
def __hash__(self):
|
|
515
|
+
"""
|
|
516
|
+
Return the hash value of ``self``.
|
|
517
|
+
|
|
518
|
+
This class is intended for use as a singleton so any instance
|
|
519
|
+
of it should be equivalent from a hashing perspective.
|
|
520
|
+
|
|
521
|
+
TESTS::
|
|
522
|
+
|
|
523
|
+
sage: from sage.rings.real_double import RealDoubleField_class
|
|
524
|
+
sage: hash(RDF) == hash(RealDoubleField_class())
|
|
525
|
+
True
|
|
526
|
+
"""
|
|
527
|
+
return 1157042230
|
|
528
|
+
|
|
529
|
+
def pi(self):
|
|
530
|
+
r"""
|
|
531
|
+
Return `\pi` to double-precision.
|
|
532
|
+
|
|
533
|
+
EXAMPLES::
|
|
534
|
+
|
|
535
|
+
sage: RDF.pi()
|
|
536
|
+
3.141592653589793
|
|
537
|
+
sage: RDF.pi().sqrt()/2
|
|
538
|
+
0.8862269254527579
|
|
539
|
+
"""
|
|
540
|
+
return self(M_PI)
|
|
541
|
+
|
|
542
|
+
def euler_constant(self):
|
|
543
|
+
"""
|
|
544
|
+
Return Euler's gamma constant to double precision.
|
|
545
|
+
|
|
546
|
+
EXAMPLES::
|
|
547
|
+
|
|
548
|
+
sage: RDF.euler_constant()
|
|
549
|
+
0.5772156649015329
|
|
550
|
+
"""
|
|
551
|
+
return self(M_EULER)
|
|
552
|
+
|
|
553
|
+
def log2(self):
|
|
554
|
+
r"""
|
|
555
|
+
Return `\log(2)` to the precision of this field.
|
|
556
|
+
|
|
557
|
+
EXAMPLES::
|
|
558
|
+
|
|
559
|
+
sage: RDF.log2()
|
|
560
|
+
0.6931471805599453
|
|
561
|
+
sage: RDF(2).log()
|
|
562
|
+
0.6931471805599453
|
|
563
|
+
"""
|
|
564
|
+
return self(M_LN2)
|
|
565
|
+
|
|
566
|
+
def factorial(self, int n):
|
|
567
|
+
"""
|
|
568
|
+
Return the factorial of the integer `n` as a real number.
|
|
569
|
+
|
|
570
|
+
EXAMPLES::
|
|
571
|
+
|
|
572
|
+
sage: RDF.factorial(100)
|
|
573
|
+
9.332621544394415e+157
|
|
574
|
+
"""
|
|
575
|
+
return global_dummy_element._factorial(n)
|
|
576
|
+
|
|
577
|
+
def zeta(self, n=2):
|
|
578
|
+
"""
|
|
579
|
+
Return an `n`-th root of unity in the real field, if one
|
|
580
|
+
exists, or raise a :exc:`ValueError` otherwise.
|
|
581
|
+
|
|
582
|
+
EXAMPLES::
|
|
583
|
+
|
|
584
|
+
sage: RDF.zeta()
|
|
585
|
+
-1.0
|
|
586
|
+
sage: RDF.zeta(1)
|
|
587
|
+
1.0
|
|
588
|
+
sage: RDF.zeta(5)
|
|
589
|
+
Traceback (most recent call last):
|
|
590
|
+
...
|
|
591
|
+
ValueError: No 5th root of unity in self
|
|
592
|
+
"""
|
|
593
|
+
if n == 1:
|
|
594
|
+
return self(1)
|
|
595
|
+
elif n == 2:
|
|
596
|
+
return self(-1)
|
|
597
|
+
raise ValueError("No %sth root of unity in self" % n)
|
|
598
|
+
|
|
599
|
+
def NaN(self):
|
|
600
|
+
"""
|
|
601
|
+
Return Not-a-Number ``NaN``.
|
|
602
|
+
|
|
603
|
+
EXAMPLES::
|
|
604
|
+
|
|
605
|
+
sage: RDF.NaN()
|
|
606
|
+
NaN
|
|
607
|
+
"""
|
|
608
|
+
return self(0)/self(0)
|
|
609
|
+
|
|
610
|
+
nan = NaN
|
|
611
|
+
|
|
612
|
+
def _factor_univariate_polynomial(self, f):
|
|
613
|
+
"""
|
|
614
|
+
Factor the univariate polynomial ``f``.
|
|
615
|
+
|
|
616
|
+
INPUT:
|
|
617
|
+
|
|
618
|
+
- ``f`` -- a univariate polynomial defined over the double precision
|
|
619
|
+
real numbers
|
|
620
|
+
|
|
621
|
+
OUTPUT:
|
|
622
|
+
|
|
623
|
+
- A factorization of ``f`` over the double precision real numbers
|
|
624
|
+
into a unit and monic irreducible factors
|
|
625
|
+
|
|
626
|
+
.. NOTE::
|
|
627
|
+
|
|
628
|
+
This is a helper method for
|
|
629
|
+
:meth:`sage.rings.polynomial.polynomial_element.Polynomial.factor`.
|
|
630
|
+
|
|
631
|
+
TESTS::
|
|
632
|
+
|
|
633
|
+
sage: # needs numpy
|
|
634
|
+
sage: R.<x> = RDF[]
|
|
635
|
+
sage: RDF._factor_univariate_polynomial(x)
|
|
636
|
+
x
|
|
637
|
+
sage: RDF._factor_univariate_polynomial(2*x)
|
|
638
|
+
(2.0) * x
|
|
639
|
+
sage: RDF._factor_univariate_polynomial(x^2)
|
|
640
|
+
x^2
|
|
641
|
+
sage: RDF._factor_univariate_polynomial(x^2 + 1)
|
|
642
|
+
x^2 + 1.0
|
|
643
|
+
sage: RDF._factor_univariate_polynomial(x^2 - 1)
|
|
644
|
+
(x - 1.0) * (x + 1.0)
|
|
645
|
+
|
|
646
|
+
The implementation relies on the ``roots()`` method which often reports
|
|
647
|
+
roots not to be real even though they are::
|
|
648
|
+
|
|
649
|
+
sage: f = (x-1)^3 # needs numpy
|
|
650
|
+
sage: f.roots(ring=CDF) # abs tol 2e-5 # needs numpy
|
|
651
|
+
[(1.0000065719436413, 1),
|
|
652
|
+
(0.9999967140281792 - 5.691454546815028e-06*I, 1),
|
|
653
|
+
(0.9999967140281792 + 5.691454546815028e-06*I, 1)]
|
|
654
|
+
|
|
655
|
+
This leads to the following incorrect factorization::
|
|
656
|
+
|
|
657
|
+
sage: f.factor() # abs tol 2e-5 # needs numpy
|
|
658
|
+
(x - 1.0000065719436413) * (x^2 - 1.9999934280563585*x + 0.9999934280995487)
|
|
659
|
+
"""
|
|
660
|
+
from sage.rings.complex_double import CDF
|
|
661
|
+
roots = f.roots(CDF)
|
|
662
|
+
|
|
663
|
+
# collect real roots and conjugate pairs of non-real roots
|
|
664
|
+
real_roots = [(r, e) for r, e in roots if r.imag().is_zero()]
|
|
665
|
+
non_real_roots = {r: e for r, e in roots if not r.imag().is_zero()}
|
|
666
|
+
assert all(non_real_roots[r.conj()] == e for r, e in non_real_roots.items()), "Bug in root finding code over RDF - roots must always come in conjugate pairs"
|
|
667
|
+
non_real_roots = [(r, e) for r, e in non_real_roots.items() if r.imag() > 0]
|
|
668
|
+
|
|
669
|
+
# turn the roots into irreducible factors
|
|
670
|
+
x = f.parent().gen()
|
|
671
|
+
real_factors = [(x - r.real(), e) for r, e in real_roots]
|
|
672
|
+
non_real_factors = [(x**2 - (r + r.conj()).real()*x + (r*r.conj()).real(), e) for r, e in non_real_roots]
|
|
673
|
+
|
|
674
|
+
# make the factors monic
|
|
675
|
+
from sage.structure.factorization import Factorization
|
|
676
|
+
return Factorization([(g.monic(), e) for g, e in real_factors + non_real_factors], f.leading_coefficient())
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
cdef class RealDoubleElement(FieldElement):
|
|
680
|
+
"""
|
|
681
|
+
An approximation to a real number using double precision floating
|
|
682
|
+
point numbers. Answers derived from calculations with such
|
|
683
|
+
approximations may differ from what they would be if those
|
|
684
|
+
calculations were performed with true real numbers. This is due to
|
|
685
|
+
the rounding errors inherent to finite precision calculations.
|
|
686
|
+
"""
|
|
687
|
+
|
|
688
|
+
__array_interface__ = {'typestr': '=f8'}
|
|
689
|
+
|
|
690
|
+
def __cinit__(self):
|
|
691
|
+
"""
|
|
692
|
+
Initialize ``self`` for cython.
|
|
693
|
+
|
|
694
|
+
EXAMPLES::
|
|
695
|
+
|
|
696
|
+
sage: RDF(2.3) # indirect doctest
|
|
697
|
+
2.3
|
|
698
|
+
"""
|
|
699
|
+
(<Element>self)._parent = _RDF
|
|
700
|
+
|
|
701
|
+
def __init__(self, x):
|
|
702
|
+
"""
|
|
703
|
+
Create a new ``RealDoubleElement`` with value ``x``.
|
|
704
|
+
|
|
705
|
+
EXAMPLES::
|
|
706
|
+
|
|
707
|
+
sage: RDF(10^100)
|
|
708
|
+
1e+100
|
|
709
|
+
|
|
710
|
+
TESTS::
|
|
711
|
+
|
|
712
|
+
sage: from gmpy2 import *
|
|
713
|
+
sage: RDF(mpz(42))
|
|
714
|
+
42.0
|
|
715
|
+
sage: RDF(mpq(3/4))
|
|
716
|
+
0.75
|
|
717
|
+
sage: RDF(mpq('4.1'))
|
|
718
|
+
4.1
|
|
719
|
+
"""
|
|
720
|
+
self._value = float(x)
|
|
721
|
+
|
|
722
|
+
def _magma_init_(self, magma):
|
|
723
|
+
r"""
|
|
724
|
+
Return a string representation of ``self`` in the Magma language.
|
|
725
|
+
|
|
726
|
+
EXAMPLES::
|
|
727
|
+
|
|
728
|
+
sage: RDF(10.5)
|
|
729
|
+
10.5
|
|
730
|
+
sage: magma(RDF(10.5)) # indirect doctest # optional - magma
|
|
731
|
+
10.5000000000000
|
|
732
|
+
"""
|
|
733
|
+
return "%s!%s" % (self.parent()._magma_init_(magma), self)
|
|
734
|
+
|
|
735
|
+
def __reduce__(self):
|
|
736
|
+
"""
|
|
737
|
+
For pickling.
|
|
738
|
+
|
|
739
|
+
EXAMPLES::
|
|
740
|
+
|
|
741
|
+
sage: a = RDF(-2.7)
|
|
742
|
+
sage: loads(dumps(a)) == a
|
|
743
|
+
True
|
|
744
|
+
"""
|
|
745
|
+
return RealDoubleElement, (self._value, )
|
|
746
|
+
|
|
747
|
+
cdef _new_c(self, double value):
|
|
748
|
+
cdef RealDoubleElement x
|
|
749
|
+
x = PY_NEW(RealDoubleElement)
|
|
750
|
+
x._value = value
|
|
751
|
+
return x
|
|
752
|
+
|
|
753
|
+
def prec(self):
|
|
754
|
+
"""
|
|
755
|
+
Return the precision of this number in bits.
|
|
756
|
+
|
|
757
|
+
Always returns 53.
|
|
758
|
+
|
|
759
|
+
EXAMPLES::
|
|
760
|
+
|
|
761
|
+
sage: RDF(0).prec()
|
|
762
|
+
53
|
|
763
|
+
"""
|
|
764
|
+
return 53
|
|
765
|
+
|
|
766
|
+
def ulp(self):
|
|
767
|
+
"""
|
|
768
|
+
Return the unit of least precision of ``self``, which is the
|
|
769
|
+
weight of the least significant bit of ``self``. This is always
|
|
770
|
+
a strictly positive number. It is also the gap between this
|
|
771
|
+
number and the closest number with larger absolute value that
|
|
772
|
+
can be represented.
|
|
773
|
+
|
|
774
|
+
EXAMPLES::
|
|
775
|
+
|
|
776
|
+
sage: a = RDF(pi) # needs sage.symbolic
|
|
777
|
+
sage: a.ulp() # needs sage.symbolic
|
|
778
|
+
4.440892098500626e-16
|
|
779
|
+
sage: b = a + a.ulp() # needs sage.symbolic
|
|
780
|
+
|
|
781
|
+
Adding or subtracting an ulp always gives a different number::
|
|
782
|
+
|
|
783
|
+
sage: # needs sage.symbolic
|
|
784
|
+
sage: a + a.ulp() == a
|
|
785
|
+
False
|
|
786
|
+
sage: a - a.ulp() == a
|
|
787
|
+
False
|
|
788
|
+
sage: b + b.ulp() == b
|
|
789
|
+
False
|
|
790
|
+
sage: b - b.ulp() == b
|
|
791
|
+
False
|
|
792
|
+
|
|
793
|
+
Since the default rounding mode is round-to-nearest, adding or
|
|
794
|
+
subtracting something less than half an ulp always gives the
|
|
795
|
+
same number, unless the result has a smaller ulp. The latter
|
|
796
|
+
can only happen if the input number is (up to sign) exactly a
|
|
797
|
+
power of 2::
|
|
798
|
+
|
|
799
|
+
sage: # needs sage.symbolic
|
|
800
|
+
sage: a - a.ulp()/3 == a
|
|
801
|
+
True
|
|
802
|
+
sage: a + a.ulp()/3 == a
|
|
803
|
+
True
|
|
804
|
+
sage: b - b.ulp()/3 == b
|
|
805
|
+
True
|
|
806
|
+
sage: b + b.ulp()/3 == b
|
|
807
|
+
True
|
|
808
|
+
|
|
809
|
+
sage: c = RDF(1)
|
|
810
|
+
sage: c - c.ulp()/3 == c
|
|
811
|
+
False
|
|
812
|
+
sage: c.ulp()
|
|
813
|
+
2.220446049250313e-16
|
|
814
|
+
sage: (c - c.ulp()).ulp()
|
|
815
|
+
1.1102230246251565e-16
|
|
816
|
+
|
|
817
|
+
The ulp is always positive::
|
|
818
|
+
|
|
819
|
+
sage: RDF(-1).ulp()
|
|
820
|
+
2.220446049250313e-16
|
|
821
|
+
|
|
822
|
+
The ulp of zero is the smallest positive number in RDF::
|
|
823
|
+
|
|
824
|
+
sage: RDF(0).ulp()
|
|
825
|
+
5e-324
|
|
826
|
+
sage: RDF(0).ulp()/2
|
|
827
|
+
0.0
|
|
828
|
+
|
|
829
|
+
Some special values::
|
|
830
|
+
|
|
831
|
+
sage: a = RDF(1)/RDF(0); a
|
|
832
|
+
+infinity
|
|
833
|
+
sage: a.ulp()
|
|
834
|
+
+infinity
|
|
835
|
+
sage: (-a).ulp()
|
|
836
|
+
+infinity
|
|
837
|
+
sage: a = RDF('nan')
|
|
838
|
+
sage: a.ulp() is a
|
|
839
|
+
True
|
|
840
|
+
|
|
841
|
+
The ulp method works correctly with small numbers::
|
|
842
|
+
|
|
843
|
+
sage: u = RDF(0).ulp()
|
|
844
|
+
sage: u.ulp() == u
|
|
845
|
+
True
|
|
846
|
+
sage: x = u * (2^52-1) # largest denormal number
|
|
847
|
+
sage: x.ulp() == u
|
|
848
|
+
True
|
|
849
|
+
sage: x = u * 2^52 # smallest normal number
|
|
850
|
+
sage: x.ulp() == u
|
|
851
|
+
True
|
|
852
|
+
"""
|
|
853
|
+
# First, check special values
|
|
854
|
+
if self._value == 0:
|
|
855
|
+
return RealDoubleElement(libc.math.ldexp(1.0, -1074))
|
|
856
|
+
if libc.math.isnan(self._value):
|
|
857
|
+
return self
|
|
858
|
+
if libc.math.isinf(self._value):
|
|
859
|
+
return self.abs()
|
|
860
|
+
|
|
861
|
+
# Normal case
|
|
862
|
+
cdef int e
|
|
863
|
+
libc.math.frexp(self._value, &e)
|
|
864
|
+
e -= 53
|
|
865
|
+
# Correction for denormals
|
|
866
|
+
if e < -1074:
|
|
867
|
+
e = -1074
|
|
868
|
+
return RealDoubleElement(libc.math.ldexp(1.0, e))
|
|
869
|
+
|
|
870
|
+
def real(self):
|
|
871
|
+
"""
|
|
872
|
+
Return ``self`` - we are already real.
|
|
873
|
+
|
|
874
|
+
EXAMPLES::
|
|
875
|
+
|
|
876
|
+
sage: a = RDF(3)
|
|
877
|
+
sage: a.real()
|
|
878
|
+
3.0
|
|
879
|
+
"""
|
|
880
|
+
return self
|
|
881
|
+
|
|
882
|
+
def imag(self):
|
|
883
|
+
"""
|
|
884
|
+
Return the imaginary part of this number, which is zero.
|
|
885
|
+
|
|
886
|
+
EXAMPLES::
|
|
887
|
+
|
|
888
|
+
sage: a = RDF(3)
|
|
889
|
+
sage: a.imag()
|
|
890
|
+
0.0
|
|
891
|
+
"""
|
|
892
|
+
return RealDoubleElement(0)
|
|
893
|
+
|
|
894
|
+
def __complex__(self):
|
|
895
|
+
"""
|
|
896
|
+
Return ``self`` as a python complex number.
|
|
897
|
+
|
|
898
|
+
EXAMPLES::
|
|
899
|
+
|
|
900
|
+
sage: a = 2303
|
|
901
|
+
sage: RDF(a)
|
|
902
|
+
2303.0
|
|
903
|
+
sage: complex(RDF(a))
|
|
904
|
+
(2303+0j)
|
|
905
|
+
"""
|
|
906
|
+
return complex(self._value, 0)
|
|
907
|
+
|
|
908
|
+
def _integer_(self, ZZ=None):
|
|
909
|
+
"""
|
|
910
|
+
If this floating-point number is actually an integer, return
|
|
911
|
+
that integer. Otherwise, raise an exception.
|
|
912
|
+
|
|
913
|
+
EXAMPLES::
|
|
914
|
+
|
|
915
|
+
sage: ZZ(RDF(237.0)) # indirect doctest
|
|
916
|
+
237
|
|
917
|
+
sage: ZZ(RDF(0.0/0.0))
|
|
918
|
+
Traceback (most recent call last):
|
|
919
|
+
...
|
|
920
|
+
ValueError: cannot convert float NaN to integer
|
|
921
|
+
sage: ZZ(RDF(1.0/0.0))
|
|
922
|
+
Traceback (most recent call last):
|
|
923
|
+
...
|
|
924
|
+
OverflowError: cannot convert float infinity to integer
|
|
925
|
+
sage: ZZ(RDF(-123456789.0))
|
|
926
|
+
-123456789
|
|
927
|
+
sage: ZZ(RDF((2.0))^290)
|
|
928
|
+
1989292945639146568621528992587283360401824603189390869761855907572637988050133502132224
|
|
929
|
+
sage: ZZ(RDF(-2345.67))
|
|
930
|
+
Traceback (most recent call last):
|
|
931
|
+
...
|
|
932
|
+
TypeError: cannot convert non-integral float to integer
|
|
933
|
+
"""
|
|
934
|
+
return Integer(self._value)
|
|
935
|
+
|
|
936
|
+
def __mpfr__(self):
|
|
937
|
+
"""
|
|
938
|
+
Convert Sage ``RealDoubleElement`` to gmpy2 ``mpfr``.
|
|
939
|
+
|
|
940
|
+
EXAMPLES::
|
|
941
|
+
|
|
942
|
+
sage: RDF(42.2).__mpfr__()
|
|
943
|
+
mpfr('42.200000000000003')
|
|
944
|
+
sage: from gmpy2 import mpfr
|
|
945
|
+
sage: mpfr(RDF(5.1))
|
|
946
|
+
mpfr('5.0999999999999996')
|
|
947
|
+
|
|
948
|
+
TESTS::
|
|
949
|
+
|
|
950
|
+
sage: RDF().__mpfr__(); raise NotImplementedError("gmpy2 is not installed")
|
|
951
|
+
Traceback (most recent call last):
|
|
952
|
+
...
|
|
953
|
+
NotImplementedError: gmpy2 is not installed
|
|
954
|
+
"""
|
|
955
|
+
return gmpy2.mpfr(self._value)
|
|
956
|
+
|
|
957
|
+
def _interface_init_(self, I=None):
|
|
958
|
+
"""
|
|
959
|
+
Return ``self`` formatted as a string, suitable as input to another
|
|
960
|
+
computer algebra system. (This is the default function used for
|
|
961
|
+
exporting to other computer algebra systems.)
|
|
962
|
+
|
|
963
|
+
EXAMPLES::
|
|
964
|
+
|
|
965
|
+
sage: s1 = RDF(sin(1)); s1 # needs sage.symbolic
|
|
966
|
+
0.8414709848078965
|
|
967
|
+
sage: s1._interface_init_() # needs sage.symbolic
|
|
968
|
+
'0.8414709848078965'
|
|
969
|
+
sage: s1 == RDF(gp(s1)) # needs sage.libs.pari sage.symbolic
|
|
970
|
+
True
|
|
971
|
+
"""
|
|
972
|
+
return repr(self._value)
|
|
973
|
+
|
|
974
|
+
def _mathematica_init_(self):
|
|
975
|
+
"""
|
|
976
|
+
TESTS:
|
|
977
|
+
|
|
978
|
+
Check that :issue:`28814` is fixed::
|
|
979
|
+
|
|
980
|
+
sage: mathematica(RDF(1e25)) # optional - mathematica
|
|
981
|
+
1.*^25
|
|
982
|
+
sage: mathematica(RDF(1e-25)) # optional - mathematica
|
|
983
|
+
1.*^-25
|
|
984
|
+
"""
|
|
985
|
+
from sage.rings.real_mpfr import RR
|
|
986
|
+
return RR(self._value)._mathematica_init_()
|
|
987
|
+
|
|
988
|
+
def _sage_input_(self, sib, coerced):
|
|
989
|
+
r"""
|
|
990
|
+
Produce an expression which will reproduce this value when evaluated.
|
|
991
|
+
|
|
992
|
+
EXAMPLES::
|
|
993
|
+
|
|
994
|
+
sage: sage_input(RDF(NaN)) # needs sage.symbolic
|
|
995
|
+
RDF(NaN)
|
|
996
|
+
sage: sage_input(RDF(-infinity), verify=True)
|
|
997
|
+
# Verified
|
|
998
|
+
-RDF(infinity)
|
|
999
|
+
sage: sage_input(RDF(-infinity)*polygen(RDF))
|
|
1000
|
+
R.<x> = RDF[]
|
|
1001
|
+
-RDF(infinity)*x + RDF(NaN)
|
|
1002
|
+
sage: sage_input(RDF(pi), verify=True) # needs sage.symbolic
|
|
1003
|
+
# Verified
|
|
1004
|
+
RDF(3.1415926535897931)
|
|
1005
|
+
sage: sage_input(RDF(-e), verify=True, preparse=False) # needs sage.symbolic
|
|
1006
|
+
# Verified
|
|
1007
|
+
-RDF(2.718281828459045...)
|
|
1008
|
+
sage: sage_input(RDF(pi)*polygen(RDF), verify=True, preparse=None) # needs sage.symbolic
|
|
1009
|
+
# Verified
|
|
1010
|
+
R = RDF['x']
|
|
1011
|
+
x = R.gen()
|
|
1012
|
+
3.1415926535897931*x
|
|
1013
|
+
sage: from sage.misc.sage_input import SageInputBuilder
|
|
1014
|
+
sage: sib = SageInputBuilder()
|
|
1015
|
+
sage: RDF(22/7)._sage_input_(sib, True) # needs sage.sage.rings.real_mpfr
|
|
1016
|
+
{atomic:3.1428571428571428}
|
|
1017
|
+
sage: RDF(22/7)._sage_input_(sib, False) # needs sage.sage.rings.real_mpfr
|
|
1018
|
+
{call: {atomic:RDF}({atomic:3.1428571428571428})}
|
|
1019
|
+
"""
|
|
1020
|
+
cdef bint isinf = libc.math.isinf(self._value)
|
|
1021
|
+
cdef bint isnan = libc.math.isnan(self._value)
|
|
1022
|
+
if isinf or isnan:
|
|
1023
|
+
if isnan:
|
|
1024
|
+
v = sib.name('NaN')
|
|
1025
|
+
else:
|
|
1026
|
+
v = sib.name('infinity')
|
|
1027
|
+
v = sib(self.parent())(v)
|
|
1028
|
+
if self._value < 0:
|
|
1029
|
+
v = -v
|
|
1030
|
+
return v
|
|
1031
|
+
|
|
1032
|
+
from sage.rings.integer_ring import ZZ
|
|
1033
|
+
from sage.rings.real_mpfr import RR
|
|
1034
|
+
|
|
1035
|
+
cdef bint negative = self._value < 0
|
|
1036
|
+
if negative:
|
|
1037
|
+
self = -self
|
|
1038
|
+
|
|
1039
|
+
# There are five possibilities for printing this floating-point
|
|
1040
|
+
# number, ordered from prettiest to ugliest (IMHO).
|
|
1041
|
+
# 1) An integer: 42
|
|
1042
|
+
# 2) A simple literal: 3.14159
|
|
1043
|
+
# 3) A coerced integer: RDF(42)
|
|
1044
|
+
# 4) A coerced literal: RDF(3.14159)
|
|
1045
|
+
# 5) A coerced RR value: RDF(RR('3.14159'))
|
|
1046
|
+
|
|
1047
|
+
# str(self) works via libc, which we don't necessarily trust
|
|
1048
|
+
# to produce the best possible answer. So this function prints
|
|
1049
|
+
# via RR/MPFR. Without the preparser, input works via libc as
|
|
1050
|
+
# well, but we don't have a choice about that.
|
|
1051
|
+
|
|
1052
|
+
# To use choice 1 or choice 3, this number must be an integer.
|
|
1053
|
+
cdef bint can_use_int_literal = \
|
|
1054
|
+
self.abs() < (Integer(1) << self.prec()) and self in ZZ
|
|
1055
|
+
|
|
1056
|
+
self_str = RR(self._value).str(truncate=False, skip_zeroes=True)
|
|
1057
|
+
|
|
1058
|
+
# To use choice 2 or choice 4, we must be able to read
|
|
1059
|
+
# numbers of this precision as a literal.
|
|
1060
|
+
cdef bint can_use_float_literal = \
|
|
1061
|
+
(sib.preparse() or float(self_str) == self)
|
|
1062
|
+
|
|
1063
|
+
if can_use_int_literal or can_use_float_literal:
|
|
1064
|
+
if can_use_int_literal:
|
|
1065
|
+
v = sib.int(self._integer_())
|
|
1066
|
+
else:
|
|
1067
|
+
v = sib.float_str(self_str)
|
|
1068
|
+
else:
|
|
1069
|
+
v = sib(RR(self))
|
|
1070
|
+
if not coerced:
|
|
1071
|
+
v = sib(self.parent())(v)
|
|
1072
|
+
|
|
1073
|
+
if negative:
|
|
1074
|
+
v = -v
|
|
1075
|
+
|
|
1076
|
+
return v
|
|
1077
|
+
|
|
1078
|
+
def _repr_(self):
|
|
1079
|
+
"""
|
|
1080
|
+
Return the string representation of ``self``.
|
|
1081
|
+
|
|
1082
|
+
EXAMPLES::
|
|
1083
|
+
|
|
1084
|
+
sage: RDF(-2/3)
|
|
1085
|
+
-0.6666666666666666
|
|
1086
|
+
sage: a = RDF(2); a
|
|
1087
|
+
2.0
|
|
1088
|
+
sage: a^2
|
|
1089
|
+
4.0
|
|
1090
|
+
sage: RDF("nan")
|
|
1091
|
+
NaN
|
|
1092
|
+
sage: RDF(1)/RDF(0)
|
|
1093
|
+
+infinity
|
|
1094
|
+
sage: RDF(-1)/RDF(0)
|
|
1095
|
+
-infinity
|
|
1096
|
+
"""
|
|
1097
|
+
return double_repr(self._value)
|
|
1098
|
+
|
|
1099
|
+
def __format__(self, format_spec):
|
|
1100
|
+
"""
|
|
1101
|
+
Return a formatted string representation of this real number.
|
|
1102
|
+
|
|
1103
|
+
EXAMPLES::
|
|
1104
|
+
|
|
1105
|
+
sage: format(RDF(32/3), '.4f')
|
|
1106
|
+
'10.6667'
|
|
1107
|
+
sage: '{:.4e}'.format(RDF(2/3))
|
|
1108
|
+
'6.6667e-01'
|
|
1109
|
+
"""
|
|
1110
|
+
return format(float(self), format_spec)
|
|
1111
|
+
|
|
1112
|
+
def _latex_(self):
|
|
1113
|
+
r"""
|
|
1114
|
+
Return a latex representation of ``self``.
|
|
1115
|
+
|
|
1116
|
+
EXAMPLES::
|
|
1117
|
+
|
|
1118
|
+
sage: latex(RDF(3.4)) # indirect doctest
|
|
1119
|
+
3.4
|
|
1120
|
+
sage: latex(RDF(2e-100)) # indirect doctest
|
|
1121
|
+
2 \times 10^{-100}
|
|
1122
|
+
"""
|
|
1123
|
+
s = self.str()
|
|
1124
|
+
parts = s.split('e')
|
|
1125
|
+
if len(parts) > 1:
|
|
1126
|
+
# scientific notation
|
|
1127
|
+
if parts[1][0] == '+':
|
|
1128
|
+
parts[1] = parts[1][1:]
|
|
1129
|
+
s = "%s \\times 10^{%s}" % (parts[0], parts[1])
|
|
1130
|
+
return s
|
|
1131
|
+
|
|
1132
|
+
def __hash__(self):
|
|
1133
|
+
"""
|
|
1134
|
+
Return the hash of ``self``, which coincides with the python float
|
|
1135
|
+
(and often int) type.
|
|
1136
|
+
|
|
1137
|
+
EXAMPLES::
|
|
1138
|
+
|
|
1139
|
+
sage: hash(RDF(1.2)) == hash(1.2r)
|
|
1140
|
+
True
|
|
1141
|
+
"""
|
|
1142
|
+
return hash(self._value)
|
|
1143
|
+
|
|
1144
|
+
def _im_gens_(self, codomain, im_gens, base_map=None):
|
|
1145
|
+
"""
|
|
1146
|
+
Return the image of ``self`` under the homomorphism from the rational
|
|
1147
|
+
field to ``codomain``.
|
|
1148
|
+
|
|
1149
|
+
This always just returns ``self`` coerced into the ``codomain``.
|
|
1150
|
+
|
|
1151
|
+
EXAMPLES::
|
|
1152
|
+
|
|
1153
|
+
sage: RDF(2.1)._im_gens_(RR, [RR(1)])
|
|
1154
|
+
2.10000000000000
|
|
1155
|
+
sage: R = RealField(20) # needs sage.rings.real_mpfr
|
|
1156
|
+
sage: RDF(2.1)._im_gens_(R, [R(1)]) # needs sage.rings.real_mpfr
|
|
1157
|
+
2.1000
|
|
1158
|
+
"""
|
|
1159
|
+
return codomain(self) # since 1 |--> 1
|
|
1160
|
+
|
|
1161
|
+
def str(self):
|
|
1162
|
+
"""
|
|
1163
|
+
Return the informal string representation of ``self``.
|
|
1164
|
+
|
|
1165
|
+
EXAMPLES::
|
|
1166
|
+
|
|
1167
|
+
sage: a = RDF('4.5'); a.str()
|
|
1168
|
+
'4.5'
|
|
1169
|
+
sage: a = RDF('49203480923840.2923904823048'); a.str()
|
|
1170
|
+
'49203480923840.29'
|
|
1171
|
+
sage: a = RDF(1)/RDF(0); a.str()
|
|
1172
|
+
'+infinity'
|
|
1173
|
+
sage: a = -RDF(1)/RDF(0); a.str()
|
|
1174
|
+
'-infinity'
|
|
1175
|
+
sage: a = RDF(0)/RDF(0); a.str()
|
|
1176
|
+
'NaN'
|
|
1177
|
+
|
|
1178
|
+
We verify consistency with ``RR`` (mpfr reals)::
|
|
1179
|
+
|
|
1180
|
+
sage: str(RR(RDF(1)/RDF(0))) == str(RDF(1)/RDF(0))
|
|
1181
|
+
True
|
|
1182
|
+
sage: str(RR(-RDF(1)/RDF(0))) == str(-RDF(1)/RDF(0))
|
|
1183
|
+
True
|
|
1184
|
+
sage: str(RR(RDF(0)/RDF(0))) == str(RDF(0)/RDF(0))
|
|
1185
|
+
True
|
|
1186
|
+
"""
|
|
1187
|
+
return double_repr(self._value)
|
|
1188
|
+
|
|
1189
|
+
def __copy__(self):
|
|
1190
|
+
"""
|
|
1191
|
+
Return copy of ``self``, which since ``self`` is immutable, is just
|
|
1192
|
+
``self``.
|
|
1193
|
+
|
|
1194
|
+
EXAMPLES::
|
|
1195
|
+
|
|
1196
|
+
sage: r = RDF('-1.6')
|
|
1197
|
+
sage: r.__copy__() is r
|
|
1198
|
+
True
|
|
1199
|
+
"""
|
|
1200
|
+
return self
|
|
1201
|
+
|
|
1202
|
+
def __deepcopy__(self, memo):
|
|
1203
|
+
"""
|
|
1204
|
+
EXAMPLES::
|
|
1205
|
+
|
|
1206
|
+
sage: r = RDF('-1.6')
|
|
1207
|
+
sage: deepcopy(r) is r
|
|
1208
|
+
True
|
|
1209
|
+
"""
|
|
1210
|
+
return self
|
|
1211
|
+
|
|
1212
|
+
def integer_part(self):
|
|
1213
|
+
"""
|
|
1214
|
+
If in decimal this number is written ``n.defg``, returns ``n``.
|
|
1215
|
+
|
|
1216
|
+
EXAMPLES::
|
|
1217
|
+
|
|
1218
|
+
sage: r = RDF('-1.6')
|
|
1219
|
+
sage: a = r.integer_part(); a
|
|
1220
|
+
-1
|
|
1221
|
+
sage: type(a)
|
|
1222
|
+
<class 'sage.rings.integer.Integer'>
|
|
1223
|
+
sage: r = RDF(0.0/0.0)
|
|
1224
|
+
sage: a = r.integer_part()
|
|
1225
|
+
Traceback (most recent call last):
|
|
1226
|
+
...
|
|
1227
|
+
TypeError: Attempt to get integer part of NaN
|
|
1228
|
+
"""
|
|
1229
|
+
if libc.math.isnan(self._value):
|
|
1230
|
+
raise TypeError("Attempt to get integer part of NaN")
|
|
1231
|
+
else:
|
|
1232
|
+
return Integer(int(self._value))
|
|
1233
|
+
|
|
1234
|
+
def sign_mantissa_exponent(self):
|
|
1235
|
+
r"""
|
|
1236
|
+
Return the sign, mantissa, and exponent of ``self``.
|
|
1237
|
+
|
|
1238
|
+
In Sage (as in MPFR), floating-point numbers of precision `p`
|
|
1239
|
+
are of the form `s m 2^{e-p}`, where `s \in \{-1, 1\}`,
|
|
1240
|
+
`2^{p-1} \leq m < 2^p`, and `-2^{30} + 1 \leq e \leq 2^{30} -
|
|
1241
|
+
1`; plus the special values ``+0``, ``-0``, ``+infinity``,
|
|
1242
|
+
``-infinity``, and ``NaN`` (which stands for Not-a-Number).
|
|
1243
|
+
|
|
1244
|
+
This function returns `s`, `m`, and `e-p`. For the special values:
|
|
1245
|
+
|
|
1246
|
+
- ``+0`` returns ``(1, 0, 0)``
|
|
1247
|
+
- ``-0`` returns ``(-1, 0, 0)``
|
|
1248
|
+
- the return values for ``+infinity``, ``-infinity``, and ``NaN`` are
|
|
1249
|
+
not specified.
|
|
1250
|
+
|
|
1251
|
+
EXAMPLES::
|
|
1252
|
+
|
|
1253
|
+
sage: # needs sage.symbolic
|
|
1254
|
+
sage: a = RDF(exp(1.0)); a
|
|
1255
|
+
2.718281828459045
|
|
1256
|
+
sage: sign, mantissa, exponent = RDF(exp(1.0)).sign_mantissa_exponent()
|
|
1257
|
+
sage: sign, mantissa, exponent
|
|
1258
|
+
(1, 6121026514868073, -51)
|
|
1259
|
+
sage: sign*mantissa*(2**exponent) == a
|
|
1260
|
+
True
|
|
1261
|
+
|
|
1262
|
+
The mantissa is always a nonnegative number::
|
|
1263
|
+
|
|
1264
|
+
sage: RDF(-1).sign_mantissa_exponent() # needs sage.rings.real_mpfr
|
|
1265
|
+
(-1, 4503599627370496, -52)
|
|
1266
|
+
|
|
1267
|
+
TESTS::
|
|
1268
|
+
|
|
1269
|
+
sage: RDF('+0').sign_mantissa_exponent() # needs sage.rings.real_mpfr
|
|
1270
|
+
(1, 0, 0)
|
|
1271
|
+
sage: RDF('-0').sign_mantissa_exponent() # needs sage.rings.real_mpfr
|
|
1272
|
+
(-1, 0, 0)
|
|
1273
|
+
"""
|
|
1274
|
+
from sage.rings.real_mpfr import RR
|
|
1275
|
+
return RR(self._value).sign_mantissa_exponent()
|
|
1276
|
+
|
|
1277
|
+
def as_integer_ratio(self):
|
|
1278
|
+
"""
|
|
1279
|
+
Return a coprime pair of integers ``(a, b)`` such that ``self``
|
|
1280
|
+
equals ``a / b`` exactly.
|
|
1281
|
+
|
|
1282
|
+
EXAMPLES::
|
|
1283
|
+
|
|
1284
|
+
sage: RDF(0).as_integer_ratio()
|
|
1285
|
+
(0, 1)
|
|
1286
|
+
sage: RDF(1/3).as_integer_ratio()
|
|
1287
|
+
(6004799503160661, 18014398509481984)
|
|
1288
|
+
sage: RDF(37/16).as_integer_ratio()
|
|
1289
|
+
(37, 16)
|
|
1290
|
+
sage: RDF(3^60).as_integer_ratio()
|
|
1291
|
+
(42391158275216203520420085760, 1)
|
|
1292
|
+
"""
|
|
1293
|
+
nd = float.as_integer_ratio(self._value)
|
|
1294
|
+
return (Integer(nd[0]), Integer(nd[1]))
|
|
1295
|
+
|
|
1296
|
+
########################
|
|
1297
|
+
# Basic Arithmetic
|
|
1298
|
+
########################
|
|
1299
|
+
def __invert__(self):
|
|
1300
|
+
"""
|
|
1301
|
+
Compute the multiplicative inverse of ``self``.
|
|
1302
|
+
|
|
1303
|
+
EXAMPLES::
|
|
1304
|
+
|
|
1305
|
+
sage: a = RDF(-1.5)*RDF(2.5)
|
|
1306
|
+
sage: a.__invert__()
|
|
1307
|
+
-0.26666666666666666
|
|
1308
|
+
sage: ~a
|
|
1309
|
+
-0.26666666666666666
|
|
1310
|
+
"""
|
|
1311
|
+
cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
|
|
1312
|
+
x._value = 1.0 / self._value
|
|
1313
|
+
return x
|
|
1314
|
+
|
|
1315
|
+
cpdef _add_(self, right):
|
|
1316
|
+
"""
|
|
1317
|
+
Add two real numbers with the same parent.
|
|
1318
|
+
|
|
1319
|
+
EXAMPLES::
|
|
1320
|
+
|
|
1321
|
+
sage: RDF('-1.5') + RDF('2.5') # indirect doctest
|
|
1322
|
+
1.0
|
|
1323
|
+
"""
|
|
1324
|
+
cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
|
|
1325
|
+
x._value = self._value + (<RealDoubleElement>right)._value
|
|
1326
|
+
return x
|
|
1327
|
+
|
|
1328
|
+
cpdef _sub_(self, right):
|
|
1329
|
+
"""
|
|
1330
|
+
Subtract two real numbers with the same parent.
|
|
1331
|
+
|
|
1332
|
+
EXAMPLES::
|
|
1333
|
+
|
|
1334
|
+
sage: RDF('-1.5') - RDF('2.5') # indirect doctest
|
|
1335
|
+
-4.0
|
|
1336
|
+
"""
|
|
1337
|
+
cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
|
|
1338
|
+
x._value = self._value - (<RealDoubleElement>right)._value
|
|
1339
|
+
return x
|
|
1340
|
+
|
|
1341
|
+
cpdef _mul_(self, right):
|
|
1342
|
+
"""
|
|
1343
|
+
Multiply two real numbers with the same parent.
|
|
1344
|
+
|
|
1345
|
+
EXAMPLES::
|
|
1346
|
+
|
|
1347
|
+
sage: RDF('-1.5') * RDF('2.5') # indirect doctest
|
|
1348
|
+
-3.75
|
|
1349
|
+
"""
|
|
1350
|
+
cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
|
|
1351
|
+
x._value = self._value * (<RealDoubleElement>right)._value
|
|
1352
|
+
return x
|
|
1353
|
+
|
|
1354
|
+
cpdef _div_(self, right):
|
|
1355
|
+
"""
|
|
1356
|
+
Divide ``self`` by ``right``.
|
|
1357
|
+
|
|
1358
|
+
EXAMPLES::
|
|
1359
|
+
|
|
1360
|
+
sage: RDF('-1.5') / RDF('2.5') # indirect doctest
|
|
1361
|
+
-0.6
|
|
1362
|
+
sage: RDF(1)/RDF(0)
|
|
1363
|
+
+infinity
|
|
1364
|
+
"""
|
|
1365
|
+
cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
|
|
1366
|
+
x._value = self._value / (<RealDoubleElement>right)._value
|
|
1367
|
+
return x
|
|
1368
|
+
|
|
1369
|
+
def __neg__(self):
|
|
1370
|
+
"""
|
|
1371
|
+
Negate ``self``.
|
|
1372
|
+
|
|
1373
|
+
EXAMPLES::
|
|
1374
|
+
|
|
1375
|
+
sage: -RDF('-1.5')
|
|
1376
|
+
1.5
|
|
1377
|
+
"""
|
|
1378
|
+
cdef RealDoubleElement x = <RealDoubleElement>PY_NEW(RealDoubleElement)
|
|
1379
|
+
x._value = -self._value
|
|
1380
|
+
return x
|
|
1381
|
+
|
|
1382
|
+
def conjugate(self):
|
|
1383
|
+
r"""
|
|
1384
|
+
Return the complex conjugate of this real number, which is
|
|
1385
|
+
the real number itself.
|
|
1386
|
+
|
|
1387
|
+
EXAMPLES::
|
|
1388
|
+
|
|
1389
|
+
sage: RDF(4).conjugate()
|
|
1390
|
+
4.0
|
|
1391
|
+
"""
|
|
1392
|
+
return self
|
|
1393
|
+
|
|
1394
|
+
def __abs__(self):
|
|
1395
|
+
"""
|
|
1396
|
+
Return the absolute value of ``self``.
|
|
1397
|
+
|
|
1398
|
+
EXAMPLES::
|
|
1399
|
+
|
|
1400
|
+
sage: abs(RDF(1.5))
|
|
1401
|
+
1.5
|
|
1402
|
+
sage: abs(RDF(-1.5))
|
|
1403
|
+
1.5
|
|
1404
|
+
sage: abs(RDF(0.0))
|
|
1405
|
+
0.0
|
|
1406
|
+
sage: abs(RDF(-0.0))
|
|
1407
|
+
0.0
|
|
1408
|
+
"""
|
|
1409
|
+
# Use signbit instead of >= to handle -0.0 correctly
|
|
1410
|
+
if not libc.math.signbit(self._value):
|
|
1411
|
+
return self
|
|
1412
|
+
else:
|
|
1413
|
+
return self._new_c(-self._value)
|
|
1414
|
+
|
|
1415
|
+
cpdef RealDoubleElement abs(RealDoubleElement self):
|
|
1416
|
+
"""
|
|
1417
|
+
Return the absolute value of ``self``.
|
|
1418
|
+
|
|
1419
|
+
EXAMPLES::
|
|
1420
|
+
|
|
1421
|
+
sage: RDF(1e10).abs()
|
|
1422
|
+
10000000000.0
|
|
1423
|
+
sage: RDF(-1e10).abs()
|
|
1424
|
+
10000000000.0
|
|
1425
|
+
"""
|
|
1426
|
+
if self._value >= 0:
|
|
1427
|
+
return self
|
|
1428
|
+
else:
|
|
1429
|
+
return self._new_c(-self._value)
|
|
1430
|
+
|
|
1431
|
+
def __lshift__(x, y):
|
|
1432
|
+
"""
|
|
1433
|
+
LShifting a double is not supported; nor is lshifting a
|
|
1434
|
+
:class:`RealDoubleElement`.
|
|
1435
|
+
|
|
1436
|
+
TESTS::
|
|
1437
|
+
|
|
1438
|
+
sage: RDF(2) << 3
|
|
1439
|
+
Traceback (most recent call last):
|
|
1440
|
+
...
|
|
1441
|
+
TypeError: unsupported operand type(s) for <<
|
|
1442
|
+
"""
|
|
1443
|
+
raise TypeError("unsupported operand type(s) for <<")
|
|
1444
|
+
|
|
1445
|
+
def __rshift__(x, y):
|
|
1446
|
+
"""
|
|
1447
|
+
RShifting a double is not supported; nor is rshifting a
|
|
1448
|
+
:class:`RealDoubleElement`.
|
|
1449
|
+
|
|
1450
|
+
TESTS::
|
|
1451
|
+
|
|
1452
|
+
sage: RDF(2) >> 3
|
|
1453
|
+
Traceback (most recent call last):
|
|
1454
|
+
...
|
|
1455
|
+
TypeError: unsupported operand type(s) for >>
|
|
1456
|
+
"""
|
|
1457
|
+
raise TypeError("unsupported operand type(s) for >>")
|
|
1458
|
+
|
|
1459
|
+
def multiplicative_order(self):
|
|
1460
|
+
r"""
|
|
1461
|
+
Return `n` such that ``self^n == 1``.
|
|
1462
|
+
|
|
1463
|
+
Only `\pm 1` have finite multiplicative order.
|
|
1464
|
+
|
|
1465
|
+
EXAMPLES::
|
|
1466
|
+
|
|
1467
|
+
sage: RDF(1).multiplicative_order()
|
|
1468
|
+
1
|
|
1469
|
+
sage: RDF(-1).multiplicative_order()
|
|
1470
|
+
2
|
|
1471
|
+
sage: RDF(3).multiplicative_order()
|
|
1472
|
+
+Infinity
|
|
1473
|
+
"""
|
|
1474
|
+
if self._value == 1:
|
|
1475
|
+
return 1
|
|
1476
|
+
elif self._value == -1:
|
|
1477
|
+
return 2
|
|
1478
|
+
return sage.rings.infinity.infinity
|
|
1479
|
+
|
|
1480
|
+
def sign(self):
|
|
1481
|
+
"""
|
|
1482
|
+
Return -1, 0, or 1 if ``self`` is negative, zero, or positive;
|
|
1483
|
+
respectively.
|
|
1484
|
+
|
|
1485
|
+
EXAMPLES::
|
|
1486
|
+
|
|
1487
|
+
sage: RDF(-1.5).sign()
|
|
1488
|
+
-1
|
|
1489
|
+
sage: RDF(0).sign()
|
|
1490
|
+
0
|
|
1491
|
+
sage: RDF(2.5).sign()
|
|
1492
|
+
1
|
|
1493
|
+
"""
|
|
1494
|
+
if not self._value:
|
|
1495
|
+
return 0
|
|
1496
|
+
if self._value > 0:
|
|
1497
|
+
return 1
|
|
1498
|
+
return -1
|
|
1499
|
+
|
|
1500
|
+
###################
|
|
1501
|
+
# Rounding etc
|
|
1502
|
+
###################
|
|
1503
|
+
|
|
1504
|
+
def round(self):
|
|
1505
|
+
"""
|
|
1506
|
+
Round ``self`` to the nearest integer.
|
|
1507
|
+
|
|
1508
|
+
This uses the convention of rounding half to even
|
|
1509
|
+
(i.e., if the fractional part of ``self`` is `0.5`, then it
|
|
1510
|
+
is rounded to the nearest even integer).
|
|
1511
|
+
|
|
1512
|
+
EXAMPLES::
|
|
1513
|
+
|
|
1514
|
+
sage: RDF(0.49).round()
|
|
1515
|
+
0
|
|
1516
|
+
sage: a=RDF(0.51).round(); a
|
|
1517
|
+
1
|
|
1518
|
+
sage: RDF(0.5).round()
|
|
1519
|
+
0
|
|
1520
|
+
sage: RDF(1.5).round()
|
|
1521
|
+
2
|
|
1522
|
+
"""
|
|
1523
|
+
return Integer(round(self._value))
|
|
1524
|
+
|
|
1525
|
+
def floor(self):
|
|
1526
|
+
"""
|
|
1527
|
+
Return the floor of ``self``.
|
|
1528
|
+
|
|
1529
|
+
EXAMPLES::
|
|
1530
|
+
|
|
1531
|
+
sage: RDF(2.99).floor()
|
|
1532
|
+
2
|
|
1533
|
+
sage: RDF(2.00).floor()
|
|
1534
|
+
2
|
|
1535
|
+
sage: RDF(-5/2).floor()
|
|
1536
|
+
-3
|
|
1537
|
+
"""
|
|
1538
|
+
return Integer(math.floor(self._value))
|
|
1539
|
+
|
|
1540
|
+
def ceil(self):
|
|
1541
|
+
"""
|
|
1542
|
+
Return the ceiling of ``self``.
|
|
1543
|
+
|
|
1544
|
+
EXAMPLES::
|
|
1545
|
+
|
|
1546
|
+
sage: RDF(2.99).ceil()
|
|
1547
|
+
3
|
|
1548
|
+
sage: RDF(2.00).ceil()
|
|
1549
|
+
2
|
|
1550
|
+
sage: RDF(-5/2).ceil()
|
|
1551
|
+
-2
|
|
1552
|
+
"""
|
|
1553
|
+
return Integer(math.ceil(self._value))
|
|
1554
|
+
|
|
1555
|
+
ceiling = ceil
|
|
1556
|
+
|
|
1557
|
+
def trunc(self):
|
|
1558
|
+
"""
|
|
1559
|
+
Truncates this number (returns integer part).
|
|
1560
|
+
|
|
1561
|
+
EXAMPLES::
|
|
1562
|
+
|
|
1563
|
+
sage: RDF(2.99).trunc()
|
|
1564
|
+
2
|
|
1565
|
+
sage: RDF(-2.00).trunc()
|
|
1566
|
+
-2
|
|
1567
|
+
sage: RDF(0.00).trunc()
|
|
1568
|
+
0
|
|
1569
|
+
"""
|
|
1570
|
+
return Integer(int(self._value))
|
|
1571
|
+
|
|
1572
|
+
def frac(self):
|
|
1573
|
+
"""
|
|
1574
|
+
Return a real number in `(-1, 1)`. It satisfies the relation:
|
|
1575
|
+
``x = x.trunc() + x.frac()``
|
|
1576
|
+
|
|
1577
|
+
EXAMPLES::
|
|
1578
|
+
|
|
1579
|
+
sage: RDF(2.99).frac()
|
|
1580
|
+
0.9900000000000002
|
|
1581
|
+
sage: RDF(2.50).frac()
|
|
1582
|
+
0.5
|
|
1583
|
+
sage: RDF(-2.79).frac()
|
|
1584
|
+
-0.79
|
|
1585
|
+
"""
|
|
1586
|
+
return self._new_c(self._value - int(self._value))
|
|
1587
|
+
|
|
1588
|
+
###########################################
|
|
1589
|
+
# Conversions
|
|
1590
|
+
###########################################
|
|
1591
|
+
|
|
1592
|
+
def __float__(self):
|
|
1593
|
+
"""
|
|
1594
|
+
Return ``self`` as a python float.
|
|
1595
|
+
|
|
1596
|
+
EXAMPLES::
|
|
1597
|
+
|
|
1598
|
+
sage: float(RDF(1.5))
|
|
1599
|
+
1.5
|
|
1600
|
+
sage: type(float(RDF(1.5)))
|
|
1601
|
+
<... 'float'>
|
|
1602
|
+
"""
|
|
1603
|
+
return self._value
|
|
1604
|
+
|
|
1605
|
+
def _rpy_(self):
|
|
1606
|
+
"""
|
|
1607
|
+
Return ``self.__float__()`` for rpy to convert into the
|
|
1608
|
+
appropriate R object.
|
|
1609
|
+
|
|
1610
|
+
EXAMPLES::
|
|
1611
|
+
|
|
1612
|
+
sage: n = RDF(2.0)
|
|
1613
|
+
sage: n._rpy_()
|
|
1614
|
+
2.0
|
|
1615
|
+
sage: type(n._rpy_())
|
|
1616
|
+
<... 'float'>
|
|
1617
|
+
"""
|
|
1618
|
+
return self.__float__()
|
|
1619
|
+
|
|
1620
|
+
def __int__(self):
|
|
1621
|
+
"""
|
|
1622
|
+
Return integer truncation of this real number.
|
|
1623
|
+
|
|
1624
|
+
EXAMPLES::
|
|
1625
|
+
|
|
1626
|
+
sage: int(RDF(2.99))
|
|
1627
|
+
2
|
|
1628
|
+
sage: int(RDF(-2.99))
|
|
1629
|
+
-2
|
|
1630
|
+
"""
|
|
1631
|
+
return int(self._value)
|
|
1632
|
+
|
|
1633
|
+
def _complex_mpfr_field_(self, CC):
|
|
1634
|
+
"""
|
|
1635
|
+
EXAMPLES::
|
|
1636
|
+
|
|
1637
|
+
sage: a = RDF(1/3)
|
|
1638
|
+
sage: CC(a) # needs sage.rings.real_mpfr
|
|
1639
|
+
0.333333333333333
|
|
1640
|
+
sage: a._complex_mpfr_field_(CC) # needs sage.rings.real_mpfr
|
|
1641
|
+
0.333333333333333
|
|
1642
|
+
|
|
1643
|
+
If we coerce to a higher-precision field the extra bits appear
|
|
1644
|
+
random; they are actually 0s in base 2.
|
|
1645
|
+
|
|
1646
|
+
::
|
|
1647
|
+
|
|
1648
|
+
sage: a._complex_mpfr_field_(ComplexField(100)) # needs sage.rings.real_mpfr
|
|
1649
|
+
0.33333333333333331482961625625
|
|
1650
|
+
sage: a._complex_mpfr_field_(ComplexField(100)).str(2) # needs sage.rings.real_mpfr
|
|
1651
|
+
'0.01010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000'
|
|
1652
|
+
"""
|
|
1653
|
+
return CC(self._value)
|
|
1654
|
+
|
|
1655
|
+
def _complex_double_(self, CDF):
|
|
1656
|
+
"""
|
|
1657
|
+
Return ``self`` as a complex double.
|
|
1658
|
+
|
|
1659
|
+
EXAMPLES::
|
|
1660
|
+
|
|
1661
|
+
sage: CDF(RDF(1/3)) # indirect doctest # needs sage.rings.complex_double
|
|
1662
|
+
0.3333333333333333
|
|
1663
|
+
"""
|
|
1664
|
+
return CDF(self._value)
|
|
1665
|
+
|
|
1666
|
+
def __pari__(self):
|
|
1667
|
+
"""
|
|
1668
|
+
Return a PARI representation of ``self``.
|
|
1669
|
+
|
|
1670
|
+
EXAMPLES::
|
|
1671
|
+
|
|
1672
|
+
sage: RDF(1.5).__pari__() # needs sage.libs.pari
|
|
1673
|
+
1.50000000000000
|
|
1674
|
+
"""
|
|
1675
|
+
global new_gen_from_real_double_element
|
|
1676
|
+
if new_gen_from_real_double_element is None:
|
|
1677
|
+
from sage.libs.pari.convert_sage_real_double import new_gen_from_real_double_element
|
|
1678
|
+
return new_gen_from_real_double_element(self)
|
|
1679
|
+
|
|
1680
|
+
###########################################
|
|
1681
|
+
# Comparisons: ==, !=, <, <=, >, >=
|
|
1682
|
+
###########################################
|
|
1683
|
+
|
|
1684
|
+
def is_NaN(self):
|
|
1685
|
+
"""
|
|
1686
|
+
Check if ``self`` is ``NaN``.
|
|
1687
|
+
|
|
1688
|
+
EXAMPLES::
|
|
1689
|
+
|
|
1690
|
+
sage: RDF(1).is_NaN()
|
|
1691
|
+
False
|
|
1692
|
+
sage: a = RDF(0)/RDF(0)
|
|
1693
|
+
sage: a.is_NaN()
|
|
1694
|
+
True
|
|
1695
|
+
"""
|
|
1696
|
+
return bool(libc.math.isnan(self._value))
|
|
1697
|
+
|
|
1698
|
+
def is_positive_infinity(self):
|
|
1699
|
+
r"""
|
|
1700
|
+
Check if ``self`` is `+\infty`.
|
|
1701
|
+
|
|
1702
|
+
EXAMPLES::
|
|
1703
|
+
|
|
1704
|
+
sage: a = RDF(1)/RDF(0)
|
|
1705
|
+
sage: a.is_positive_infinity()
|
|
1706
|
+
True
|
|
1707
|
+
sage: a = RDF(-1)/RDF(0)
|
|
1708
|
+
sage: a.is_positive_infinity()
|
|
1709
|
+
False
|
|
1710
|
+
"""
|
|
1711
|
+
if not libc.math.isinf(self._value):
|
|
1712
|
+
return False
|
|
1713
|
+
return self._value > 0
|
|
1714
|
+
|
|
1715
|
+
def is_negative_infinity(self):
|
|
1716
|
+
r"""
|
|
1717
|
+
Check if ``self`` is `-\infty`.
|
|
1718
|
+
|
|
1719
|
+
EXAMPLES::
|
|
1720
|
+
|
|
1721
|
+
sage: a = RDF(2)/RDF(0)
|
|
1722
|
+
sage: a.is_negative_infinity()
|
|
1723
|
+
False
|
|
1724
|
+
sage: a = RDF(-3)/RDF(0)
|
|
1725
|
+
sage: a.is_negative_infinity()
|
|
1726
|
+
True
|
|
1727
|
+
"""
|
|
1728
|
+
if not libc.math.isinf(self._value):
|
|
1729
|
+
return False
|
|
1730
|
+
return self._value < 0
|
|
1731
|
+
|
|
1732
|
+
def is_infinity(self):
|
|
1733
|
+
r"""
|
|
1734
|
+
Check if ``self`` is `\infty`.
|
|
1735
|
+
|
|
1736
|
+
EXAMPLES::
|
|
1737
|
+
|
|
1738
|
+
sage: a = RDF(2); b = RDF(0)
|
|
1739
|
+
sage: (a/b).is_infinity()
|
|
1740
|
+
True
|
|
1741
|
+
sage: (b/a).is_infinity()
|
|
1742
|
+
False
|
|
1743
|
+
"""
|
|
1744
|
+
return bool(libc.math.isinf(self._value))
|
|
1745
|
+
|
|
1746
|
+
cpdef _richcmp_(left, right, int op):
|
|
1747
|
+
"""
|
|
1748
|
+
Rich comparison of ``left`` and ``right``.
|
|
1749
|
+
|
|
1750
|
+
EXAMPLES::
|
|
1751
|
+
|
|
1752
|
+
sage: RDF(2) < RDF(0)
|
|
1753
|
+
False
|
|
1754
|
+
sage: RDF(2) == RDF(4/2)
|
|
1755
|
+
True
|
|
1756
|
+
sage: RDF(-2) > RDF(-4)
|
|
1757
|
+
True
|
|
1758
|
+
|
|
1759
|
+
TESTS:
|
|
1760
|
+
|
|
1761
|
+
Check comparisons with ``NaN`` (:issue:`16515`)::
|
|
1762
|
+
|
|
1763
|
+
sage: n = RDF('NaN')
|
|
1764
|
+
sage: n == n
|
|
1765
|
+
False
|
|
1766
|
+
sage: n == RDF(1)
|
|
1767
|
+
False
|
|
1768
|
+
"""
|
|
1769
|
+
# We really need to use the correct operators, to deal
|
|
1770
|
+
# correctly with NaNs.
|
|
1771
|
+
cdef double x = (<RealDoubleElement>left)._value
|
|
1772
|
+
cdef double y = (<RealDoubleElement>right)._value
|
|
1773
|
+
if op == Py_LT:
|
|
1774
|
+
return x < y
|
|
1775
|
+
elif op == Py_LE:
|
|
1776
|
+
return x <= y
|
|
1777
|
+
elif op == Py_EQ:
|
|
1778
|
+
return x == y
|
|
1779
|
+
elif op == Py_NE:
|
|
1780
|
+
return x != y
|
|
1781
|
+
elif op == Py_GT:
|
|
1782
|
+
return x > y
|
|
1783
|
+
else:
|
|
1784
|
+
return x >= y
|
|
1785
|
+
|
|
1786
|
+
############################
|
|
1787
|
+
# Special Functions
|
|
1788
|
+
############################
|
|
1789
|
+
|
|
1790
|
+
def NaN(self):
|
|
1791
|
+
"""
|
|
1792
|
+
Return Not-a-Number ``NaN``.
|
|
1793
|
+
|
|
1794
|
+
EXAMPLES::
|
|
1795
|
+
|
|
1796
|
+
sage: RDF.NaN()
|
|
1797
|
+
NaN
|
|
1798
|
+
"""
|
|
1799
|
+
return self(0)/self(0)
|
|
1800
|
+
|
|
1801
|
+
nan = NaN
|
|
1802
|
+
|
|
1803
|
+
def sqrt(self, extend=True, all=False):
|
|
1804
|
+
"""
|
|
1805
|
+
The square root function.
|
|
1806
|
+
|
|
1807
|
+
INPUT:
|
|
1808
|
+
|
|
1809
|
+
- ``extend`` -- boolean (default: ``True``); if ``True``, return a
|
|
1810
|
+
square root in a complex field if necessary if ``self`` is negative.
|
|
1811
|
+
Otherwise raise a :exc:`ValueError`.
|
|
1812
|
+
|
|
1813
|
+
- ``all`` -- boolean (default: ``False``); if ``True``, return a
|
|
1814
|
+
list of all square roots
|
|
1815
|
+
|
|
1816
|
+
EXAMPLES::
|
|
1817
|
+
|
|
1818
|
+
sage: r = RDF(4.0)
|
|
1819
|
+
sage: r.sqrt()
|
|
1820
|
+
2.0
|
|
1821
|
+
sage: r.sqrt()^2 == r
|
|
1822
|
+
True
|
|
1823
|
+
|
|
1824
|
+
::
|
|
1825
|
+
|
|
1826
|
+
sage: r = RDF(4344)
|
|
1827
|
+
sage: r.sqrt()
|
|
1828
|
+
65.90902821313632
|
|
1829
|
+
sage: r.sqrt()^2 - r
|
|
1830
|
+
0.0
|
|
1831
|
+
|
|
1832
|
+
::
|
|
1833
|
+
|
|
1834
|
+
sage: r = RDF(-2.0)
|
|
1835
|
+
sage: r.sqrt() # needs sage.rings.complex_double
|
|
1836
|
+
1.4142135623730951*I
|
|
1837
|
+
|
|
1838
|
+
::
|
|
1839
|
+
|
|
1840
|
+
sage: RDF(2).sqrt(all=True)
|
|
1841
|
+
[1.4142135623730951, -1.4142135623730951]
|
|
1842
|
+
sage: RDF(0).sqrt(all=True)
|
|
1843
|
+
[0.0]
|
|
1844
|
+
sage: RDF(-2).sqrt(all=True) # needs sage.rings.complex_double
|
|
1845
|
+
[1.4142135623730951*I, -1.4142135623730951*I]
|
|
1846
|
+
"""
|
|
1847
|
+
if self._value >= 0:
|
|
1848
|
+
x = self._new_c(libc.math.sqrt(self._value))
|
|
1849
|
+
if all:
|
|
1850
|
+
if x.is_zero():
|
|
1851
|
+
return [x]
|
|
1852
|
+
else:
|
|
1853
|
+
return [x, -x]
|
|
1854
|
+
else:
|
|
1855
|
+
return x
|
|
1856
|
+
if not extend:
|
|
1857
|
+
raise ValueError("negative number %s does not have a square root in the real field" % self)
|
|
1858
|
+
import sage.rings.complex_double
|
|
1859
|
+
return self._complex_double_(sage.rings.complex_double.CDF).sqrt(all=all)
|
|
1860
|
+
|
|
1861
|
+
def is_square(self):
|
|
1862
|
+
"""
|
|
1863
|
+
Return whether or not this number is a square in this field. For
|
|
1864
|
+
the real numbers, this is ``True`` if and only if ``self`` is
|
|
1865
|
+
nonnegative.
|
|
1866
|
+
|
|
1867
|
+
EXAMPLES::
|
|
1868
|
+
|
|
1869
|
+
sage: RDF(3.5).is_square()
|
|
1870
|
+
True
|
|
1871
|
+
sage: RDF(0).is_square()
|
|
1872
|
+
True
|
|
1873
|
+
sage: RDF(-4).is_square()
|
|
1874
|
+
False
|
|
1875
|
+
"""
|
|
1876
|
+
return self._value >= 0
|
|
1877
|
+
|
|
1878
|
+
def is_integer(self):
|
|
1879
|
+
"""
|
|
1880
|
+
Return ``True`` if this number is a integer.
|
|
1881
|
+
|
|
1882
|
+
EXAMPLES::
|
|
1883
|
+
|
|
1884
|
+
sage: RDF(3.5).is_integer()
|
|
1885
|
+
False
|
|
1886
|
+
sage: RDF(3).is_integer()
|
|
1887
|
+
True
|
|
1888
|
+
"""
|
|
1889
|
+
return self._value in ZZ
|
|
1890
|
+
|
|
1891
|
+
def cube_root(self):
|
|
1892
|
+
"""
|
|
1893
|
+
Return the cubic root (defined over the real numbers) of ``self``.
|
|
1894
|
+
|
|
1895
|
+
EXAMPLES::
|
|
1896
|
+
|
|
1897
|
+
sage: r = RDF(125.0); r.cube_root()
|
|
1898
|
+
5.000000000000001
|
|
1899
|
+
sage: r = RDF(-119.0)
|
|
1900
|
+
sage: r.cube_root()^3 - r # rel tol 1
|
|
1901
|
+
-1.4210854715202004e-14
|
|
1902
|
+
"""
|
|
1903
|
+
return self.nth_root(3)
|
|
1904
|
+
|
|
1905
|
+
def agm(self, other):
|
|
1906
|
+
r"""
|
|
1907
|
+
Return the arithmetic-geometric mean of ``self`` and ``other``. The
|
|
1908
|
+
arithmetic-geometric mean is the common limit of the sequences
|
|
1909
|
+
`u_n` and `v_n`, where `u_0` is ``self``,
|
|
1910
|
+
`v_0` is other, `u_{n+1}` is the arithmetic mean
|
|
1911
|
+
of `u_n` and `v_n`, and `v_{n+1}` is the
|
|
1912
|
+
geometric mean of `u_n` and `v_n`. If any operand is negative, the
|
|
1913
|
+
return value is ``NaN``.
|
|
1914
|
+
|
|
1915
|
+
EXAMPLES::
|
|
1916
|
+
|
|
1917
|
+
sage: a = RDF(1.5)
|
|
1918
|
+
sage: b = RDF(2.3)
|
|
1919
|
+
sage: a.agm(b)
|
|
1920
|
+
1.8786484558146697
|
|
1921
|
+
|
|
1922
|
+
The arithmetic-geometric mean always lies between the geometric and
|
|
1923
|
+
arithmetic mean::
|
|
1924
|
+
|
|
1925
|
+
sage: sqrt(a*b) < a.agm(b) < (a+b)/2
|
|
1926
|
+
True
|
|
1927
|
+
"""
|
|
1928
|
+
cdef double a = self._value
|
|
1929
|
+
cdef double b = other
|
|
1930
|
+
cdef double eps = 2.0**-51
|
|
1931
|
+
if a < 0 or b < 0:
|
|
1932
|
+
return self._parent.nan()
|
|
1933
|
+
while True:
|
|
1934
|
+
a1 = (a+b)/2
|
|
1935
|
+
b1 = libc.math.sqrt(a*b)
|
|
1936
|
+
if abs((b1/a1)-1) < eps:
|
|
1937
|
+
return self._new_c(a1)
|
|
1938
|
+
a, b = a1, b1
|
|
1939
|
+
|
|
1940
|
+
def algebraic_dependency(self, n):
|
|
1941
|
+
"""
|
|
1942
|
+
Return a polynomial of degree at most `n` which is
|
|
1943
|
+
approximately satisfied by this number.
|
|
1944
|
+
|
|
1945
|
+
.. NOTE::
|
|
1946
|
+
|
|
1947
|
+
The resulting polynomial need not be irreducible, and indeed
|
|
1948
|
+
usually won't be if this number is a good approximation to an
|
|
1949
|
+
algebraic number of degree less than `n`.
|
|
1950
|
+
|
|
1951
|
+
ALGORITHM:
|
|
1952
|
+
|
|
1953
|
+
Uses the PARI C-library :pari:`algdep` command.
|
|
1954
|
+
|
|
1955
|
+
EXAMPLES::
|
|
1956
|
+
|
|
1957
|
+
sage: r = sqrt(RDF(2)); r
|
|
1958
|
+
1.4142135623730951
|
|
1959
|
+
sage: r.algebraic_dependency(5) # needs sage.libs.pari
|
|
1960
|
+
x^2 - 2
|
|
1961
|
+
"""
|
|
1962
|
+
return sage.arith.misc.algebraic_dependency(self, n)
|
|
1963
|
+
|
|
1964
|
+
algdep = algebraic_dependency
|
|
1965
|
+
|
|
1966
|
+
cdef class ToRDF(Morphism):
|
|
1967
|
+
def __init__(self, R):
|
|
1968
|
+
"""
|
|
1969
|
+
Fast morphism from anything with a ``__float__`` method to an ``RDF``
|
|
1970
|
+
element.
|
|
1971
|
+
|
|
1972
|
+
EXAMPLES::
|
|
1973
|
+
|
|
1974
|
+
sage: f = RDF.coerce_map_from(ZZ); f
|
|
1975
|
+
Native morphism:
|
|
1976
|
+
From: Integer Ring
|
|
1977
|
+
To: Real Double Field
|
|
1978
|
+
sage: f(4)
|
|
1979
|
+
4.0
|
|
1980
|
+
sage: f = RDF.coerce_map_from(QQ); f
|
|
1981
|
+
Native morphism:
|
|
1982
|
+
From: Rational Field
|
|
1983
|
+
To: Real Double Field
|
|
1984
|
+
sage: f(1/2)
|
|
1985
|
+
0.5
|
|
1986
|
+
sage: f = RDF.coerce_map_from(int); f
|
|
1987
|
+
Native morphism:
|
|
1988
|
+
From: Set of Python objects of class 'int'
|
|
1989
|
+
To: Real Double Field
|
|
1990
|
+
sage: f(3r)
|
|
1991
|
+
3.0
|
|
1992
|
+
sage: f = RDF.coerce_map_from(float); f
|
|
1993
|
+
Native morphism:
|
|
1994
|
+
From: Set of Python objects of class 'float'
|
|
1995
|
+
To: Real Double Field
|
|
1996
|
+
sage: f(3.5)
|
|
1997
|
+
3.5
|
|
1998
|
+
"""
|
|
1999
|
+
from sage.categories.homset import Hom
|
|
2000
|
+
if isinstance(R, type):
|
|
2001
|
+
from sage.sets.pythonclass import Set_PythonType
|
|
2002
|
+
R = Set_PythonType(R)
|
|
2003
|
+
Morphism.__init__(self, Hom(R, RDF))
|
|
2004
|
+
|
|
2005
|
+
cpdef Element _call_(self, x):
|
|
2006
|
+
"""
|
|
2007
|
+
Send ``x`` to the image under this map.
|
|
2008
|
+
|
|
2009
|
+
EXAMPLES::
|
|
2010
|
+
|
|
2011
|
+
sage: f = RDF.coerce_map_from(float)
|
|
2012
|
+
sage: f(3.5) # indirect doctest
|
|
2013
|
+
3.5
|
|
2014
|
+
"""
|
|
2015
|
+
cdef RealDoubleElement r = <RealDoubleElement>PY_NEW(RealDoubleElement)
|
|
2016
|
+
r._value = PyFloat_AsDouble(x)
|
|
2017
|
+
return r
|
|
2018
|
+
|
|
2019
|
+
def _repr_type(self):
|
|
2020
|
+
"""
|
|
2021
|
+
Return the representation type of ``self``.
|
|
2022
|
+
|
|
2023
|
+
EXAMPLES::
|
|
2024
|
+
|
|
2025
|
+
sage: RDF.coerce_map_from(float)._repr_type()
|
|
2026
|
+
'Native'
|
|
2027
|
+
"""
|
|
2028
|
+
return "Native"
|
|
2029
|
+
|
|
2030
|
+
|
|
2031
|
+
#####################################################
|
|
2032
|
+
# unique objects
|
|
2033
|
+
#####################################################
|
|
2034
|
+
cdef RealDoubleField_class _RDF
|
|
2035
|
+
_RDF = RealDoubleField_class()
|
|
2036
|
+
|
|
2037
|
+
RDF = _RDF # external interface
|
|
2038
|
+
|
|
2039
|
+
|
|
2040
|
+
def RealDoubleField():
|
|
2041
|
+
"""
|
|
2042
|
+
Return the unique instance of the
|
|
2043
|
+
:class:`real double field<RealDoubleField_class>`.
|
|
2044
|
+
|
|
2045
|
+
EXAMPLES::
|
|
2046
|
+
|
|
2047
|
+
sage: RealDoubleField() is RealDoubleField()
|
|
2048
|
+
True
|
|
2049
|
+
"""
|
|
2050
|
+
global _RDF
|
|
2051
|
+
return _RDF
|
|
2052
|
+
|
|
2053
|
+
|
|
2054
|
+
def is_RealDoubleElement(x):
|
|
2055
|
+
"""
|
|
2056
|
+
Check if ``x`` is an element of the real double field.
|
|
2057
|
+
|
|
2058
|
+
EXAMPLES::
|
|
2059
|
+
|
|
2060
|
+
sage: from sage.rings.real_double import is_RealDoubleElement
|
|
2061
|
+
sage: is_RealDoubleElement(RDF(3))
|
|
2062
|
+
doctest:warning...
|
|
2063
|
+
DeprecationWarning: The function is_RealDoubleElement is deprecated;
|
|
2064
|
+
use 'isinstance(..., RealDoubleElement)' instead.
|
|
2065
|
+
See https://github.com/sagemath/sage/issues/38128 for details.
|
|
2066
|
+
True
|
|
2067
|
+
sage: is_RealDoubleElement(RIF(3)) # needs sage.rings.real_interval_field
|
|
2068
|
+
False
|
|
2069
|
+
"""
|
|
2070
|
+
from sage.misc.superseded import deprecation_cython
|
|
2071
|
+
deprecation_cython(38128,
|
|
2072
|
+
"The function is_RealDoubleElement is deprecated; "
|
|
2073
|
+
"use 'isinstance(..., RealDoubleElement)' instead.")
|
|
2074
|
+
return isinstance(x, RealDoubleElement)
|
|
2075
|
+
|
|
2076
|
+
|
|
2077
|
+
# ################ FAST CREATION CODE ######################
|
|
2078
|
+
# Based on fast integer creation code
|
|
2079
|
+
# There is nothing to see here, move along
|
|
2080
|
+
|
|
2081
|
+
# We use a global element to steal all the references
|
|
2082
|
+
# from. DO NOT INITIALIZE IT AGAIN and DO NOT REFERENCE IT!
|
|
2083
|
+
cdef RealDoubleElement global_dummy_element
|
|
2084
|
+
|
|
2085
|
+
try:
|
|
2086
|
+
from sage.rings.real_double_element_gsl import RealDoubleElement_gsl
|
|
2087
|
+
except ImportError:
|
|
2088
|
+
global_dummy_element = RealDoubleElement(0)
|
|
2089
|
+
else:
|
|
2090
|
+
global_dummy_element = RealDoubleElement_gsl(0)
|
|
2091
|
+
|
|
2092
|
+
# A global pool for performance when elements are rapidly created and destroyed.
|
|
2093
|
+
# It operates on the following principles:
|
|
2094
|
+
#
|
|
2095
|
+
# - The pool starts out empty.
|
|
2096
|
+
# - When a new element is needed, one from the pool is returned
|
|
2097
|
+
# if available, otherwise a new RealDoubleElement object is created
|
|
2098
|
+
# - When an element is collected, it will add it to the pool
|
|
2099
|
+
# if there is room, otherwise it will be deallocated.
|
|
2100
|
+
DEF element_pool_size = 50
|
|
2101
|
+
|
|
2102
|
+
cdef PyObject* element_pool[element_pool_size]
|
|
2103
|
+
cdef int element_pool_count = 0
|
|
2104
|
+
|
|
2105
|
+
# used for profiling the pool
|
|
2106
|
+
cdef int total_alloc = 0
|
|
2107
|
+
cdef int use_pool = 0
|
|
2108
|
+
|
|
2109
|
+
|
|
2110
|
+
cdef PyObject* fast_tp_new(type t, args, kwds) noexcept:
|
|
2111
|
+
global element_pool, element_pool_count, total_alloc, use_pool
|
|
2112
|
+
|
|
2113
|
+
cdef PyObject* new
|
|
2114
|
+
|
|
2115
|
+
# for profiling pool usage
|
|
2116
|
+
# total_alloc += 1
|
|
2117
|
+
|
|
2118
|
+
# If there is a ready real double in the pool, we will
|
|
2119
|
+
# decrement the counter and return that.
|
|
2120
|
+
|
|
2121
|
+
if element_pool_count > 0:
|
|
2122
|
+
|
|
2123
|
+
# for profiling pool usage
|
|
2124
|
+
# use_pool += 1
|
|
2125
|
+
|
|
2126
|
+
element_pool_count -= 1
|
|
2127
|
+
new = <PyObject *> element_pool[element_pool_count]
|
|
2128
|
+
|
|
2129
|
+
# Otherwise, we have to create one.
|
|
2130
|
+
|
|
2131
|
+
else:
|
|
2132
|
+
|
|
2133
|
+
# allocate enough room for the RealDoubleElement,
|
|
2134
|
+
# sizeof_RealDoubleElement is sizeof(RealDoubleElement).
|
|
2135
|
+
# The use of PyObject_Malloc directly assumes
|
|
2136
|
+
# that RealDoubleElements are not garbage collected, i.e.
|
|
2137
|
+
# they do not possess references to other Python
|
|
2138
|
+
# objects (As indicated by the Py_TPFLAGS_HAVE_GC flag).
|
|
2139
|
+
# See below for a more detailed description.
|
|
2140
|
+
|
|
2141
|
+
new = <PyObject*>PyObject_Malloc(sizeof(RealDoubleElement))
|
|
2142
|
+
|
|
2143
|
+
# Now set every member as set in z, the global dummy RealDoubleElement
|
|
2144
|
+
# created before this tp_new started to operate.
|
|
2145
|
+
|
|
2146
|
+
memcpy(new, (<void*>global_dummy_element), sizeof(RealDoubleElement))
|
|
2147
|
+
|
|
2148
|
+
# This line is only needed if Python is compiled in debugging mode
|
|
2149
|
+
# './configure --with-pydebug' or SAGE_DEBUG=yes. If that is the
|
|
2150
|
+
# case a Python object has a bunch of debugging fields which are
|
|
2151
|
+
# initialized with this macro.
|
|
2152
|
+
if_Py_TRACE_REFS_then_PyObject_INIT(
|
|
2153
|
+
new, Py_TYPE(global_dummy_element))
|
|
2154
|
+
|
|
2155
|
+
# The global_dummy_element may have a reference count larger than
|
|
2156
|
+
# one, but it is expected that newly created objects have a
|
|
2157
|
+
# reference count of one. This is potentially unneeded if
|
|
2158
|
+
# everybody plays nice, because the global_dummy_element has only
|
|
2159
|
+
# one reference in that case.
|
|
2160
|
+
|
|
2161
|
+
# Objects from the pool have reference count zero, so this
|
|
2162
|
+
# needs to be set in this case.
|
|
2163
|
+
|
|
2164
|
+
Py_SET_REFCNT(<PyObject*>new, 1)
|
|
2165
|
+
|
|
2166
|
+
return new
|
|
2167
|
+
|
|
2168
|
+
cdef void fast_tp_dealloc(PyObject* o) noexcept:
|
|
2169
|
+
|
|
2170
|
+
# If there is room in the pool for a used integer object,
|
|
2171
|
+
# then put it in rather than deallocating it.
|
|
2172
|
+
|
|
2173
|
+
global element_pool, element_pool_count
|
|
2174
|
+
|
|
2175
|
+
if element_pool_count < element_pool_size:
|
|
2176
|
+
|
|
2177
|
+
# And add it to the pool.
|
|
2178
|
+
element_pool[element_pool_count] = o
|
|
2179
|
+
element_pool_count += 1
|
|
2180
|
+
return
|
|
2181
|
+
|
|
2182
|
+
# Free the object. This assumes that Py_TPFLAGS_HAVE_GC is not
|
|
2183
|
+
# set. If it was set another free function would need to be
|
|
2184
|
+
# called.
|
|
2185
|
+
|
|
2186
|
+
PyObject_Free(o)
|
|
2187
|
+
|
|
2188
|
+
|
|
2189
|
+
from sage.misc.allocator cimport hook_tp_functions, hook_tp_functions_type
|
|
2190
|
+
hook_tp_functions(global_dummy_element, <newfunc>(&fast_tp_new), <destructor>(&fast_tp_dealloc), False)
|
|
2191
|
+
try:
|
|
2192
|
+
from sage.rings.real_double_element_gsl import RealDoubleElement_gsl
|
|
2193
|
+
except Exception:
|
|
2194
|
+
pass
|
|
2195
|
+
else:
|
|
2196
|
+
# global_dummy_element is of type RealDoubleElement_gsl,
|
|
2197
|
+
# so hook the base class now.
|
|
2198
|
+
hook_tp_functions_type(RealDoubleElement, <newfunc>(&fast_tp_new), <destructor>(&fast_tp_dealloc), False)
|
|
2199
|
+
# From here on, calling PY_NEW(RealDoubleElement) actually creates an instance of RealDoubleElement_gsl
|
|
2200
|
+
|
|
2201
|
+
|
|
2202
|
+
cdef double_repr(double x):
|
|
2203
|
+
"""
|
|
2204
|
+
Convert a double to a string with maximum precision.
|
|
2205
|
+
"""
|
|
2206
|
+
if libc.math.isfinite(x):
|
|
2207
|
+
return repr(x)
|
|
2208
|
+
if libc.math.isinf(x):
|
|
2209
|
+
if x > 0:
|
|
2210
|
+
return "+infinity"
|
|
2211
|
+
if x < 0:
|
|
2212
|
+
return "-infinity"
|
|
2213
|
+
return "NaN"
|
|
2214
|
+
|
|
2215
|
+
|
|
2216
|
+
# Support Python's numbers abstract base class
|
|
2217
|
+
import numbers
|
|
2218
|
+
numbers.Real.register(RealDoubleElement)
|