passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_categories-10.6.32.dist-info/METADATA +156 -0
- passagemath_categories-10.6.32.dist-info/RECORD +719 -0
- passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
- passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_categories.py +28 -0
- sage/arith/all.py +38 -0
- sage/arith/constants.pxd +27 -0
- sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/functions.pxd +4 -0
- sage/arith/functions.pyx +221 -0
- sage/arith/misc.py +6552 -0
- sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/multi_modular.pxd +39 -0
- sage/arith/multi_modular.pyx +994 -0
- sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/rational_reconstruction.pxd +4 -0
- sage/arith/rational_reconstruction.pyx +115 -0
- sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/arith/srange.pyx +571 -0
- sage/calculus/all__sagemath_categories.py +2 -0
- sage/calculus/functional.py +481 -0
- sage/calculus/functions.py +151 -0
- sage/categories/additive_groups.py +73 -0
- sage/categories/additive_magmas.py +1044 -0
- sage/categories/additive_monoids.py +114 -0
- sage/categories/additive_semigroups.py +184 -0
- sage/categories/affine_weyl_groups.py +238 -0
- sage/categories/algebra_ideals.py +95 -0
- sage/categories/algebra_modules.py +96 -0
- sage/categories/algebras.py +349 -0
- sage/categories/algebras_with_basis.py +377 -0
- sage/categories/all.py +160 -0
- sage/categories/aperiodic_semigroups.py +29 -0
- sage/categories/associative_algebras.py +47 -0
- sage/categories/bialgebras.py +101 -0
- sage/categories/bialgebras_with_basis.py +414 -0
- sage/categories/bimodules.py +206 -0
- sage/categories/chain_complexes.py +268 -0
- sage/categories/classical_crystals.py +480 -0
- sage/categories/coalgebras.py +405 -0
- sage/categories/coalgebras_with_basis.py +232 -0
- sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/coercion_methods.pyx +52 -0
- sage/categories/commutative_additive_groups.py +104 -0
- sage/categories/commutative_additive_monoids.py +45 -0
- sage/categories/commutative_additive_semigroups.py +48 -0
- sage/categories/commutative_algebra_ideals.py +87 -0
- sage/categories/commutative_algebras.py +94 -0
- sage/categories/commutative_ring_ideals.py +58 -0
- sage/categories/commutative_rings.py +736 -0
- sage/categories/complete_discrete_valuation.py +293 -0
- sage/categories/complex_reflection_groups.py +145 -0
- sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
- sage/categories/coxeter_group_algebras.py +186 -0
- sage/categories/coxeter_groups.py +3402 -0
- sage/categories/crystals.py +2628 -0
- sage/categories/cw_complexes.py +216 -0
- sage/categories/dedekind_domains.py +137 -0
- sage/categories/discrete_valuation.py +325 -0
- sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
- sage/categories/division_rings.py +114 -0
- sage/categories/domains.py +95 -0
- sage/categories/drinfeld_modules.py +789 -0
- sage/categories/dual.py +42 -0
- sage/categories/enumerated_sets.py +1146 -0
- sage/categories/euclidean_domains.py +271 -0
- sage/categories/examples/algebras_with_basis.py +102 -0
- sage/categories/examples/all.py +1 -0
- sage/categories/examples/commutative_additive_monoids.py +130 -0
- sage/categories/examples/commutative_additive_semigroups.py +199 -0
- sage/categories/examples/coxeter_groups.py +8 -0
- sage/categories/examples/crystals.py +236 -0
- sage/categories/examples/cw_complexes.py +163 -0
- sage/categories/examples/facade_sets.py +187 -0
- sage/categories/examples/filtered_algebras_with_basis.py +204 -0
- sage/categories/examples/filtered_modules_with_basis.py +154 -0
- sage/categories/examples/finite_coxeter_groups.py +252 -0
- sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
- sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
- sage/categories/examples/finite_enumerated_sets.py +208 -0
- sage/categories/examples/finite_monoids.py +150 -0
- sage/categories/examples/finite_semigroups.py +190 -0
- sage/categories/examples/finite_weyl_groups.py +191 -0
- sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
- sage/categories/examples/graded_modules_with_basis.py +168 -0
- sage/categories/examples/graphs.py +122 -0
- sage/categories/examples/hopf_algebras_with_basis.py +145 -0
- sage/categories/examples/infinite_enumerated_sets.py +190 -0
- sage/categories/examples/lie_algebras.py +352 -0
- sage/categories/examples/lie_algebras_with_basis.py +196 -0
- sage/categories/examples/magmas.py +162 -0
- sage/categories/examples/manifolds.py +94 -0
- sage/categories/examples/monoids.py +144 -0
- sage/categories/examples/posets.py +178 -0
- sage/categories/examples/semigroups.py +580 -0
- sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/categories/examples/semigroups_cython.pyx +221 -0
- sage/categories/examples/semirings.py +249 -0
- sage/categories/examples/sets_cat.py +706 -0
- sage/categories/examples/sets_with_grading.py +101 -0
- sage/categories/examples/with_realizations.py +542 -0
- sage/categories/fields.py +991 -0
- sage/categories/filtered_algebras.py +63 -0
- sage/categories/filtered_algebras_with_basis.py +548 -0
- sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
- sage/categories/filtered_modules.py +210 -0
- sage/categories/filtered_modules_with_basis.py +1209 -0
- sage/categories/finite_complex_reflection_groups.py +1506 -0
- sage/categories/finite_coxeter_groups.py +1138 -0
- sage/categories/finite_crystals.py +103 -0
- sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
- sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
- sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
- sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
- sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
- sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
- sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
- sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
- sage/categories/finite_enumerated_sets.py +769 -0
- sage/categories/finite_fields.py +252 -0
- sage/categories/finite_groups.py +256 -0
- sage/categories/finite_lattice_posets.py +242 -0
- sage/categories/finite_monoids.py +316 -0
- sage/categories/finite_permutation_groups.py +339 -0
- sage/categories/finite_posets.py +1994 -0
- sage/categories/finite_semigroups.py +136 -0
- sage/categories/finite_sets.py +93 -0
- sage/categories/finite_weyl_groups.py +39 -0
- sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
- sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
- sage/categories/finitely_generated_magmas.py +57 -0
- sage/categories/finitely_generated_semigroups.py +214 -0
- sage/categories/function_fields.py +76 -0
- sage/categories/g_sets.py +77 -0
- sage/categories/gcd_domains.py +65 -0
- sage/categories/generalized_coxeter_groups.py +94 -0
- sage/categories/graded_algebras.py +85 -0
- sage/categories/graded_algebras_with_basis.py +258 -0
- sage/categories/graded_bialgebras.py +32 -0
- sage/categories/graded_bialgebras_with_basis.py +32 -0
- sage/categories/graded_coalgebras.py +65 -0
- sage/categories/graded_coalgebras_with_basis.py +51 -0
- sage/categories/graded_hopf_algebras.py +41 -0
- sage/categories/graded_hopf_algebras_with_basis.py +169 -0
- sage/categories/graded_lie_algebras.py +91 -0
- sage/categories/graded_lie_algebras_with_basis.py +44 -0
- sage/categories/graded_lie_conformal_algebras.py +74 -0
- sage/categories/graded_modules.py +133 -0
- sage/categories/graded_modules_with_basis.py +329 -0
- sage/categories/graphs.py +138 -0
- sage/categories/group_algebras.py +430 -0
- sage/categories/groupoid.py +94 -0
- sage/categories/groups.py +667 -0
- sage/categories/h_trivial_semigroups.py +64 -0
- sage/categories/hecke_modules.py +185 -0
- sage/categories/highest_weight_crystals.py +980 -0
- sage/categories/hopf_algebras.py +219 -0
- sage/categories/hopf_algebras_with_basis.py +309 -0
- sage/categories/infinite_enumerated_sets.py +115 -0
- sage/categories/integral_domains.py +203 -0
- sage/categories/j_trivial_semigroups.py +29 -0
- sage/categories/kac_moody_algebras.py +82 -0
- sage/categories/kahler_algebras.py +203 -0
- sage/categories/l_trivial_semigroups.py +63 -0
- sage/categories/lambda_bracket_algebras.py +280 -0
- sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
- sage/categories/lattice_posets.py +89 -0
- sage/categories/left_modules.py +49 -0
- sage/categories/lie_algebras.py +1070 -0
- sage/categories/lie_algebras_with_basis.py +261 -0
- sage/categories/lie_conformal_algebras.py +350 -0
- sage/categories/lie_conformal_algebras_with_basis.py +147 -0
- sage/categories/lie_groups.py +73 -0
- sage/categories/loop_crystals.py +1290 -0
- sage/categories/magmas.py +1189 -0
- sage/categories/magmas_and_additive_magmas.py +149 -0
- sage/categories/magmatic_algebras.py +365 -0
- sage/categories/manifolds.py +352 -0
- sage/categories/matrix_algebras.py +40 -0
- sage/categories/metric_spaces.py +387 -0
- sage/categories/modular_abelian_varieties.py +78 -0
- sage/categories/modules.py +989 -0
- sage/categories/modules_with_basis.py +2794 -0
- sage/categories/monoid_algebras.py +38 -0
- sage/categories/monoids.py +739 -0
- sage/categories/noetherian_rings.py +87 -0
- sage/categories/number_fields.py +242 -0
- sage/categories/ore_modules.py +189 -0
- sage/categories/partially_ordered_monoids.py +49 -0
- sage/categories/permutation_groups.py +63 -0
- sage/categories/pointed_sets.py +42 -0
- sage/categories/polyhedra.py +74 -0
- sage/categories/poor_man_map.py +270 -0
- sage/categories/posets.py +722 -0
- sage/categories/principal_ideal_domains.py +270 -0
- sage/categories/quantum_group_representations.py +543 -0
- sage/categories/quotient_fields.py +728 -0
- sage/categories/r_trivial_semigroups.py +45 -0
- sage/categories/regular_crystals.py +898 -0
- sage/categories/regular_supercrystals.py +170 -0
- sage/categories/right_modules.py +49 -0
- sage/categories/ring_ideals.py +74 -0
- sage/categories/rings.py +1904 -0
- sage/categories/rngs.py +175 -0
- sage/categories/schemes.py +393 -0
- sage/categories/semigroups.py +1060 -0
- sage/categories/semirings.py +71 -0
- sage/categories/semisimple_algebras.py +114 -0
- sage/categories/sets_with_grading.py +235 -0
- sage/categories/shephard_groups.py +43 -0
- sage/categories/signed_tensor.py +120 -0
- sage/categories/simplicial_complexes.py +134 -0
- sage/categories/simplicial_sets.py +1206 -0
- sage/categories/super_algebras.py +149 -0
- sage/categories/super_algebras_with_basis.py +144 -0
- sage/categories/super_hopf_algebras_with_basis.py +126 -0
- sage/categories/super_lie_conformal_algebras.py +193 -0
- sage/categories/super_modules.py +229 -0
- sage/categories/super_modules_with_basis.py +193 -0
- sage/categories/supercommutative_algebras.py +99 -0
- sage/categories/supercrystals.py +406 -0
- sage/categories/tensor.py +110 -0
- sage/categories/topological_spaces.py +170 -0
- sage/categories/triangular_kac_moody_algebras.py +439 -0
- sage/categories/tutorial.py +58 -0
- sage/categories/unique_factorization_domains.py +318 -0
- sage/categories/unital_algebras.py +426 -0
- sage/categories/vector_bundles.py +159 -0
- sage/categories/vector_spaces.py +357 -0
- sage/categories/weyl_groups.py +853 -0
- sage/combinat/all__sagemath_categories.py +34 -0
- sage/combinat/backtrack.py +180 -0
- sage/combinat/combinat.py +2269 -0
- sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/combinat_cython.pxd +6 -0
- sage/combinat/combinat_cython.pyx +390 -0
- sage/combinat/combination.py +796 -0
- sage/combinat/combinatorial_map.py +416 -0
- sage/combinat/composition.py +2192 -0
- sage/combinat/dlx.py +510 -0
- sage/combinat/integer_lists/__init__.py +7 -0
- sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/base.pxd +16 -0
- sage/combinat/integer_lists/base.pyx +713 -0
- sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/integer_lists/invlex.pxd +4 -0
- sage/combinat/integer_lists/invlex.pyx +1650 -0
- sage/combinat/integer_lists/lists.py +328 -0
- sage/combinat/integer_lists/nn.py +48 -0
- sage/combinat/integer_vector.py +1818 -0
- sage/combinat/integer_vector_weighted.py +413 -0
- sage/combinat/matrices/all__sagemath_categories.py +5 -0
- sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/matrices/dancing_links.pyx +1159 -0
- sage/combinat/matrices/dancing_links_c.h +380 -0
- sage/combinat/matrices/dlxcpp.py +136 -0
- sage/combinat/partition.py +10070 -0
- sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/partitions.pyx +743 -0
- sage/combinat/permutation.py +10168 -0
- sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/combinat/permutation_cython.pxd +11 -0
- sage/combinat/permutation_cython.pyx +407 -0
- sage/combinat/q_analogues.py +1090 -0
- sage/combinat/ranker.py +268 -0
- sage/combinat/subset.py +1561 -0
- sage/combinat/subsets_hereditary.py +202 -0
- sage/combinat/subsets_pairwise.py +184 -0
- sage/combinat/tools.py +63 -0
- sage/combinat/tuple.py +348 -0
- sage/data_structures/all.py +2 -0
- sage/data_structures/all__sagemath_categories.py +2 -0
- sage/data_structures/binary_matrix.pxd +138 -0
- sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/binary_search.pxd +3 -0
- sage/data_structures/binary_search.pyx +66 -0
- sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset.pxd +40 -0
- sage/data_structures/bitset.pyx +2385 -0
- sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/bitset_base.pxd +926 -0
- sage/data_structures/bitset_base.pyx +117 -0
- sage/data_structures/bitset_intrinsics.h +487 -0
- sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/blas_dict.pxd +12 -0
- sage/data_structures/blas_dict.pyx +469 -0
- sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/list_of_pairs.pxd +16 -0
- sage/data_structures/list_of_pairs.pyx +122 -0
- sage/data_structures/mutable_poset.py +3312 -0
- sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/data_structures/pairing_heap.h +346 -0
- sage/data_structures/pairing_heap.pxd +88 -0
- sage/data_structures/pairing_heap.pyx +1464 -0
- sage/data_structures/sparse_bitset.pxd +62 -0
- sage/data_structures/stream.py +5070 -0
- sage/databases/all__sagemath_categories.py +7 -0
- sage/databases/sql_db.py +2236 -0
- sage/ext/all__sagemath_categories.py +3 -0
- sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_callable.pxd +4 -0
- sage/ext/fast_callable.pyx +2746 -0
- sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/fast_eval.pxd +1 -0
- sage/ext/fast_eval.pyx +102 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_categories.py +2 -0
- sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_el.pxd +18 -0
- sage/ext/interpreters/wrapper_el.pyx +148 -0
- sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_py.pxd +17 -0
- sage/ext/interpreters/wrapper_py.pyx +133 -0
- sage/functions/airy.py +937 -0
- sage/functions/all.py +97 -0
- sage/functions/bessel.py +2102 -0
- sage/functions/error.py +784 -0
- sage/functions/exp_integral.py +1529 -0
- sage/functions/gamma.py +1087 -0
- sage/functions/generalized.py +672 -0
- sage/functions/hyperbolic.py +747 -0
- sage/functions/hypergeometric.py +1156 -0
- sage/functions/jacobi.py +1705 -0
- sage/functions/log.py +1402 -0
- sage/functions/min_max.py +338 -0
- sage/functions/orthogonal_polys.py +3106 -0
- sage/functions/other.py +2303 -0
- sage/functions/piecewise.py +1505 -0
- sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/functions/prime_pi.pyx +262 -0
- sage/functions/special.py +1212 -0
- sage/functions/spike_function.py +278 -0
- sage/functions/transcendental.py +690 -0
- sage/functions/trig.py +1062 -0
- sage/functions/wigner.py +726 -0
- sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/geometry/abc.pyx +82 -0
- sage/geometry/all__sagemath_categories.py +1 -0
- sage/groups/all__sagemath_categories.py +11 -0
- sage/groups/generic.py +1733 -0
- sage/groups/groups_catalog.py +113 -0
- sage/groups/perm_gps/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/all.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
- sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
- sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
- sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
- sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
- sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
- sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
- sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
- sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
- sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
- sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
- sage/interfaces/abc.py +140 -0
- sage/interfaces/all.py +58 -0
- sage/interfaces/all__sagemath_categories.py +1 -0
- sage/interfaces/expect.py +1643 -0
- sage/interfaces/interface.py +1682 -0
- sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/process.pxd +5 -0
- sage/interfaces/process.pyx +288 -0
- sage/interfaces/quit.py +167 -0
- sage/interfaces/sage0.py +604 -0
- sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/interfaces/sagespawn.pyx +308 -0
- sage/interfaces/tab_completion.py +101 -0
- sage/misc/all__sagemath_categories.py +78 -0
- sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/allocator.pxd +6 -0
- sage/misc/allocator.pyx +47 -0
- sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/binary_tree.pxd +29 -0
- sage/misc/binary_tree.pyx +537 -0
- sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/callable_dict.pyx +89 -0
- sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/citation.pyx +159 -0
- sage/misc/converting_dict.py +293 -0
- sage/misc/defaults.py +129 -0
- sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/derivative.pyx +223 -0
- sage/misc/functional.py +2005 -0
- sage/misc/html.py +589 -0
- sage/misc/latex.py +2673 -0
- sage/misc/latex_macros.py +236 -0
- sage/misc/latex_standalone.py +1833 -0
- sage/misc/map_threaded.py +38 -0
- sage/misc/mathml.py +76 -0
- sage/misc/method_decorator.py +88 -0
- sage/misc/mrange.py +755 -0
- sage/misc/multireplace.py +41 -0
- sage/misc/object_multiplexer.py +92 -0
- sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/parser.pyx +1107 -0
- sage/misc/random_testing.py +264 -0
- sage/misc/rest_index_of_methods.py +377 -0
- sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/search.pxd +2 -0
- sage/misc/search.pyx +68 -0
- sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/misc/stopgap.pyx +95 -0
- sage/misc/table.py +853 -0
- sage/monoids/all__sagemath_categories.py +1 -0
- sage/monoids/indexed_free_monoid.py +1071 -0
- sage/monoids/monoid.py +82 -0
- sage/numerical/all__sagemath_categories.py +1 -0
- sage/numerical/backends/all__sagemath_categories.py +1 -0
- sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_backend.pxd +61 -0
- sage/numerical/backends/generic_backend.pyx +1893 -0
- sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/numerical/backends/generic_sdp_backend.pxd +38 -0
- sage/numerical/backends/generic_sdp_backend.pyx +755 -0
- sage/parallel/all.py +6 -0
- sage/parallel/decorate.py +575 -0
- sage/parallel/map_reduce.py +1997 -0
- sage/parallel/multiprocessing_sage.py +76 -0
- sage/parallel/ncpus.py +35 -0
- sage/parallel/parallelism.py +364 -0
- sage/parallel/reference.py +47 -0
- sage/parallel/use_fork.py +333 -0
- sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/abc.pxd +31 -0
- sage/rings/abc.pyx +526 -0
- sage/rings/algebraic_closure_finite_field.py +1154 -0
- sage/rings/all__sagemath_categories.py +91 -0
- sage/rings/big_oh.py +227 -0
- sage/rings/continued_fraction.py +2754 -0
- sage/rings/continued_fraction_gosper.py +220 -0
- sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/factorint.pyx +295 -0
- sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fast_arith.pxd +21 -0
- sage/rings/fast_arith.pyx +535 -0
- sage/rings/finite_rings/all__sagemath_categories.py +9 -0
- sage/rings/finite_rings/conway_polynomials.py +542 -0
- sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_base.pxd +12 -0
- sage/rings/finite_rings/element_base.pyx +1176 -0
- sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/finite_field_base.pxd +7 -0
- sage/rings/finite_rings/finite_field_base.pyx +2171 -0
- sage/rings/finite_rings/finite_field_constructor.py +827 -0
- sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
- sage/rings/finite_rings/galois_group.py +154 -0
- sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field.pxd +23 -0
- sage/rings/finite_rings/hom_finite_field.pyx +856 -0
- sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
- sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
- sage/rings/finite_rings/homset.py +357 -0
- sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/integer_mod.pxd +56 -0
- sage/rings/finite_rings/integer_mod.pyx +4586 -0
- sage/rings/finite_rings/integer_mod_limits.h +11 -0
- sage/rings/finite_rings/integer_mod_ring.py +2044 -0
- sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field.pxd +30 -0
- sage/rings/finite_rings/residue_field.pyx +1811 -0
- sage/rings/finite_rings/stdint.pxd +19 -0
- sage/rings/fraction_field.py +1452 -0
- sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/fraction_field_element.pyx +1357 -0
- sage/rings/function_field/all.py +7 -0
- sage/rings/function_field/all__sagemath_categories.py +2 -0
- sage/rings/function_field/constructor.py +218 -0
- sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element.pxd +11 -0
- sage/rings/function_field/element.pyx +1008 -0
- sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/element_rational.pyx +513 -0
- sage/rings/function_field/extensions.py +230 -0
- sage/rings/function_field/function_field.py +1468 -0
- sage/rings/function_field/function_field_rational.py +1005 -0
- sage/rings/function_field/ideal.py +1155 -0
- sage/rings/function_field/ideal_rational.py +629 -0
- sage/rings/function_field/jacobian_base.py +826 -0
- sage/rings/function_field/jacobian_hess.py +1053 -0
- sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
- sage/rings/function_field/maps.py +1039 -0
- sage/rings/function_field/order.py +281 -0
- sage/rings/function_field/order_basis.py +586 -0
- sage/rings/function_field/order_rational.py +576 -0
- sage/rings/function_field/place.py +426 -0
- sage/rings/function_field/place_rational.py +181 -0
- sage/rings/generic.py +320 -0
- sage/rings/homset.py +332 -0
- sage/rings/ideal.py +1885 -0
- sage/rings/ideal_monoid.py +215 -0
- sage/rings/infinity.py +1890 -0
- sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer.pxd +45 -0
- sage/rings/integer.pyx +7874 -0
- sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/integer_ring.pxd +8 -0
- sage/rings/integer_ring.pyx +1693 -0
- sage/rings/laurent_series_ring.py +931 -0
- sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/laurent_series_ring_element.pxd +11 -0
- sage/rings/laurent_series_ring_element.pyx +1927 -0
- sage/rings/lazy_series.py +7815 -0
- sage/rings/lazy_series_ring.py +4356 -0
- sage/rings/localization.py +1043 -0
- sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/morphism.pxd +39 -0
- sage/rings/morphism.pyx +3299 -0
- sage/rings/multi_power_series_ring.py +1145 -0
- sage/rings/multi_power_series_ring_element.py +2184 -0
- sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/noncommutative_ideals.pyx +423 -0
- sage/rings/number_field/all__sagemath_categories.py +1 -0
- sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_base.pxd +8 -0
- sage/rings/number_field/number_field_base.pyx +507 -0
- sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/number_field/number_field_element_base.pxd +6 -0
- sage/rings/number_field/number_field_element_base.pyx +36 -0
- sage/rings/number_field/number_field_ideal.py +3550 -0
- sage/rings/padics/all__sagemath_categories.py +4 -0
- sage/rings/padics/local_generic.py +1670 -0
- sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/local_generic_element.pxd +5 -0
- sage/rings/padics/local_generic_element.pyx +1017 -0
- sage/rings/padics/misc.py +256 -0
- sage/rings/padics/padic_generic.py +1911 -0
- sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer.pxd +38 -0
- sage/rings/padics/pow_computer.pyx +671 -0
- sage/rings/padics/precision_error.py +24 -0
- sage/rings/polynomial/all__sagemath_categories.py +25 -0
- sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/commutative_polynomial.pxd +6 -0
- sage/rings/polynomial/commutative_polynomial.pyx +24 -0
- sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/cyclotomic.pyx +404 -0
- sage/rings/polynomial/flatten.py +711 -0
- sage/rings/polynomial/ideal.py +102 -0
- sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
- sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
- sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial.pxd +18 -0
- sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
- sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
- sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
- sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
- sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial.pxd +12 -0
- sage/rings/polynomial/multi_polynomial.pyx +3082 -0
- sage/rings/polynomial/multi_polynomial_element.py +2570 -0
- sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
- sage/rings/polynomial/multi_polynomial_ring.py +947 -0
- sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
- sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
- sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
- sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polydict.pxd +45 -0
- sage/rings/polynomial/polydict.pyx +2701 -0
- sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_compiled.pxd +59 -0
- sage/rings/polynomial/polynomial_compiled.pyx +509 -0
- sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_element.pxd +64 -0
- sage/rings/polynomial/polynomial_element.pyx +13255 -0
- sage/rings/polynomial/polynomial_element_generic.py +1637 -0
- sage/rings/polynomial/polynomial_fateman.py +97 -0
- sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
- sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
- sage/rings/polynomial/polynomial_ring.py +3784 -0
- sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
- sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
- sage/rings/polynomial/polynomial_singular_interface.py +549 -0
- sage/rings/polynomial/symmetric_ideal.py +989 -0
- sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/symmetric_reduction.pxd +8 -0
- sage/rings/polynomial/symmetric_reduction.pyx +669 -0
- sage/rings/polynomial/term_order.py +2279 -0
- sage/rings/polynomial/toy_buchberger.py +449 -0
- sage/rings/polynomial/toy_d_basis.py +387 -0
- sage/rings/polynomial/toy_variety.py +362 -0
- sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_mpoly.pxd +9 -0
- sage/rings/power_series_mpoly.pyx +161 -0
- sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_poly.pxd +10 -0
- sage/rings/power_series_poly.pyx +1317 -0
- sage/rings/power_series_ring.py +1441 -0
- sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/power_series_ring_element.pxd +12 -0
- sage/rings/power_series_ring_element.pyx +3028 -0
- sage/rings/puiseux_series_ring.py +487 -0
- sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/puiseux_series_ring_element.pxd +7 -0
- sage/rings/puiseux_series_ring_element.pyx +1055 -0
- sage/rings/qqbar_decorators.py +167 -0
- sage/rings/quotient_ring.py +1598 -0
- sage/rings/quotient_ring_element.py +979 -0
- sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/rational.pxd +20 -0
- sage/rings/rational.pyx +4284 -0
- sage/rings/rational_field.py +1730 -0
- sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_double.pxd +16 -0
- sage/rings/real_double.pyx +2218 -0
- sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/real_lazy.pxd +30 -0
- sage/rings/real_lazy.pyx +1773 -0
- sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/ring.pxd +30 -0
- sage/rings/ring.pyx +850 -0
- sage/rings/semirings/all.py +3 -0
- sage/rings/semirings/non_negative_integer_semiring.py +107 -0
- sage/rings/semirings/tropical_mpolynomial.py +972 -0
- sage/rings/semirings/tropical_polynomial.py +997 -0
- sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/semirings/tropical_semiring.pyx +676 -0
- sage/rings/semirings/tropical_variety.py +1701 -0
- sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/rings/sum_of_squares.pxd +3 -0
- sage/rings/sum_of_squares.pyx +336 -0
- sage/rings/tests.py +504 -0
- sage/schemes/affine/affine_homset.py +508 -0
- sage/schemes/affine/affine_morphism.py +1574 -0
- sage/schemes/affine/affine_point.py +460 -0
- sage/schemes/affine/affine_rational_point.py +308 -0
- sage/schemes/affine/affine_space.py +1264 -0
- sage/schemes/affine/affine_subscheme.py +592 -0
- sage/schemes/affine/all.py +25 -0
- sage/schemes/all__sagemath_categories.py +5 -0
- sage/schemes/generic/algebraic_scheme.py +2092 -0
- sage/schemes/generic/all.py +5 -0
- sage/schemes/generic/ambient_space.py +400 -0
- sage/schemes/generic/divisor.py +465 -0
- sage/schemes/generic/divisor_group.py +313 -0
- sage/schemes/generic/glue.py +84 -0
- sage/schemes/generic/homset.py +820 -0
- sage/schemes/generic/hypersurface.py +234 -0
- sage/schemes/generic/morphism.py +2107 -0
- sage/schemes/generic/point.py +237 -0
- sage/schemes/generic/scheme.py +1190 -0
- sage/schemes/generic/spec.py +199 -0
- sage/schemes/product_projective/all.py +6 -0
- sage/schemes/product_projective/homset.py +236 -0
- sage/schemes/product_projective/morphism.py +517 -0
- sage/schemes/product_projective/point.py +568 -0
- sage/schemes/product_projective/rational_point.py +550 -0
- sage/schemes/product_projective/space.py +1301 -0
- sage/schemes/product_projective/subscheme.py +466 -0
- sage/schemes/projective/all.py +24 -0
- sage/schemes/projective/proj_bdd_height.py +453 -0
- sage/schemes/projective/projective_homset.py +718 -0
- sage/schemes/projective/projective_morphism.py +2792 -0
- sage/schemes/projective/projective_point.py +1484 -0
- sage/schemes/projective/projective_rational_point.py +569 -0
- sage/schemes/projective/projective_space.py +2571 -0
- sage/schemes/projective/projective_subscheme.py +1574 -0
- sage/sets/all.py +17 -0
- sage/sets/cartesian_product.py +376 -0
- sage/sets/condition_set.py +525 -0
- sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/disjoint_set.pxd +36 -0
- sage/sets/disjoint_set.pyx +998 -0
- sage/sets/disjoint_union_enumerated_sets.py +625 -0
- sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/family.pxd +12 -0
- sage/sets/family.pyx +1556 -0
- sage/sets/finite_enumerated_set.py +406 -0
- sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/finite_set_map_cy.pxd +34 -0
- sage/sets/finite_set_map_cy.pyx +708 -0
- sage/sets/finite_set_maps.py +591 -0
- sage/sets/image_set.py +448 -0
- sage/sets/integer_range.py +829 -0
- sage/sets/non_negative_integers.py +241 -0
- sage/sets/positive_integers.py +93 -0
- sage/sets/primes.py +188 -0
- sage/sets/real_set.py +2760 -0
- sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/sets/recursively_enumerated_set.pxd +31 -0
- sage/sets/recursively_enumerated_set.pyx +2082 -0
- sage/sets/set.py +2083 -0
- sage/sets/set_from_iterator.py +1021 -0
- sage/sets/totally_ordered_finite_set.py +329 -0
- sage/symbolic/all__sagemath_categories.py +1 -0
- sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/function.pxd +29 -0
- sage/symbolic/function.pyx +1488 -0
- sage/symbolic/symbols.py +56 -0
- sage/tests/all__sagemath_categories.py +1 -0
- sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/cython.pyx +37 -0
- sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/tests/stl_vector.pyx +171 -0
- sage/typeset/all.py +6 -0
- sage/typeset/ascii_art.py +295 -0
- sage/typeset/character_art.py +789 -0
- sage/typeset/character_art_factory.py +572 -0
- sage/typeset/symbols.py +334 -0
- sage/typeset/unicode_art.py +183 -0
- sage/typeset/unicode_characters.py +101 -0
sage/rings/real_lazy.pyx
ADDED
|
@@ -0,0 +1,1773 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-categories
|
|
2
|
+
# sage.doctest: needs sage.rings.real_interval_field sage.rings.real_mpfr
|
|
3
|
+
"""
|
|
4
|
+
Lazy real and complex numbers
|
|
5
|
+
|
|
6
|
+
These classes are very lazy, in the sense that it doesn't really do anything
|
|
7
|
+
but simply sits between exact rings of characteristic 0 and the real numbers.
|
|
8
|
+
The values are actually computed when they are cast into a field of fixed
|
|
9
|
+
precision.
|
|
10
|
+
|
|
11
|
+
The main purpose of these classes is to provide a place for exact rings (e.g.
|
|
12
|
+
number fields) to embed for the coercion model (as only one embedding can be
|
|
13
|
+
specified in the forward direction).
|
|
14
|
+
|
|
15
|
+
TESTS:
|
|
16
|
+
|
|
17
|
+
Bug :issue:`21991`::
|
|
18
|
+
|
|
19
|
+
sage: a = QuadraticField(5).gen() # needs sage.rings.number_field
|
|
20
|
+
sage: u = -573147844013817084101/2*a + 1281597540372340914251/2 # needs sage.rings.number_field
|
|
21
|
+
sage: RealIntervalField(128)(RLF(u)).is_exact() # needs sage.rings.number_field
|
|
22
|
+
False
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# ****************************************************************************
|
|
26
|
+
# Copyright (C) 2008 Robert Bradshaw <robertwb@math.washington.edu>
|
|
27
|
+
#
|
|
28
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
29
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
30
|
+
# the License, or (at your option) any later version.
|
|
31
|
+
# https://www.gnu.org/licenses/
|
|
32
|
+
# ****************************************************************************
|
|
33
|
+
|
|
34
|
+
import math
|
|
35
|
+
import cmath
|
|
36
|
+
|
|
37
|
+
cdef add, sub, mul, truediv, pow, neg, inv
|
|
38
|
+
from operator import add, sub, mul, pow, neg, inv, truediv
|
|
39
|
+
|
|
40
|
+
cdef canonical_coercion
|
|
41
|
+
from sage.structure.element import canonical_coercion
|
|
42
|
+
from sage.structure.element cimport parent
|
|
43
|
+
from sage.structure.richcmp cimport richcmp
|
|
44
|
+
|
|
45
|
+
import sage.categories.map
|
|
46
|
+
from sage.categories.morphism cimport Morphism
|
|
47
|
+
from sage.rings.ring cimport Field
|
|
48
|
+
import sage.rings.infinity
|
|
49
|
+
from sage.rings.integer import Integer
|
|
50
|
+
|
|
51
|
+
cdef QQ, RR, CC, RealField, ComplexField
|
|
52
|
+
from sage.rings.rational_field import QQ
|
|
53
|
+
|
|
54
|
+
cdef late_import():
|
|
55
|
+
global RR, CC, RealField, ComplexField
|
|
56
|
+
if CC is not None:
|
|
57
|
+
return
|
|
58
|
+
try:
|
|
59
|
+
from sage.rings.real_mpfr import RR, RealField
|
|
60
|
+
from sage.rings.complex_mpfr import ComplexField
|
|
61
|
+
from sage.rings.cc import CC
|
|
62
|
+
except ImportError:
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
cdef _QQx = None
|
|
66
|
+
|
|
67
|
+
cdef QQx():
|
|
68
|
+
global _QQx
|
|
69
|
+
if _QQx is None:
|
|
70
|
+
_QQx = QQ['x']
|
|
71
|
+
return _QQx
|
|
72
|
+
|
|
73
|
+
cdef named_unops = [ 'sqrt', 'erf', 'gamma', 'abs',
|
|
74
|
+
'floor', 'ceil', 'trunc',
|
|
75
|
+
'exp', 'log', 'log10', 'log2',
|
|
76
|
+
'sin', 'cos', 'tan', 'arcsin', 'arccos', 'arctan',
|
|
77
|
+
'csc', 'sec', 'cot',
|
|
78
|
+
'sinh', 'cosh', 'tanh', 'arcsinh', 'arccosh', 'arctanh' ]
|
|
79
|
+
|
|
80
|
+
cdef named_constants = [ 'pi', 'e',
|
|
81
|
+
'euler_constant', 'catalan_constant' ]
|
|
82
|
+
|
|
83
|
+
cdef class LazyField(Field):
|
|
84
|
+
"""
|
|
85
|
+
The base class for lazy real fields.
|
|
86
|
+
|
|
87
|
+
.. WARNING::
|
|
88
|
+
|
|
89
|
+
LazyField uses :meth:`__getattr__`, to implement::
|
|
90
|
+
|
|
91
|
+
sage: CLF.pi
|
|
92
|
+
3.141592653589794?
|
|
93
|
+
|
|
94
|
+
I (NT, 20/04/2012) did not manage to have ``__getattr__`` call
|
|
95
|
+
:meth:`Parent.__getattr__` in case of failure; hence we can't
|
|
96
|
+
use this ``__getattr__`` trick for extension types to recover
|
|
97
|
+
the methods from categories. Therefore, at this point, no
|
|
98
|
+
concrete subclass of this class should be an extension type
|
|
99
|
+
(which is probably just fine)::
|
|
100
|
+
|
|
101
|
+
sage: RLF.__class__
|
|
102
|
+
<class 'sage.rings.real_lazy.RealLazyField_class_with_category'>
|
|
103
|
+
sage: CLF.__class__
|
|
104
|
+
<class 'sage.rings.real_lazy.ComplexLazyField_class_with_category'>
|
|
105
|
+
"""
|
|
106
|
+
def __init__(self, base=None, names=None, normalize=True, category=None):
|
|
107
|
+
"""
|
|
108
|
+
Initialize ``self``.
|
|
109
|
+
|
|
110
|
+
EXAMPLES::
|
|
111
|
+
|
|
112
|
+
sage: RLF # indirect doctest
|
|
113
|
+
Real Lazy Field
|
|
114
|
+
"""
|
|
115
|
+
Field.__init__(self,base or self, names=names, normalize=normalize, category=category)
|
|
116
|
+
|
|
117
|
+
Element = LazyWrapper
|
|
118
|
+
|
|
119
|
+
def __getattr__(self, name):
|
|
120
|
+
"""
|
|
121
|
+
Simulates a list of methods found on the real/complex rings.
|
|
122
|
+
|
|
123
|
+
EXAMPLES::
|
|
124
|
+
|
|
125
|
+
sage: a = CLF.pi() * CLF.I(); a
|
|
126
|
+
3.141592653589794?*I
|
|
127
|
+
sage: CDF(a)
|
|
128
|
+
3.141592653589793*I
|
|
129
|
+
"""
|
|
130
|
+
if name in named_constants:
|
|
131
|
+
return LazyConstant(self, name)
|
|
132
|
+
elif name == 'I' and self == CLF:
|
|
133
|
+
return LazyConstant(self, name)
|
|
134
|
+
else:
|
|
135
|
+
raise AttributeError(name)
|
|
136
|
+
|
|
137
|
+
cpdef _coerce_map_from_(self, R):
|
|
138
|
+
r"""
|
|
139
|
+
The only things that coerce into this ring are exact rings that
|
|
140
|
+
embed into `\RR` or `\CC` (depending on whether this field
|
|
141
|
+
is real or complex), that is, exact rings that coerce into all
|
|
142
|
+
rings into which this ring coerces.
|
|
143
|
+
|
|
144
|
+
.. NOTE::
|
|
145
|
+
|
|
146
|
+
The rings into which this ring coerces are currently the
|
|
147
|
+
corresponding floating-point fields (RealField(p) or
|
|
148
|
+
ComplexField(p)), machine-precision floating-point fields (RDF,
|
|
149
|
+
CDF), and interval fields (RealIntervalField(p),
|
|
150
|
+
ComplexIntervalField(p)). This method should be updated if a new
|
|
151
|
+
parent is added that declares a coercion from RLF/CLF but not from
|
|
152
|
+
one of these, otherwise coercions of elements of type LazyWrapper
|
|
153
|
+
into the new ring might fail.
|
|
154
|
+
|
|
155
|
+
EXAMPLES::
|
|
156
|
+
|
|
157
|
+
sage: RLF.has_coerce_map_from(ZZ) # indirect doctest
|
|
158
|
+
True
|
|
159
|
+
sage: RLF.has_coerce_map_from(QQ)
|
|
160
|
+
True
|
|
161
|
+
sage: RLF.has_coerce_map_from(AA) # needs sage.rings.number_field
|
|
162
|
+
True
|
|
163
|
+
sage: CLF.has_coerce_map_from(QQbar) # needs sage.rings.number_field
|
|
164
|
+
True
|
|
165
|
+
sage: RLF.has_coerce_map_from(RDF)
|
|
166
|
+
False
|
|
167
|
+
|
|
168
|
+
sage: CLF.has_coerce_map_from(QQ)
|
|
169
|
+
True
|
|
170
|
+
sage: CLF.has_coerce_map_from(QQbar) # needs sage.rings.number_field
|
|
171
|
+
True
|
|
172
|
+
sage: CLF.has_coerce_map_from(CC)
|
|
173
|
+
False
|
|
174
|
+
sage: CLF.has_coerce_map_from(RLF)
|
|
175
|
+
True
|
|
176
|
+
"""
|
|
177
|
+
if isinstance(R, type):
|
|
178
|
+
if R is int:
|
|
179
|
+
from sage.sets.pythonclass import Set_PythonType
|
|
180
|
+
return LazyWrapperMorphism(Set_PythonType(R), self)
|
|
181
|
+
elif R.is_exact():
|
|
182
|
+
try:
|
|
183
|
+
ivf = self.interval_field()
|
|
184
|
+
except ImportError:
|
|
185
|
+
return None
|
|
186
|
+
mor = ivf.coerce_map_from(R)
|
|
187
|
+
# Indirect coercions might lead to loops both in the coercion
|
|
188
|
+
# discovery algorithm and when trying to convert LazyWrappers,
|
|
189
|
+
# so we only consider direct coercions.
|
|
190
|
+
if mor is not None and not isinstance(mor, sage.categories.map.FormalCompositeMap):
|
|
191
|
+
mor = ivf.middle_field().coerce_map_from(R)
|
|
192
|
+
if mor is not None and not isinstance(mor, sage.categories.map.FormalCompositeMap):
|
|
193
|
+
return LazyWrapperMorphism(R, self)
|
|
194
|
+
# We can skip the test for a coercion to RDF/CDF since RR/CC
|
|
195
|
+
# already coerce into it.
|
|
196
|
+
|
|
197
|
+
def algebraic_closure(self):
|
|
198
|
+
"""
|
|
199
|
+
Return the algebraic closure of ``self``, i.e., the complex lazy
|
|
200
|
+
field.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: RLF.algebraic_closure()
|
|
205
|
+
Complex Lazy Field
|
|
206
|
+
|
|
207
|
+
sage: CLF.algebraic_closure()
|
|
208
|
+
Complex Lazy Field
|
|
209
|
+
"""
|
|
210
|
+
return CLF
|
|
211
|
+
|
|
212
|
+
cpdef interval_field(self, prec=None):
|
|
213
|
+
"""
|
|
214
|
+
Abstract method to create the corresponding interval field.
|
|
215
|
+
|
|
216
|
+
TESTS::
|
|
217
|
+
|
|
218
|
+
sage: RLF.interval_field() # indirect doctest
|
|
219
|
+
Real Interval Field with 53 bits of precision
|
|
220
|
+
"""
|
|
221
|
+
raise NotImplementedError("subclasses must override this method")
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class RealLazyField_class(LazyField):
|
|
225
|
+
r"""
|
|
226
|
+
This class represents the set of real numbers to unspecified precision.
|
|
227
|
+
For the most part it simply wraps exact elements and defers evaluation
|
|
228
|
+
until a specified precision is requested.
|
|
229
|
+
|
|
230
|
+
Its primary use is to connect the exact rings (such as number fields) to
|
|
231
|
+
fixed precision real numbers. For example, to specify an embedding of a
|
|
232
|
+
number field `K` into `\RR` one can map into this field and the
|
|
233
|
+
coercion will then be able to carry the mapping to real fields of any
|
|
234
|
+
precision.
|
|
235
|
+
|
|
236
|
+
EXAMPLES::
|
|
237
|
+
|
|
238
|
+
sage: a = RLF(1/3)
|
|
239
|
+
sage: a
|
|
240
|
+
0.3333333333333334?
|
|
241
|
+
sage: a + 1/5
|
|
242
|
+
0.5333333333333334?
|
|
243
|
+
sage: a = RLF(1/3)
|
|
244
|
+
sage: a
|
|
245
|
+
0.3333333333333334?
|
|
246
|
+
sage: a + 5
|
|
247
|
+
5.333333333333334?
|
|
248
|
+
sage: RealField(100)(a+5)
|
|
249
|
+
5.3333333333333333333333333333
|
|
250
|
+
|
|
251
|
+
::
|
|
252
|
+
|
|
253
|
+
sage: CC.0 + RLF(1/3)
|
|
254
|
+
0.333333333333333 + 1.00000000000000*I
|
|
255
|
+
sage: ComplexField(200).0 + RLF(1/3)
|
|
256
|
+
0.33333333333333333333333333333333333333333333333333333333333 + 1.0000000000000000000000000000000000000000000000000000000000*I
|
|
257
|
+
|
|
258
|
+
TESTS::
|
|
259
|
+
|
|
260
|
+
sage: TestSuite(RLF).run()
|
|
261
|
+
"""
|
|
262
|
+
def interval_field(self, prec=None):
|
|
263
|
+
"""
|
|
264
|
+
Return the interval field that represents the same mathematical
|
|
265
|
+
field as ``self``.
|
|
266
|
+
|
|
267
|
+
EXAMPLES::
|
|
268
|
+
|
|
269
|
+
sage: RLF.interval_field()
|
|
270
|
+
Real Interval Field with 53 bits of precision
|
|
271
|
+
sage: RLF.interval_field(200)
|
|
272
|
+
Real Interval Field with 200 bits of precision
|
|
273
|
+
"""
|
|
274
|
+
from sage.rings.real_mpfi import RIF, RealIntervalField
|
|
275
|
+
if prec is None:
|
|
276
|
+
return RIF
|
|
277
|
+
else:
|
|
278
|
+
return RealIntervalField(prec)
|
|
279
|
+
|
|
280
|
+
def construction(self):
|
|
281
|
+
"""
|
|
282
|
+
Return the functorial construction of ``self``, namely, the
|
|
283
|
+
completion of the rationals at infinity to infinite precision.
|
|
284
|
+
|
|
285
|
+
EXAMPLES::
|
|
286
|
+
|
|
287
|
+
sage: c, S = RLF.construction(); S
|
|
288
|
+
Rational Field
|
|
289
|
+
sage: RLF == c(S)
|
|
290
|
+
True
|
|
291
|
+
"""
|
|
292
|
+
from sage.categories.pushout import CompletionFunctor
|
|
293
|
+
return CompletionFunctor(sage.rings.infinity.Infinity,
|
|
294
|
+
sage.rings.infinity.Infinity,
|
|
295
|
+
{'type': 'RLF'}), QQ
|
|
296
|
+
|
|
297
|
+
def _latex_(self):
|
|
298
|
+
r"""
|
|
299
|
+
Return a latex representation of ``self``.
|
|
300
|
+
|
|
301
|
+
EXAMPLES::
|
|
302
|
+
|
|
303
|
+
sage: latex(RLF) # indirect doctest
|
|
304
|
+
\Bold{R}
|
|
305
|
+
"""
|
|
306
|
+
return "\\Bold{R}"
|
|
307
|
+
|
|
308
|
+
def gen(self, i=0):
|
|
309
|
+
"""
|
|
310
|
+
Return the `i`-th generator of ``self``.
|
|
311
|
+
|
|
312
|
+
EXAMPLES::
|
|
313
|
+
|
|
314
|
+
sage: RLF.gen()
|
|
315
|
+
1
|
|
316
|
+
"""
|
|
317
|
+
if i == 0:
|
|
318
|
+
return self(Integer(1))
|
|
319
|
+
else:
|
|
320
|
+
raise ValueError("RLF has only one generator.")
|
|
321
|
+
|
|
322
|
+
def _repr_(self):
|
|
323
|
+
"""
|
|
324
|
+
Return a string representation of ``self``.
|
|
325
|
+
|
|
326
|
+
EXAMPLES::
|
|
327
|
+
|
|
328
|
+
sage: RealLazyField()
|
|
329
|
+
Real Lazy Field
|
|
330
|
+
"""
|
|
331
|
+
return "Real Lazy Field"
|
|
332
|
+
|
|
333
|
+
def __hash__(self):
|
|
334
|
+
"""
|
|
335
|
+
Return the hash of ``self``.
|
|
336
|
+
|
|
337
|
+
EXAMPLES::
|
|
338
|
+
|
|
339
|
+
sage: hash(RLF) == hash(RealLazyField())
|
|
340
|
+
True
|
|
341
|
+
"""
|
|
342
|
+
return 1501555429
|
|
343
|
+
|
|
344
|
+
def __reduce__(self):
|
|
345
|
+
"""
|
|
346
|
+
For pickling.
|
|
347
|
+
|
|
348
|
+
TESTS::
|
|
349
|
+
|
|
350
|
+
sage: RLF == loads(dumps(RLF))
|
|
351
|
+
True
|
|
352
|
+
sage: RLF is loads(dumps(RLF))
|
|
353
|
+
True
|
|
354
|
+
"""
|
|
355
|
+
return RealLazyField, ()
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
RLF = RealLazyField_class()
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def RealLazyField():
|
|
362
|
+
"""
|
|
363
|
+
Return the lazy real field.
|
|
364
|
+
|
|
365
|
+
EXAMPLES:
|
|
366
|
+
|
|
367
|
+
There is only one lazy real field::
|
|
368
|
+
|
|
369
|
+
sage: RealLazyField() is RealLazyField()
|
|
370
|
+
True
|
|
371
|
+
"""
|
|
372
|
+
return RLF
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
class ComplexLazyField_class(LazyField):
|
|
376
|
+
"""
|
|
377
|
+
This class represents the set of complex numbers to unspecified precision.
|
|
378
|
+
For the most part it simply wraps exact elements and defers evaluation
|
|
379
|
+
until a specified precision is requested.
|
|
380
|
+
|
|
381
|
+
For more information, see the documentation of the
|
|
382
|
+
:class:`RLF <sage.rings.real_lazy.RealLazyField_class>`.
|
|
383
|
+
|
|
384
|
+
EXAMPLES::
|
|
385
|
+
|
|
386
|
+
sage: a = CLF(-1).sqrt()
|
|
387
|
+
sage: a
|
|
388
|
+
1*I
|
|
389
|
+
sage: CDF(a)
|
|
390
|
+
1.0*I
|
|
391
|
+
sage: ComplexField(200)(a)
|
|
392
|
+
1.0000000000000000000000000000000000000000000000000000000000*I
|
|
393
|
+
|
|
394
|
+
TESTS::
|
|
395
|
+
|
|
396
|
+
sage: TestSuite(CLF).run()
|
|
397
|
+
"""
|
|
398
|
+
def __init__(self):
|
|
399
|
+
"""
|
|
400
|
+
This lazy field does not evaluate its elements until they are cast into
|
|
401
|
+
a field of fixed precision.
|
|
402
|
+
|
|
403
|
+
EXAMPLES::
|
|
404
|
+
|
|
405
|
+
sage: a = RLF(1/3); a
|
|
406
|
+
0.3333333333333334?
|
|
407
|
+
sage: Reals(200)(a)
|
|
408
|
+
0.33333333333333333333333333333333333333333333333333333333333
|
|
409
|
+
"""
|
|
410
|
+
LazyField.__init__(self, base=RLF)
|
|
411
|
+
self._populate_coercion_lists_(coerce_list=[LazyWrapperMorphism(RLF, self)])
|
|
412
|
+
|
|
413
|
+
def interval_field(self, prec=None):
|
|
414
|
+
"""
|
|
415
|
+
Return the interval field that represents the same mathematical
|
|
416
|
+
field as ``self``.
|
|
417
|
+
|
|
418
|
+
EXAMPLES::
|
|
419
|
+
|
|
420
|
+
sage: CLF.interval_field()
|
|
421
|
+
Complex Interval Field with 53 bits of precision
|
|
422
|
+
sage: CLF.interval_field(333) # needs sage.rings.complex_interval_field
|
|
423
|
+
Complex Interval Field with 333 bits of precision
|
|
424
|
+
sage: CLF.interval_field() is CIF
|
|
425
|
+
True
|
|
426
|
+
"""
|
|
427
|
+
if prec is None:
|
|
428
|
+
from sage.rings.cif import CIF
|
|
429
|
+
return CIF
|
|
430
|
+
else:
|
|
431
|
+
from sage.rings.complex_interval_field import ComplexIntervalField
|
|
432
|
+
return ComplexIntervalField(prec)
|
|
433
|
+
|
|
434
|
+
def gen(self, i=0):
|
|
435
|
+
"""
|
|
436
|
+
Return the `i`-th generator of ``self``.
|
|
437
|
+
|
|
438
|
+
EXAMPLES::
|
|
439
|
+
|
|
440
|
+
sage: CLF.gen()
|
|
441
|
+
1*I
|
|
442
|
+
sage: ComplexField(100)(CLF.gen()) # needs sage.rings.number_field
|
|
443
|
+
1.0000000000000000000000000000*I
|
|
444
|
+
"""
|
|
445
|
+
if i == 0:
|
|
446
|
+
from sage.rings.complex_double import CDF
|
|
447
|
+
return LazyAlgebraic(self, [1, 0, 1], CDF.gen())
|
|
448
|
+
else:
|
|
449
|
+
raise ValueError("CLF has only one generator.")
|
|
450
|
+
|
|
451
|
+
def construction(self):
|
|
452
|
+
"""
|
|
453
|
+
Return the functorial construction of ``self``, namely,
|
|
454
|
+
algebraic closure of the real lazy field.
|
|
455
|
+
|
|
456
|
+
EXAMPLES::
|
|
457
|
+
|
|
458
|
+
sage: c, S = CLF.construction(); S
|
|
459
|
+
Real Lazy Field
|
|
460
|
+
sage: CLF == c(S)
|
|
461
|
+
True
|
|
462
|
+
"""
|
|
463
|
+
from sage.categories.pushout import AlgebraicClosureFunctor
|
|
464
|
+
return (AlgebraicClosureFunctor(), RLF)
|
|
465
|
+
|
|
466
|
+
def _latex_(self):
|
|
467
|
+
r"""
|
|
468
|
+
Return a latex representation of ``self``.
|
|
469
|
+
|
|
470
|
+
EXAMPLES::
|
|
471
|
+
|
|
472
|
+
sage: latex(CLF) # indirect doctest
|
|
473
|
+
\Bold{C}
|
|
474
|
+
"""
|
|
475
|
+
return "\\Bold{C}"
|
|
476
|
+
|
|
477
|
+
def _repr_(self):
|
|
478
|
+
"""
|
|
479
|
+
Return a string representation of ``self``.
|
|
480
|
+
|
|
481
|
+
EXAMPLES::
|
|
482
|
+
|
|
483
|
+
sage: CLF
|
|
484
|
+
Complex Lazy Field
|
|
485
|
+
"""
|
|
486
|
+
return "Complex Lazy Field"
|
|
487
|
+
|
|
488
|
+
def __hash__(self):
|
|
489
|
+
"""
|
|
490
|
+
Return the hash of ``self``.
|
|
491
|
+
|
|
492
|
+
EXAMPLES::
|
|
493
|
+
|
|
494
|
+
sage: from sage.rings.real_lazy import ComplexLazyField_class
|
|
495
|
+
sage: hash(CLF) == hash(ComplexLazyField_class())
|
|
496
|
+
True
|
|
497
|
+
"""
|
|
498
|
+
return -1382606040
|
|
499
|
+
|
|
500
|
+
def __reduce__(self):
|
|
501
|
+
"""
|
|
502
|
+
For pickling.
|
|
503
|
+
|
|
504
|
+
TESTS::
|
|
505
|
+
|
|
506
|
+
sage: CLF == loads(dumps(CLF))
|
|
507
|
+
True
|
|
508
|
+
sage: CLF is loads(dumps(CLF))
|
|
509
|
+
True
|
|
510
|
+
"""
|
|
511
|
+
return ComplexLazyField, ()
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
CLF = ComplexLazyField_class()
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def ComplexLazyField():
|
|
518
|
+
"""
|
|
519
|
+
Return the lazy complex field.
|
|
520
|
+
|
|
521
|
+
EXAMPLES:
|
|
522
|
+
|
|
523
|
+
There is only one lazy complex field::
|
|
524
|
+
|
|
525
|
+
sage: ComplexLazyField() is ComplexLazyField()
|
|
526
|
+
True
|
|
527
|
+
"""
|
|
528
|
+
return CLF
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
cdef int get_new_prec(R, int depth) except -1:
|
|
532
|
+
"""
|
|
533
|
+
There are depth operations, so we want at least that many more digits of
|
|
534
|
+
precision.
|
|
535
|
+
|
|
536
|
+
Field creation may be expensive, so we want to avoid incrementing by 1 so
|
|
537
|
+
that it is more likely for cached fields to be used.
|
|
538
|
+
"""
|
|
539
|
+
cdef int needed_prec = R.prec()
|
|
540
|
+
needed_prec += depth
|
|
541
|
+
if needed_prec % 10 != 0:
|
|
542
|
+
needed_prec += 10 - needed_prec % 10
|
|
543
|
+
return needed_prec
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
cdef class LazyFieldElement(FieldElement):
|
|
547
|
+
|
|
548
|
+
cpdef _add_(left, right):
|
|
549
|
+
"""
|
|
550
|
+
Add ``left`` with ``right``.
|
|
551
|
+
|
|
552
|
+
EXAMPLES::
|
|
553
|
+
|
|
554
|
+
sage: RLF(5) + RLF(1/2) # indirect doctest
|
|
555
|
+
5.5000000000000000?
|
|
556
|
+
"""
|
|
557
|
+
if isinstance(left, LazyWrapper) and isinstance(right, LazyWrapper):
|
|
558
|
+
try:
|
|
559
|
+
return left._new_wrapper((<LazyWrapper?>left)._value + (<LazyWrapper?>right)._value)
|
|
560
|
+
except TypeError:
|
|
561
|
+
pass
|
|
562
|
+
return left._new_binop(left, right, add)
|
|
563
|
+
|
|
564
|
+
cpdef _sub_(left, right):
|
|
565
|
+
"""
|
|
566
|
+
Subtract ``right`` from ``left``.
|
|
567
|
+
|
|
568
|
+
EXAMPLES::
|
|
569
|
+
|
|
570
|
+
sage: CLF(5) - 2 # indirect doctest
|
|
571
|
+
3
|
|
572
|
+
"""
|
|
573
|
+
if isinstance(left, LazyWrapper) and isinstance(right, LazyWrapper):
|
|
574
|
+
try:
|
|
575
|
+
return left._new_wrapper((<LazyWrapper?>left)._value - (<LazyWrapper?>right)._value)
|
|
576
|
+
except TypeError:
|
|
577
|
+
pass
|
|
578
|
+
return left._new_binop(left, right, sub)
|
|
579
|
+
|
|
580
|
+
cpdef _mul_(left, right):
|
|
581
|
+
"""
|
|
582
|
+
Multiply ``left`` with ``right``.
|
|
583
|
+
|
|
584
|
+
EXAMPLES::
|
|
585
|
+
|
|
586
|
+
sage: CLF(10) * RLF(5) # indirect doctest
|
|
587
|
+
50
|
|
588
|
+
"""
|
|
589
|
+
if isinstance(left, LazyWrapper) and isinstance(right, LazyWrapper):
|
|
590
|
+
try:
|
|
591
|
+
return left._new_wrapper((<LazyWrapper?>left)._value * (<LazyWrapper?>right)._value)
|
|
592
|
+
except TypeError:
|
|
593
|
+
pass
|
|
594
|
+
return left._new_binop(left, right, mul)
|
|
595
|
+
|
|
596
|
+
cpdef _div_(left, right):
|
|
597
|
+
"""
|
|
598
|
+
Divide ``left`` by ``right``.
|
|
599
|
+
|
|
600
|
+
EXAMPLES::
|
|
601
|
+
|
|
602
|
+
sage: a = RLF(1) / RLF(6); a # indirect doctest
|
|
603
|
+
0.1666666666666667?
|
|
604
|
+
sage: Reals(300)(a)
|
|
605
|
+
0.166666666666666666666666666666666666666666666666666666666666666666666666666666666666666667
|
|
606
|
+
"""
|
|
607
|
+
if isinstance(left, LazyWrapper) and isinstance(right, LazyWrapper):
|
|
608
|
+
try:
|
|
609
|
+
return left._new_wrapper((<LazyWrapper?>left)._value / (<LazyWrapper?>right)._value)
|
|
610
|
+
except TypeError:
|
|
611
|
+
pass
|
|
612
|
+
return left._new_binop(left, right, truediv)
|
|
613
|
+
|
|
614
|
+
def __pow__(left, right, dummy):
|
|
615
|
+
"""
|
|
616
|
+
Raise ``left`` to the ``right`` power.
|
|
617
|
+
|
|
618
|
+
EXAMPLES::
|
|
619
|
+
|
|
620
|
+
sage: a = RLF(2) ^ (1/2); a
|
|
621
|
+
1.414213562373095?
|
|
622
|
+
sage: Reals(300)(a)
|
|
623
|
+
1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753
|
|
624
|
+
"""
|
|
625
|
+
if isinstance(left, LazyWrapper) and isinstance(right, LazyWrapper):
|
|
626
|
+
try:
|
|
627
|
+
return left._new_wrapper((<LazyWrapper>left)._value ** (<LazyWrapper>right)._value)
|
|
628
|
+
except TypeError:
|
|
629
|
+
pass
|
|
630
|
+
if not isinstance(left, LazyFieldElement):
|
|
631
|
+
left = (<LazyFieldElement>right)._new_wrapper(left)
|
|
632
|
+
elif not isinstance(right, LazyFieldElement):
|
|
633
|
+
right = (<LazyFieldElement>left)._new_wrapper(right)
|
|
634
|
+
return (<LazyFieldElement>left)._new_binop(left, right, pow)
|
|
635
|
+
|
|
636
|
+
def __neg__(self):
|
|
637
|
+
"""
|
|
638
|
+
Return the negation of ``self``.
|
|
639
|
+
|
|
640
|
+
EXAMPLES::
|
|
641
|
+
|
|
642
|
+
sage: -RLF(7)
|
|
643
|
+
-7
|
|
644
|
+
"""
|
|
645
|
+
return self._new_unop(self, neg)
|
|
646
|
+
|
|
647
|
+
def __invert__(self):
|
|
648
|
+
"""
|
|
649
|
+
Take the reciprocal of ``self``.
|
|
650
|
+
|
|
651
|
+
EXAMPLES::
|
|
652
|
+
|
|
653
|
+
sage: a = ~RLF(6); a
|
|
654
|
+
0.1666666666666667?
|
|
655
|
+
sage: Reals(90)(a)
|
|
656
|
+
0.16666666666666666666666667
|
|
657
|
+
"""
|
|
658
|
+
return self._new_unop(self, inv)
|
|
659
|
+
|
|
660
|
+
cpdef _richcmp_(self, other, int op):
|
|
661
|
+
"""
|
|
662
|
+
If things are being wrapped, tries to compare values. That failing, it
|
|
663
|
+
tries to compare intervals, which may return a false negative.
|
|
664
|
+
|
|
665
|
+
EXAMPLES::
|
|
666
|
+
|
|
667
|
+
sage: RLF(3) == RLF(9/3)
|
|
668
|
+
True
|
|
669
|
+
sage: RLF(3) == RLF(4)
|
|
670
|
+
False
|
|
671
|
+
sage: RLF(3) < RLF(5/3)
|
|
672
|
+
False
|
|
673
|
+
|
|
674
|
+
TESTS::
|
|
675
|
+
|
|
676
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
677
|
+
sage: RLF(3) < LazyBinop(RLF, 5, 3, operator.truediv)
|
|
678
|
+
False
|
|
679
|
+
sage: from sage.rings.real_lazy import LazyWrapper
|
|
680
|
+
sage: LazyWrapper(RLF, 3) < LazyWrapper(RLF, 5/3)
|
|
681
|
+
False
|
|
682
|
+
sage: from sage.rings.real_lazy import LazyUnop
|
|
683
|
+
sage: RLF(3) < LazyUnop(RLF, 2, sqrt)
|
|
684
|
+
False
|
|
685
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
686
|
+
sage: RLF(3) < LazyNamedUnop(RLF, 0, 'sin')
|
|
687
|
+
False
|
|
688
|
+
sage: from sage.rings.real_lazy import LazyConstant
|
|
689
|
+
sage: RLF(3) < LazyConstant(RLF, 'e')
|
|
690
|
+
False
|
|
691
|
+
"""
|
|
692
|
+
left = self
|
|
693
|
+
try:
|
|
694
|
+
if isinstance(self, LazyWrapper) and isinstance(other, LazyWrapper):
|
|
695
|
+
left, right = canonical_coercion((<LazyWrapper>self)._value, (<LazyWrapper>other)._value)
|
|
696
|
+
return richcmp(left, right, op)
|
|
697
|
+
except TypeError:
|
|
698
|
+
pass
|
|
699
|
+
left, right = self.approx(), other.approx()
|
|
700
|
+
return richcmp(left.endpoints(), right.endpoints(), op)
|
|
701
|
+
|
|
702
|
+
def __hash__(self):
|
|
703
|
+
"""
|
|
704
|
+
Return the hash value of ``self``.
|
|
705
|
+
|
|
706
|
+
EXAMPLES::
|
|
707
|
+
|
|
708
|
+
sage: a = RLF(3)
|
|
709
|
+
sage: hash(a)
|
|
710
|
+
3
|
|
711
|
+
"""
|
|
712
|
+
return hash(complex(self))
|
|
713
|
+
|
|
714
|
+
cdef LazyFieldElement _new_wrapper(self, value):
|
|
715
|
+
cdef LazyWrapper e = <LazyWrapper>LazyWrapper.__new__(LazyWrapper)
|
|
716
|
+
e._parent = self._parent
|
|
717
|
+
e._value = value
|
|
718
|
+
return e
|
|
719
|
+
|
|
720
|
+
cdef LazyFieldElement _new_binop(self, LazyFieldElement left, LazyFieldElement right, op):
|
|
721
|
+
cdef LazyBinop e = <LazyBinop>LazyBinop.__new__(LazyBinop)
|
|
722
|
+
e._parent = self._parent
|
|
723
|
+
e._left = left
|
|
724
|
+
e._right = right
|
|
725
|
+
e._op = op
|
|
726
|
+
return e
|
|
727
|
+
|
|
728
|
+
cdef LazyFieldElement _new_unop(self, LazyFieldElement arg, op):
|
|
729
|
+
cdef LazyUnop e = <LazyUnop>LazyUnop.__new__(LazyUnop)
|
|
730
|
+
e._parent = self._parent
|
|
731
|
+
e._op = op
|
|
732
|
+
e._arg = arg
|
|
733
|
+
return e
|
|
734
|
+
|
|
735
|
+
def _repr_(self):
|
|
736
|
+
"""
|
|
737
|
+
The string representation of ``self`` is an interval in which
|
|
738
|
+
``self`` is contained.
|
|
739
|
+
|
|
740
|
+
EXAMPLES::
|
|
741
|
+
|
|
742
|
+
sage: RLF(3) # indirect doctest
|
|
743
|
+
3
|
|
744
|
+
sage: RLF(1/3)
|
|
745
|
+
0.3333333333333334?
|
|
746
|
+
"""
|
|
747
|
+
return str(self.approx())
|
|
748
|
+
|
|
749
|
+
def approx(self):
|
|
750
|
+
"""
|
|
751
|
+
Return ``self`` as an element of an interval field.
|
|
752
|
+
|
|
753
|
+
EXAMPLES::
|
|
754
|
+
|
|
755
|
+
sage: CLF(1/6).approx()
|
|
756
|
+
0.1666666666666667?
|
|
757
|
+
sage: CLF(1/6).approx().parent()
|
|
758
|
+
Complex Interval Field with 53 bits of precision
|
|
759
|
+
|
|
760
|
+
When the absolute value is involved, the result might be real::
|
|
761
|
+
|
|
762
|
+
sage: # needs sage.symbolic
|
|
763
|
+
sage: z = exp(CLF(1 + I/2)); z
|
|
764
|
+
2.38551673095914? + 1.303213729686996?*I
|
|
765
|
+
sage: r = z.abs(); r
|
|
766
|
+
2.71828182845905?
|
|
767
|
+
sage: parent(z.approx())
|
|
768
|
+
Complex Interval Field with 53 bits of precision
|
|
769
|
+
sage: parent(r.approx())
|
|
770
|
+
Real Interval Field with 53 bits of precision
|
|
771
|
+
"""
|
|
772
|
+
return self.eval(self._parent.interval_field())
|
|
773
|
+
|
|
774
|
+
def _real_double_(self, R):
|
|
775
|
+
"""
|
|
776
|
+
Return ``self`` as a real double.
|
|
777
|
+
|
|
778
|
+
EXAMPLES::
|
|
779
|
+
|
|
780
|
+
sage: a = RLF(3)
|
|
781
|
+
sage: RDF(a) # indirect doctest
|
|
782
|
+
3.0
|
|
783
|
+
"""
|
|
784
|
+
return self.eval(R)
|
|
785
|
+
|
|
786
|
+
def _complex_double_(self, R):
|
|
787
|
+
"""
|
|
788
|
+
Return ``self`` as a complex double.
|
|
789
|
+
|
|
790
|
+
EXAMPLES::
|
|
791
|
+
|
|
792
|
+
sage: a = RLF(5)
|
|
793
|
+
sage: CDF(a) # indirect doctest
|
|
794
|
+
5.0
|
|
795
|
+
sage: a = CLF(-1)^(1/4)
|
|
796
|
+
sage: CDF(a)
|
|
797
|
+
0.7071067811865476 + 0.7071067811865475*I
|
|
798
|
+
"""
|
|
799
|
+
return self.eval(R)
|
|
800
|
+
|
|
801
|
+
def _generic_(self, R):
|
|
802
|
+
"""
|
|
803
|
+
Return ``self`` in a generic ring ``R``.
|
|
804
|
+
|
|
805
|
+
EXAMPLES::
|
|
806
|
+
|
|
807
|
+
sage: a = RLF(2/3)
|
|
808
|
+
sage: RR(a) # indirect doctest
|
|
809
|
+
0.666666666666667
|
|
810
|
+
sage: RR(a^2)
|
|
811
|
+
0.444444444444444
|
|
812
|
+
"""
|
|
813
|
+
return self.eval(R)
|
|
814
|
+
|
|
815
|
+
_real_mpfi_ = _complex_mpfi_ =_mpfr_ = _complex_mpfr_field_ = _generic_
|
|
816
|
+
|
|
817
|
+
def __complex__(self):
|
|
818
|
+
"""
|
|
819
|
+
Return ``self`` as a complex.
|
|
820
|
+
|
|
821
|
+
EXAMPLES::
|
|
822
|
+
|
|
823
|
+
sage: complex(CLF(-1)^(1/4))
|
|
824
|
+
(0.707106781186547...+0.707106781186547...j)
|
|
825
|
+
"""
|
|
826
|
+
try:
|
|
827
|
+
return self.eval(complex)
|
|
828
|
+
except Exception:
|
|
829
|
+
return complex(self.eval(ComplexField(53)))
|
|
830
|
+
|
|
831
|
+
cpdef eval(self, R):
|
|
832
|
+
"""
|
|
833
|
+
Abstract method for converting ``self`` into an element of ``R``.
|
|
834
|
+
|
|
835
|
+
EXAMPLES::
|
|
836
|
+
|
|
837
|
+
sage: a = RLF(12)
|
|
838
|
+
sage: a.eval(ZZ)
|
|
839
|
+
12
|
|
840
|
+
"""
|
|
841
|
+
raise NotImplementedError("Subclasses must override this method.")
|
|
842
|
+
|
|
843
|
+
cpdef int depth(self) noexcept:
|
|
844
|
+
"""
|
|
845
|
+
Abstract method for returning the depth of ``self`` as an arithmetic
|
|
846
|
+
expression.
|
|
847
|
+
|
|
848
|
+
This is the maximum number of dependent intermediate expressions when
|
|
849
|
+
evaluating ``self``, and is used to determine the precision needed to
|
|
850
|
+
get the final result to the desired number of bits.
|
|
851
|
+
|
|
852
|
+
It is equal to the maximum of the right and left depths, plus one.
|
|
853
|
+
|
|
854
|
+
EXAMPLES::
|
|
855
|
+
|
|
856
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
857
|
+
sage: a = LazyBinop(RLF, 6, 8, operator.mul)
|
|
858
|
+
sage: a.depth()
|
|
859
|
+
1
|
|
860
|
+
"""
|
|
861
|
+
raise NotImplementedError("Subclasses must override this method.")
|
|
862
|
+
|
|
863
|
+
def __dir__(self):
|
|
864
|
+
"""
|
|
865
|
+
Add the named_unops to ``__dir__`` so that tab completion works.
|
|
866
|
+
|
|
867
|
+
TESTS::
|
|
868
|
+
|
|
869
|
+
sage: "log" in RLF(sqrt(8)).__dir__() # needs sage.symbolic
|
|
870
|
+
True
|
|
871
|
+
"""
|
|
872
|
+
return FieldElement.__dir__(self) + named_unops
|
|
873
|
+
|
|
874
|
+
def __getattribute__(self, name):
|
|
875
|
+
"""
|
|
876
|
+
Simulates a list of methods found on the real/complex mpfr classes.
|
|
877
|
+
|
|
878
|
+
EXAMPLES::
|
|
879
|
+
|
|
880
|
+
sage: a = RLF(3)
|
|
881
|
+
sage: a.sqrt()
|
|
882
|
+
1.732050807568878?
|
|
883
|
+
sage: sin(a) # needs sage.symbolic
|
|
884
|
+
0.1411200080598673?
|
|
885
|
+
sage: RealField(160)(tanh(RLF(3)))
|
|
886
|
+
0.99505475368673045133188018525548847509781385470
|
|
887
|
+
"""
|
|
888
|
+
if name in named_unops:
|
|
889
|
+
return LazyNamedUnop(self._parent, self, name)
|
|
890
|
+
else:
|
|
891
|
+
return FieldElement.__getattribute__(self, name)
|
|
892
|
+
|
|
893
|
+
def continued_fraction(self):
|
|
894
|
+
r"""
|
|
895
|
+
Return the continued fraction of ``self``.
|
|
896
|
+
|
|
897
|
+
EXAMPLES::
|
|
898
|
+
|
|
899
|
+
sage: # needs sage.symbolic
|
|
900
|
+
sage: a = RLF(sqrt(2)) + RLF(sqrt(3))
|
|
901
|
+
sage: cf = a.continued_fraction()
|
|
902
|
+
sage: cf
|
|
903
|
+
[3; 6, 1, 5, 7, 1, 1, 4, 1, 38, 43, 1, 3, 2, 1, 1, 1, 1, 2, 4, ...]
|
|
904
|
+
sage: cf.convergent(100)
|
|
905
|
+
444927297812646558239761867973501208151173610180916865469/141414466649174973335183571854340329919207428365474086063
|
|
906
|
+
"""
|
|
907
|
+
from sage.rings.continued_fraction import ContinuedFraction_real
|
|
908
|
+
return ContinuedFraction_real(self)
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
def make_element(parent, *args):
|
|
912
|
+
"""
|
|
913
|
+
Create an element of ``parent``.
|
|
914
|
+
|
|
915
|
+
EXAMPLES::
|
|
916
|
+
|
|
917
|
+
sage: a = RLF(pi) + RLF(sqrt(1/2)) # indirect doctest # needs sage.symbolic
|
|
918
|
+
sage: bool(loads(dumps(a)) == a) # needs sage.symbolic
|
|
919
|
+
True
|
|
920
|
+
"""
|
|
921
|
+
return parent(*args)
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
cdef class LazyWrapper(LazyFieldElement):
|
|
925
|
+
|
|
926
|
+
cpdef int depth(self) noexcept:
|
|
927
|
+
"""
|
|
928
|
+
Return the depth of ``self`` as an expression, which is always 0.
|
|
929
|
+
|
|
930
|
+
EXAMPLES::
|
|
931
|
+
|
|
932
|
+
sage: RLF(4).depth()
|
|
933
|
+
0
|
|
934
|
+
"""
|
|
935
|
+
return 0
|
|
936
|
+
|
|
937
|
+
def __init__(self, LazyField parent, value, check=True):
|
|
938
|
+
"""
|
|
939
|
+
A lazy element that simply wraps an element of another ring.
|
|
940
|
+
|
|
941
|
+
EXAMPLES::
|
|
942
|
+
|
|
943
|
+
sage: from sage.rings.real_lazy import LazyWrapper
|
|
944
|
+
sage: a = LazyWrapper(RLF, 3)
|
|
945
|
+
sage: a._value
|
|
946
|
+
3
|
|
947
|
+
"""
|
|
948
|
+
FieldElement.__init__(self, parent)
|
|
949
|
+
self._value = value
|
|
950
|
+
if check:
|
|
951
|
+
try:
|
|
952
|
+
ivf = self._parent.interval_field()
|
|
953
|
+
except ImportError:
|
|
954
|
+
pass
|
|
955
|
+
else:
|
|
956
|
+
ivf(value)
|
|
957
|
+
|
|
958
|
+
def __neg__(self):
|
|
959
|
+
"""
|
|
960
|
+
Return the negation of ``self``.
|
|
961
|
+
|
|
962
|
+
EXAMPLES::
|
|
963
|
+
|
|
964
|
+
sage: from sage.rings.real_lazy import LazyWrapper
|
|
965
|
+
sage: a = LazyWrapper(RLF, 3)
|
|
966
|
+
sage: (-a)._value
|
|
967
|
+
-3
|
|
968
|
+
"""
|
|
969
|
+
return self._new_wrapper(-self._value)
|
|
970
|
+
|
|
971
|
+
def __invert__(self):
|
|
972
|
+
"""
|
|
973
|
+
Return the reciprocal of ``self``.
|
|
974
|
+
|
|
975
|
+
EXAMPLES::
|
|
976
|
+
|
|
977
|
+
sage: from sage.rings.real_lazy import LazyWrapper
|
|
978
|
+
sage: a = LazyWrapper(RLF, 23)
|
|
979
|
+
sage: ~a
|
|
980
|
+
0.04347826086956522?
|
|
981
|
+
sage: (~a)._value
|
|
982
|
+
1/23
|
|
983
|
+
"""
|
|
984
|
+
return self._new_wrapper(~self._value)
|
|
985
|
+
|
|
986
|
+
def __float__(self):
|
|
987
|
+
"""
|
|
988
|
+
EXAMPLES::
|
|
989
|
+
|
|
990
|
+
sage: from sage.rings.real_lazy import LazyWrapper
|
|
991
|
+
sage: a = LazyWrapper(CLF, 19)
|
|
992
|
+
sage: float(a)
|
|
993
|
+
19.0
|
|
994
|
+
"""
|
|
995
|
+
return <double>self._value
|
|
996
|
+
|
|
997
|
+
def __bool__(self):
|
|
998
|
+
"""
|
|
999
|
+
Check to see if ``self`` is not zero.
|
|
1000
|
+
|
|
1001
|
+
EXAMPLES::
|
|
1002
|
+
|
|
1003
|
+
sage: from sage.rings.real_lazy import LazyWrapper
|
|
1004
|
+
sage: not LazyWrapper(RLF, 1)
|
|
1005
|
+
False
|
|
1006
|
+
sage: not LazyWrapper(RLF, 0)
|
|
1007
|
+
True
|
|
1008
|
+
"""
|
|
1009
|
+
return not not self._value
|
|
1010
|
+
|
|
1011
|
+
def __hash__(self):
|
|
1012
|
+
"""
|
|
1013
|
+
Return the hash value of ``self``.
|
|
1014
|
+
|
|
1015
|
+
EXAMPLES::
|
|
1016
|
+
|
|
1017
|
+
sage: hash(CLF(-1))
|
|
1018
|
+
-2
|
|
1019
|
+
sage: hash(RLF(9/4)) == hash(9/4)
|
|
1020
|
+
True
|
|
1021
|
+
"""
|
|
1022
|
+
return hash(self._value)
|
|
1023
|
+
|
|
1024
|
+
cpdef eval(self, R):
|
|
1025
|
+
"""
|
|
1026
|
+
Convert ``self`` into an element of ``R``.
|
|
1027
|
+
|
|
1028
|
+
EXAMPLES::
|
|
1029
|
+
|
|
1030
|
+
sage: a = RLF(12)
|
|
1031
|
+
sage: a.eval(ZZ)
|
|
1032
|
+
12
|
|
1033
|
+
sage: a.eval(ZZ).parent()
|
|
1034
|
+
Integer Ring
|
|
1035
|
+
"""
|
|
1036
|
+
try:
|
|
1037
|
+
mor = R.convert_map_from(parent(self._value))
|
|
1038
|
+
except AttributeError:
|
|
1039
|
+
return R(self._value)
|
|
1040
|
+
if mor is not None and self.parent() not in mor.domains():
|
|
1041
|
+
return mor(self._value)
|
|
1042
|
+
else:
|
|
1043
|
+
raise TypeError("unable to convert {!r} to an element of {}".format(self._value, R))
|
|
1044
|
+
|
|
1045
|
+
def __reduce__(self):
|
|
1046
|
+
"""
|
|
1047
|
+
For pickling.
|
|
1048
|
+
|
|
1049
|
+
TESTS::
|
|
1050
|
+
|
|
1051
|
+
sage: a = RLF(2)
|
|
1052
|
+
sage: loads(dumps(a)) == a
|
|
1053
|
+
True
|
|
1054
|
+
"""
|
|
1055
|
+
return make_element, (self._parent, self._value)
|
|
1056
|
+
|
|
1057
|
+
def continued_fraction(self):
|
|
1058
|
+
r"""
|
|
1059
|
+
Return the continued fraction of ``self``.
|
|
1060
|
+
|
|
1061
|
+
EXAMPLES::
|
|
1062
|
+
|
|
1063
|
+
sage: a = RLF(sqrt(2)) # needs sage.symbolic
|
|
1064
|
+
sage: a.continued_fraction() # needs sage.symbolic
|
|
1065
|
+
[1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...]
|
|
1066
|
+
"""
|
|
1067
|
+
from sage.rings.continued_fraction import ContinuedFraction_real, ContinuedFraction_infinite
|
|
1068
|
+
if isinstance(self._value, (ContinuedFraction_infinite, ContinuedFraction_real)):
|
|
1069
|
+
return self._value
|
|
1070
|
+
return ContinuedFraction_real(self)
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
cdef class LazyBinop(LazyFieldElement):
|
|
1074
|
+
|
|
1075
|
+
def __init__(self, LazyField parent, left, right, op):
|
|
1076
|
+
"""
|
|
1077
|
+
A lazy element representing a binary (usually arithmetic) operation
|
|
1078
|
+
between two other lazy elements.
|
|
1079
|
+
|
|
1080
|
+
EXAMPLES::
|
|
1081
|
+
|
|
1082
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
1083
|
+
sage: a = LazyBinop(RLF, 2, 1/3, operator.add)
|
|
1084
|
+
sage: a
|
|
1085
|
+
2.333333333333334?
|
|
1086
|
+
sage: Reals(200)(a)
|
|
1087
|
+
2.3333333333333333333333333333333333333333333333333333333333
|
|
1088
|
+
"""
|
|
1089
|
+
FieldElement.__init__(self, parent)
|
|
1090
|
+
if not isinstance(left, LazyFieldElement):
|
|
1091
|
+
left = self._new_wrapper(left)
|
|
1092
|
+
if not isinstance(right, LazyFieldElement):
|
|
1093
|
+
right = self._new_wrapper(right)
|
|
1094
|
+
self._left = left
|
|
1095
|
+
self._right = right
|
|
1096
|
+
self._op = op
|
|
1097
|
+
|
|
1098
|
+
cpdef int depth(self) noexcept:
|
|
1099
|
+
"""
|
|
1100
|
+
Return the depth of ``self`` as an arithmetic expression.
|
|
1101
|
+
|
|
1102
|
+
This is the maximum number of dependent intermediate expressions when
|
|
1103
|
+
evaluating ``self``, and is used to determine the precision needed to
|
|
1104
|
+
get the final result to the desired number of bits.
|
|
1105
|
+
|
|
1106
|
+
It is equal to the maximum of the right and left depths, plus one.
|
|
1107
|
+
|
|
1108
|
+
EXAMPLES::
|
|
1109
|
+
|
|
1110
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
1111
|
+
sage: a = LazyBinop(RLF, 6, 8, operator.mul)
|
|
1112
|
+
sage: a.depth()
|
|
1113
|
+
1
|
|
1114
|
+
sage: b = LazyBinop(RLF, 2, a, operator.sub)
|
|
1115
|
+
sage: b.depth()
|
|
1116
|
+
2
|
|
1117
|
+
"""
|
|
1118
|
+
cdef int left = self._left.depth()
|
|
1119
|
+
cdef int right = self._right.depth()
|
|
1120
|
+
return 1 + (left if left > right else right)
|
|
1121
|
+
|
|
1122
|
+
cpdef eval(self, R):
|
|
1123
|
+
"""
|
|
1124
|
+
Convert the operands to elements of ``R``, then perform the operation
|
|
1125
|
+
on them.
|
|
1126
|
+
|
|
1127
|
+
EXAMPLES::
|
|
1128
|
+
|
|
1129
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
1130
|
+
sage: a = LazyBinop(RLF, 6, 8, operator.add)
|
|
1131
|
+
sage: a.eval(RR)
|
|
1132
|
+
14.0000000000000
|
|
1133
|
+
|
|
1134
|
+
A bit absurd::
|
|
1135
|
+
|
|
1136
|
+
sage: a.eval(str)
|
|
1137
|
+
'68'
|
|
1138
|
+
"""
|
|
1139
|
+
left = self._left.eval(R)
|
|
1140
|
+
right = self._right.eval(R)
|
|
1141
|
+
if self._op is add:
|
|
1142
|
+
return left + right
|
|
1143
|
+
elif self._op is mul:
|
|
1144
|
+
return left * right
|
|
1145
|
+
elif self._op is sub:
|
|
1146
|
+
return left - right
|
|
1147
|
+
elif self._op is truediv:
|
|
1148
|
+
return left / right
|
|
1149
|
+
elif self._op is pow:
|
|
1150
|
+
return left ** right
|
|
1151
|
+
else:
|
|
1152
|
+
# We only do a call after testing the above because it is a python call.
|
|
1153
|
+
return self._op(left, right)
|
|
1154
|
+
|
|
1155
|
+
def __float__(self):
|
|
1156
|
+
"""
|
|
1157
|
+
EXAMPLES::
|
|
1158
|
+
|
|
1159
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
1160
|
+
sage: a = LazyBinop(RLF, 3, 1/2, operator.sub)
|
|
1161
|
+
sage: float(a)
|
|
1162
|
+
2.5
|
|
1163
|
+
sage: type(float(a))
|
|
1164
|
+
<... 'float'>
|
|
1165
|
+
"""
|
|
1166
|
+
cdef double left = self._left
|
|
1167
|
+
cdef double right = self._right
|
|
1168
|
+
if self._op is add:
|
|
1169
|
+
return left + right
|
|
1170
|
+
elif self._op is mul:
|
|
1171
|
+
return left * right
|
|
1172
|
+
elif self._op is sub:
|
|
1173
|
+
return left - right
|
|
1174
|
+
elif self._op is truediv:
|
|
1175
|
+
return left / right
|
|
1176
|
+
elif self._op is pow:
|
|
1177
|
+
return left ** right
|
|
1178
|
+
else:
|
|
1179
|
+
# We only do a call here because it is a python call.
|
|
1180
|
+
return self._op(left, right)
|
|
1181
|
+
|
|
1182
|
+
def __hash__(self):
|
|
1183
|
+
"""
|
|
1184
|
+
Return the hash value of ``self``.
|
|
1185
|
+
|
|
1186
|
+
EXAMPLES::
|
|
1187
|
+
|
|
1188
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
1189
|
+
sage: a = LazyBinop(RLF, 5, 1/2, operator.sub)
|
|
1190
|
+
sage: b = LazyBinop(RLF, 4, 1/2, operator.add)
|
|
1191
|
+
sage: hash(a) == hash(b)
|
|
1192
|
+
False
|
|
1193
|
+
"""
|
|
1194
|
+
return hash(self._op(hash(self._left), hash(self._right)))
|
|
1195
|
+
|
|
1196
|
+
def __reduce__(self):
|
|
1197
|
+
"""
|
|
1198
|
+
For pickling.
|
|
1199
|
+
|
|
1200
|
+
TESTS::
|
|
1201
|
+
|
|
1202
|
+
sage: from sage.rings.real_lazy import LazyBinop
|
|
1203
|
+
sage: a = LazyBinop(CLF, 3, 2, operator.truediv)
|
|
1204
|
+
sage: loads(dumps(a)) == a
|
|
1205
|
+
True
|
|
1206
|
+
"""
|
|
1207
|
+
return make_element, (LazyBinop, self._parent, self._left, self._right, self._op)
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
cdef class LazyUnop(LazyFieldElement):
|
|
1211
|
+
|
|
1212
|
+
def __init__(self, LazyField parent, arg, op):
|
|
1213
|
+
"""
|
|
1214
|
+
Represent a unevaluated single function of one variable.
|
|
1215
|
+
|
|
1216
|
+
EXAMPLES::
|
|
1217
|
+
|
|
1218
|
+
sage: from sage.rings.real_lazy import LazyUnop
|
|
1219
|
+
sage: a = LazyUnop(RLF, 3, sqrt); a
|
|
1220
|
+
1.732050807568878?
|
|
1221
|
+
sage: a._arg
|
|
1222
|
+
3
|
|
1223
|
+
sage: a._op
|
|
1224
|
+
<function sqrt at ...>
|
|
1225
|
+
sage: Reals(100)(a)
|
|
1226
|
+
1.7320508075688772935274463415
|
|
1227
|
+
sage: Reals(100)(a)^2
|
|
1228
|
+
3.0000000000000000000000000000
|
|
1229
|
+
"""
|
|
1230
|
+
FieldElement.__init__(self, parent)
|
|
1231
|
+
if not isinstance(arg, LazyFieldElement):
|
|
1232
|
+
arg = self._new_wrapper(arg)
|
|
1233
|
+
self._op = op
|
|
1234
|
+
self._arg = arg
|
|
1235
|
+
|
|
1236
|
+
cpdef int depth(self) noexcept:
|
|
1237
|
+
"""
|
|
1238
|
+
Return the depth of ``self`` as an arithmetic expression.
|
|
1239
|
+
|
|
1240
|
+
This is the maximum number of dependent intermediate expressions when
|
|
1241
|
+
evaluating ``self``, and is used to determine the precision needed to
|
|
1242
|
+
get the final result to the desired number of bits.
|
|
1243
|
+
|
|
1244
|
+
It is equal to one more than the depth of its operand.
|
|
1245
|
+
|
|
1246
|
+
EXAMPLES::
|
|
1247
|
+
|
|
1248
|
+
sage: from sage.rings.real_lazy import LazyUnop
|
|
1249
|
+
sage: a = LazyUnop(RLF, 3, sqrt)
|
|
1250
|
+
sage: a.depth()
|
|
1251
|
+
1
|
|
1252
|
+
sage: b = LazyUnop(RLF, a, sin)
|
|
1253
|
+
sage: b.depth()
|
|
1254
|
+
2
|
|
1255
|
+
"""
|
|
1256
|
+
return 1 + self._arg.depth()
|
|
1257
|
+
|
|
1258
|
+
cpdef eval(self, R):
|
|
1259
|
+
"""
|
|
1260
|
+
Convert ``self`` into an element of ``R``.
|
|
1261
|
+
|
|
1262
|
+
EXAMPLES::
|
|
1263
|
+
|
|
1264
|
+
sage: from sage.rings.real_lazy import LazyUnop
|
|
1265
|
+
sage: a = LazyUnop(RLF, 3, sqrt)
|
|
1266
|
+
sage: a.eval(ZZ) # needs sage.symbolic
|
|
1267
|
+
sqrt(3)
|
|
1268
|
+
"""
|
|
1269
|
+
arg = self._arg.eval(R)
|
|
1270
|
+
if self._op is neg:
|
|
1271
|
+
return -arg
|
|
1272
|
+
elif self._op is inv:
|
|
1273
|
+
return ~arg
|
|
1274
|
+
return self._op(self._arg.eval(R))
|
|
1275
|
+
|
|
1276
|
+
def __hash__(self):
|
|
1277
|
+
"""
|
|
1278
|
+
Return the hash value of ``self``.
|
|
1279
|
+
|
|
1280
|
+
EXAMPLES::
|
|
1281
|
+
|
|
1282
|
+
sage: hash(RLF(sin(1))) == hash(RLF(sin(1))) # needs sage.symbolic
|
|
1283
|
+
True
|
|
1284
|
+
"""
|
|
1285
|
+
return hash(self._op(hash(self._arg)))
|
|
1286
|
+
|
|
1287
|
+
def __float__(self):
|
|
1288
|
+
"""
|
|
1289
|
+
Convert ``self`` into a floating point.
|
|
1290
|
+
|
|
1291
|
+
EXAMPLES::
|
|
1292
|
+
|
|
1293
|
+
sage: from sage.rings.real_lazy import LazyUnop
|
|
1294
|
+
sage: a = LazyUnop(RLF, 3, sqrt)
|
|
1295
|
+
sage: float(a)
|
|
1296
|
+
1.7320508075688772
|
|
1297
|
+
"""
|
|
1298
|
+
return self._op(<double>self._arg)
|
|
1299
|
+
|
|
1300
|
+
def __reduce__(self):
|
|
1301
|
+
"""
|
|
1302
|
+
For pickling.
|
|
1303
|
+
|
|
1304
|
+
TESTS::
|
|
1305
|
+
|
|
1306
|
+
sage: from sage.rings.real_lazy import LazyUnop
|
|
1307
|
+
sage: a = LazyUnop(RLF, 7, sqrt)
|
|
1308
|
+
sage: float(loads(dumps(a))) == float(a)
|
|
1309
|
+
True
|
|
1310
|
+
"""
|
|
1311
|
+
return make_element, (LazyUnop, self._parent, self._arg, self._op)
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
cdef class LazyNamedUnop(LazyUnop):
|
|
1315
|
+
|
|
1316
|
+
def __init__(self, LazyField parent, arg, op, extra_args=None):
|
|
1317
|
+
"""
|
|
1318
|
+
This class is used to represent the many named methods attached to real
|
|
1319
|
+
numbers, and is instantiated by the ``__getattr__`` method of
|
|
1320
|
+
:class:`LazyElements`.
|
|
1321
|
+
|
|
1322
|
+
EXAMPLES::
|
|
1323
|
+
|
|
1324
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
1325
|
+
sage: a = LazyNamedUnop(RLF, 1, 'arcsin')
|
|
1326
|
+
sage: RR(a)
|
|
1327
|
+
1.57079632679490
|
|
1328
|
+
sage: a = LazyNamedUnop(RLF, 9, 'log', extra_args=(3,))
|
|
1329
|
+
sage: RR(a)
|
|
1330
|
+
2.00000000000000
|
|
1331
|
+
"""
|
|
1332
|
+
LazyUnop.__init__(self, parent, arg, op)
|
|
1333
|
+
if extra_args is not None and not isinstance(extra_args, tuple):
|
|
1334
|
+
raise TypeError("extra args must be a tuple")
|
|
1335
|
+
self._extra_args = extra_args
|
|
1336
|
+
|
|
1337
|
+
cpdef eval(self, R):
|
|
1338
|
+
"""
|
|
1339
|
+
Convert ``self`` into an element of ``R``.
|
|
1340
|
+
|
|
1341
|
+
TESTS::
|
|
1342
|
+
|
|
1343
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
1344
|
+
sage: a = LazyNamedUnop(RLF, 4, 'sqrt')
|
|
1345
|
+
sage: RR(a) # indirect doctest
|
|
1346
|
+
2.00000000000000
|
|
1347
|
+
sage: a.sqrt()
|
|
1348
|
+
1.414213562373095?
|
|
1349
|
+
sage: RealField(212)(a)
|
|
1350
|
+
2.00000000000000000000000000000000000000000000000000000000000000
|
|
1351
|
+
sage: float(a)
|
|
1352
|
+
2.0
|
|
1353
|
+
|
|
1354
|
+
Now for some extra arguments::
|
|
1355
|
+
|
|
1356
|
+
sage: a = RLF(100)
|
|
1357
|
+
sage: a.log(10)
|
|
1358
|
+
2
|
|
1359
|
+
sage: float(a.log(10))
|
|
1360
|
+
2.0
|
|
1361
|
+
"""
|
|
1362
|
+
arg = self._arg.eval(R)
|
|
1363
|
+
cdef bint has_extra_args = self._extra_args is not None and len(self._extra_args) > 0
|
|
1364
|
+
if type(R) is type:
|
|
1365
|
+
f = getattr(math, self._op)
|
|
1366
|
+
if has_extra_args:
|
|
1367
|
+
return f(arg, *self._extra_args)
|
|
1368
|
+
else:
|
|
1369
|
+
return f(arg)
|
|
1370
|
+
else:
|
|
1371
|
+
f = getattr(arg, self._op)
|
|
1372
|
+
if has_extra_args:
|
|
1373
|
+
return f(*self._extra_args)
|
|
1374
|
+
else:
|
|
1375
|
+
return f()
|
|
1376
|
+
|
|
1377
|
+
def approx(self):
|
|
1378
|
+
"""
|
|
1379
|
+
Do something reasonable with functions that are not defined on the
|
|
1380
|
+
interval fields.
|
|
1381
|
+
|
|
1382
|
+
TESTS::
|
|
1383
|
+
|
|
1384
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
1385
|
+
sage: LazyNamedUnop(RLF, 8, 'sqrt') # indirect doctest
|
|
1386
|
+
2.828427124746190?
|
|
1387
|
+
"""
|
|
1388
|
+
try:
|
|
1389
|
+
return LazyUnop.approx(self)
|
|
1390
|
+
except AttributeError:
|
|
1391
|
+
# not everything defined on interval fields
|
|
1392
|
+
# this is less info though, but mostly just want to print it
|
|
1393
|
+
interval_field = self._parent.interval_field()
|
|
1394
|
+
return self.eval(interval_field.middle_field())
|
|
1395
|
+
|
|
1396
|
+
def __hash__(self):
|
|
1397
|
+
"""
|
|
1398
|
+
Return the hash value of ``self``.
|
|
1399
|
+
|
|
1400
|
+
EXAMPLES::
|
|
1401
|
+
|
|
1402
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
1403
|
+
sage: a = LazyNamedUnop(RLF, 1, 'sin')
|
|
1404
|
+
sage: b = LazyNamedUnop(RLF, 1, 'cos')
|
|
1405
|
+
sage: hash(a) == hash(b)
|
|
1406
|
+
False
|
|
1407
|
+
"""
|
|
1408
|
+
return hash(complex(self))
|
|
1409
|
+
|
|
1410
|
+
def __float__(self):
|
|
1411
|
+
"""
|
|
1412
|
+
TESTS::
|
|
1413
|
+
|
|
1414
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
1415
|
+
sage: a = LazyNamedUnop(RLF, 1, 'sin')
|
|
1416
|
+
sage: float(a)
|
|
1417
|
+
0.8414709848078965
|
|
1418
|
+
"""
|
|
1419
|
+
return self.eval(float)
|
|
1420
|
+
|
|
1421
|
+
def __call__(self, *args):
|
|
1422
|
+
"""
|
|
1423
|
+
TESTS::
|
|
1424
|
+
|
|
1425
|
+
sage: a = RLF(32)
|
|
1426
|
+
sage: a.log(2)
|
|
1427
|
+
5
|
|
1428
|
+
sage: float(a.log(2))
|
|
1429
|
+
5.0
|
|
1430
|
+
|
|
1431
|
+
What is going on here in the background is::
|
|
1432
|
+
|
|
1433
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
1434
|
+
sage: b = LazyNamedUnop(RLF, a, 'log')
|
|
1435
|
+
sage: b(2)
|
|
1436
|
+
5
|
|
1437
|
+
sage: b(2)._extra_args
|
|
1438
|
+
(2,)
|
|
1439
|
+
"""
|
|
1440
|
+
self._extra_args = args
|
|
1441
|
+
return self
|
|
1442
|
+
|
|
1443
|
+
def __reduce__(self):
|
|
1444
|
+
"""
|
|
1445
|
+
TESTS::
|
|
1446
|
+
|
|
1447
|
+
sage: from sage.rings.real_lazy import LazyNamedUnop
|
|
1448
|
+
sage: a = LazyNamedUnop(RLF, 1, 'sin')
|
|
1449
|
+
sage: float(loads(dumps(a))) == float(a)
|
|
1450
|
+
True
|
|
1451
|
+
"""
|
|
1452
|
+
return make_element, (LazyNamedUnop, self._parent, self._arg, self._op, self._extra_args)
|
|
1453
|
+
|
|
1454
|
+
cdef class LazyConstant(LazyFieldElement):
|
|
1455
|
+
|
|
1456
|
+
cdef readonly _name
|
|
1457
|
+
cdef readonly _extra_args
|
|
1458
|
+
|
|
1459
|
+
def __init__(self, LazyField parent, name, extra_args=None):
|
|
1460
|
+
"""
|
|
1461
|
+
This class represents a real or complex constant (such as ``pi``
|
|
1462
|
+
or ``I``).
|
|
1463
|
+
|
|
1464
|
+
TESTS::
|
|
1465
|
+
|
|
1466
|
+
sage: a = RLF.pi(); a
|
|
1467
|
+
3.141592653589794?
|
|
1468
|
+
sage: RealField(300)(a)
|
|
1469
|
+
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482
|
|
1470
|
+
|
|
1471
|
+
sage: from sage.rings.real_lazy import LazyConstant
|
|
1472
|
+
sage: a = LazyConstant(RLF, 'euler_constant')
|
|
1473
|
+
sage: RealField(200)(a)
|
|
1474
|
+
0.57721566490153286060651209008240243104215933593992359880577
|
|
1475
|
+
"""
|
|
1476
|
+
LazyFieldElement.__init__(self, parent)
|
|
1477
|
+
self._name = name
|
|
1478
|
+
self._extra_args = extra_args
|
|
1479
|
+
|
|
1480
|
+
cpdef eval(self, R):
|
|
1481
|
+
"""
|
|
1482
|
+
Convert ``self`` into an element of ``R``.
|
|
1483
|
+
|
|
1484
|
+
EXAMPLES::
|
|
1485
|
+
|
|
1486
|
+
sage: from sage.rings.real_lazy import LazyConstant
|
|
1487
|
+
sage: a = LazyConstant(RLF, 'e')
|
|
1488
|
+
sage: RDF(a) # indirect doctest
|
|
1489
|
+
2.718281828459045
|
|
1490
|
+
sage: a = LazyConstant(CLF, 'I')
|
|
1491
|
+
sage: CC(a)
|
|
1492
|
+
1.00000000000000*I
|
|
1493
|
+
|
|
1494
|
+
TESTS:
|
|
1495
|
+
|
|
1496
|
+
Check that :issue:`26839` is fixed::
|
|
1497
|
+
|
|
1498
|
+
sage: RLF.pi().eval(float)
|
|
1499
|
+
3.141592653589793
|
|
1500
|
+
sage: type(RLF.pi().eval(float)) is float
|
|
1501
|
+
True
|
|
1502
|
+
|
|
1503
|
+
sage: RLF.pi().eval(complex)
|
|
1504
|
+
(3.141592653589793+0j)
|
|
1505
|
+
sage: type(RLF.pi().eval(complex)) is complex
|
|
1506
|
+
True
|
|
1507
|
+
|
|
1508
|
+
sage: RLF.pi().eval(RealBallField(128))
|
|
1509
|
+
[3.1415926535897932384626433832795028842 +/- 1.06e-38]
|
|
1510
|
+
|
|
1511
|
+
sage: float(sin(RLF.pi()))
|
|
1512
|
+
1.2246467991473532e-16
|
|
1513
|
+
"""
|
|
1514
|
+
# special handling of e and I
|
|
1515
|
+
if self._name == 'I':
|
|
1516
|
+
if R is float:
|
|
1517
|
+
raise ValueError('I is not a real number')
|
|
1518
|
+
elif R is complex:
|
|
1519
|
+
return 1j
|
|
1520
|
+
else:
|
|
1521
|
+
I = R.gen()
|
|
1522
|
+
if I*I != -R.one():
|
|
1523
|
+
raise TypeError("The complex constant I is not in this complex field.")
|
|
1524
|
+
return I
|
|
1525
|
+
|
|
1526
|
+
elif self._name == 'e':
|
|
1527
|
+
if R is float:
|
|
1528
|
+
return math.e
|
|
1529
|
+
elif R is complex:
|
|
1530
|
+
return complex(math.e)
|
|
1531
|
+
else:
|
|
1532
|
+
return R(1).exp()
|
|
1533
|
+
|
|
1534
|
+
elif R is float:
|
|
1535
|
+
# generic float
|
|
1536
|
+
return getattr(math, self._name)
|
|
1537
|
+
elif R is complex:
|
|
1538
|
+
# generic complex
|
|
1539
|
+
return complex(getattr(cmath, self._name))
|
|
1540
|
+
else:
|
|
1541
|
+
# generic Sage parent
|
|
1542
|
+
f = getattr(R, self._name)
|
|
1543
|
+
if self._extra_args is None:
|
|
1544
|
+
return f()
|
|
1545
|
+
else:
|
|
1546
|
+
return f(*self._extra_args)
|
|
1547
|
+
|
|
1548
|
+
def __call__(self, *args):
|
|
1549
|
+
"""
|
|
1550
|
+
TESTS::
|
|
1551
|
+
|
|
1552
|
+
sage: CLF.I()
|
|
1553
|
+
1*I
|
|
1554
|
+
sage: CDF(CLF.I())
|
|
1555
|
+
1.0*I
|
|
1556
|
+
"""
|
|
1557
|
+
self._extra_args = args
|
|
1558
|
+
return self
|
|
1559
|
+
|
|
1560
|
+
def __hash__(self):
|
|
1561
|
+
"""
|
|
1562
|
+
Return the hash value of ``self``.
|
|
1563
|
+
|
|
1564
|
+
TESTS::
|
|
1565
|
+
|
|
1566
|
+
sage: from sage.rings.real_lazy import LazyConstant
|
|
1567
|
+
sage: a = LazyConstant(RLF, 'e')
|
|
1568
|
+
sage: hash(a) == hash(1)
|
|
1569
|
+
False
|
|
1570
|
+
"""
|
|
1571
|
+
return hash(complex(self))
|
|
1572
|
+
|
|
1573
|
+
def __float__(self):
|
|
1574
|
+
"""
|
|
1575
|
+
TESTS::
|
|
1576
|
+
|
|
1577
|
+
sage: from sage.rings.real_lazy import LazyConstant
|
|
1578
|
+
sage: a = LazyConstant(RLF, 'pi')
|
|
1579
|
+
sage: float(a)
|
|
1580
|
+
3.141592653589793
|
|
1581
|
+
"""
|
|
1582
|
+
interval_field = self._parent.interval_field()
|
|
1583
|
+
return <double>self.eval(interval_field.middle_field())
|
|
1584
|
+
|
|
1585
|
+
def __reduce__(self):
|
|
1586
|
+
"""
|
|
1587
|
+
TESTS::
|
|
1588
|
+
|
|
1589
|
+
sage: from sage.rings.real_lazy import LazyConstant
|
|
1590
|
+
sage: a = LazyConstant(RLF, 'pi')
|
|
1591
|
+
sage: float(loads(dumps(a))) == float(a)
|
|
1592
|
+
True
|
|
1593
|
+
"""
|
|
1594
|
+
return make_element, (LazyConstant, self._parent, self._name, self._extra_args)
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
cdef class LazyAlgebraic(LazyFieldElement):
|
|
1598
|
+
|
|
1599
|
+
cdef readonly _poly
|
|
1600
|
+
cdef readonly _root_approx
|
|
1601
|
+
cdef readonly int _prec
|
|
1602
|
+
cdef readonly _quadratic_disc
|
|
1603
|
+
cdef readonly _root
|
|
1604
|
+
|
|
1605
|
+
def __init__(self, parent, poly, approx, int prec=0):
|
|
1606
|
+
r"""
|
|
1607
|
+
This represents an algebraic number, specified by a polynomial over
|
|
1608
|
+
`\QQ` and a real or complex approximation.
|
|
1609
|
+
|
|
1610
|
+
EXAMPLES::
|
|
1611
|
+
|
|
1612
|
+
sage: x = polygen(QQ)
|
|
1613
|
+
sage: from sage.rings.real_lazy import LazyAlgebraic
|
|
1614
|
+
sage: a = LazyAlgebraic(RLF, x^2-2, 1.5)
|
|
1615
|
+
sage: a
|
|
1616
|
+
1.414213562373095?
|
|
1617
|
+
"""
|
|
1618
|
+
LazyFieldElement.__init__(self, parent)
|
|
1619
|
+
self._poly = QQx()(poly)
|
|
1620
|
+
self._root = None
|
|
1621
|
+
if prec is None:
|
|
1622
|
+
prec = approx.parent().prec()
|
|
1623
|
+
self._prec = prec
|
|
1624
|
+
if self._poly.degree() == 2:
|
|
1625
|
+
c, b, a = self._poly.list()
|
|
1626
|
+
self._quadratic_disc = b*b - 4*a*c
|
|
1627
|
+
|
|
1628
|
+
late_import()
|
|
1629
|
+
|
|
1630
|
+
if isinstance(parent, RealLazyField_class):
|
|
1631
|
+
if not self._poly.number_of_real_roots():
|
|
1632
|
+
raise ValueError("%s has no real roots" % self._poly)
|
|
1633
|
+
approx = (RR if prec == 0 else RealField(prec))(approx)
|
|
1634
|
+
else:
|
|
1635
|
+
approx = (CC if prec == 0 else ComplexField(prec))(approx)
|
|
1636
|
+
self._root_approx = approx
|
|
1637
|
+
|
|
1638
|
+
cpdef eval(self, R):
|
|
1639
|
+
"""
|
|
1640
|
+
Convert ``self`` into an element of ``R``.
|
|
1641
|
+
|
|
1642
|
+
EXAMPLES::
|
|
1643
|
+
|
|
1644
|
+
sage: from sage.rings.real_lazy import LazyAlgebraic
|
|
1645
|
+
sage: a = LazyAlgebraic(CLF, QQ['x'].cyclotomic_polynomial(7), 0.6+0.8*CC.0)
|
|
1646
|
+
sage: a
|
|
1647
|
+
0.6234898018587335? + 0.7818314824680299?*I
|
|
1648
|
+
sage: ComplexField(150)(a) # indirect doctest # needs sage.rings.number_field
|
|
1649
|
+
0.62348980185873353052500488400423981063227473 + 0.78183148246802980870844452667405775023233452*I
|
|
1650
|
+
|
|
1651
|
+
sage: a = LazyAlgebraic(CLF, QQ['x'].0^2-7, -2.0)
|
|
1652
|
+
sage: RR(a) # needs sage.rings.number_field
|
|
1653
|
+
-2.64575131106459
|
|
1654
|
+
sage: RR(a)^2 # needs sage.rings.number_field
|
|
1655
|
+
7.00000000000000
|
|
1656
|
+
"""
|
|
1657
|
+
if isinstance(R, type):
|
|
1658
|
+
if self._prec < 53:
|
|
1659
|
+
self.eval(self.parent().interval_field(64)) # up the prec
|
|
1660
|
+
elif R.is_exact() or self._prec < R.prec():
|
|
1661
|
+
# Carl Witty said:
|
|
1662
|
+
# Quadratic equation faster and more accurate than roots(),
|
|
1663
|
+
# but the current code doesn't do the right thing with interval
|
|
1664
|
+
# arithmetic (it returns a point interval) so it's being disabled
|
|
1665
|
+
# for now
|
|
1666
|
+
# if self._quadratic_disc is not None:
|
|
1667
|
+
# c, b, a = self._poly.list()
|
|
1668
|
+
# if self._root_approx.real() < -b/2*a:
|
|
1669
|
+
# z = (-b - R(self._quadratic_disc).sqrt()) / (2*a)
|
|
1670
|
+
# else:
|
|
1671
|
+
# z = (-b + R(self._quadratic_disc).sqrt()) / (2*a)
|
|
1672
|
+
# if z.parent() is not R:
|
|
1673
|
+
# z = R(z)
|
|
1674
|
+
# self._root_approx = z
|
|
1675
|
+
# from sage.rings.complex_interval_field import is_IntervalField
|
|
1676
|
+
# if is_IntervalField(R):
|
|
1677
|
+
# self._root_approx = (self._root_approx.upper() + self._root_approx.lower()) / 2
|
|
1678
|
+
# self._prec = R.prec()
|
|
1679
|
+
# return R(self._root_approx)
|
|
1680
|
+
if self._root is None:
|
|
1681
|
+
# This could be done much more efficiently with Newton iteration,
|
|
1682
|
+
# but will require some care to make sure we get the right root, and
|
|
1683
|
+
# to the correct precision.
|
|
1684
|
+
from sage.rings.qqbar import AA, QQbar
|
|
1685
|
+
roots = self._poly.roots(ring = AA if isinstance(self._parent, RealLazyField_class) else QQbar)
|
|
1686
|
+
best_root = roots[0][0]
|
|
1687
|
+
min_dist = abs(self._root_approx - best_root)
|
|
1688
|
+
for r, e in roots[1:]:
|
|
1689
|
+
dist = abs(self._root_approx - r)
|
|
1690
|
+
if dist < min_dist:
|
|
1691
|
+
best_root = r
|
|
1692
|
+
min_dist = dist
|
|
1693
|
+
self._root = best_root
|
|
1694
|
+
if self._root is not None:
|
|
1695
|
+
return R(self._root)
|
|
1696
|
+
|
|
1697
|
+
def __float__(self):
|
|
1698
|
+
"""
|
|
1699
|
+
TESTS::
|
|
1700
|
+
|
|
1701
|
+
sage: x = polygen(QQ)
|
|
1702
|
+
sage: from sage.rings.real_lazy import LazyAlgebraic
|
|
1703
|
+
sage: a = LazyAlgebraic(RLF, x^3-10, 1.5)
|
|
1704
|
+
sage: float(a)
|
|
1705
|
+
2.154434690031883...
|
|
1706
|
+
"""
|
|
1707
|
+
return self.eval(float)
|
|
1708
|
+
|
|
1709
|
+
def __reduce__(self):
|
|
1710
|
+
"""
|
|
1711
|
+
TESTS::
|
|
1712
|
+
|
|
1713
|
+
sage: from sage.rings.real_lazy import LazyAlgebraic
|
|
1714
|
+
sage: x = polygen(QQ)
|
|
1715
|
+
sage: a = LazyAlgebraic(RLF, x^2 - 2, 1.5)
|
|
1716
|
+
sage: float(loads(dumps(a))) == float(a)
|
|
1717
|
+
True
|
|
1718
|
+
"""
|
|
1719
|
+
return make_element, (LazyAlgebraic, self._parent, self._poly, self._root_approx, self._prec)
|
|
1720
|
+
|
|
1721
|
+
|
|
1722
|
+
cdef class LazyWrapperMorphism(Morphism):
|
|
1723
|
+
|
|
1724
|
+
def __init__(self, domain, LazyField codomain):
|
|
1725
|
+
"""
|
|
1726
|
+
This morphism coerces elements from anywhere into lazy rings
|
|
1727
|
+
by creating a wrapper element (as fast as possible).
|
|
1728
|
+
|
|
1729
|
+
EXAMPLES::
|
|
1730
|
+
|
|
1731
|
+
sage: from sage.rings.real_lazy import LazyWrapperMorphism
|
|
1732
|
+
sage: f = LazyWrapperMorphism(QQ, RLF)
|
|
1733
|
+
sage: a = f(3); a
|
|
1734
|
+
3
|
|
1735
|
+
sage: type(a)
|
|
1736
|
+
<class 'sage.rings.real_lazy.LazyWrapper'>
|
|
1737
|
+
sage: a._value
|
|
1738
|
+
3
|
|
1739
|
+
sage: a._value.parent()
|
|
1740
|
+
Rational Field
|
|
1741
|
+
"""
|
|
1742
|
+
from sage.categories.homset import Hom
|
|
1743
|
+
Morphism.__init__(self, Hom(domain, codomain))
|
|
1744
|
+
|
|
1745
|
+
cpdef Element _call_(self, x):
|
|
1746
|
+
"""
|
|
1747
|
+
EXAMPLES::
|
|
1748
|
+
|
|
1749
|
+
sage: from sage.rings.real_lazy import LazyWrapperMorphism
|
|
1750
|
+
sage: f = LazyWrapperMorphism(QQ, CLF)
|
|
1751
|
+
sage: a = f(1/3); a # indirect doctest
|
|
1752
|
+
0.3333333333333334?
|
|
1753
|
+
sage: type(a)
|
|
1754
|
+
<class 'sage.rings.real_lazy.LazyWrapper'>
|
|
1755
|
+
sage: Reals(100)(a)
|
|
1756
|
+
0.33333333333333333333333333333
|
|
1757
|
+
|
|
1758
|
+
Note that it doesn't double-wrap lazy elements::
|
|
1759
|
+
|
|
1760
|
+
sage: f = LazyWrapperMorphism(RLF, CLF)
|
|
1761
|
+
sage: x = RLF(20)
|
|
1762
|
+
sage: f(x)
|
|
1763
|
+
20
|
|
1764
|
+
sage: f(x)._value
|
|
1765
|
+
20
|
|
1766
|
+
"""
|
|
1767
|
+
cdef LazyWrapper e = <LazyWrapper>LazyWrapper.__new__(LazyWrapper)
|
|
1768
|
+
e._parent = self._codomain
|
|
1769
|
+
if type(x) is LazyWrapper:
|
|
1770
|
+
e._value = (<LazyWrapper>x)._value
|
|
1771
|
+
else:
|
|
1772
|
+
e._value = x
|
|
1773
|
+
return e
|