passagemath-pari 10.6.32__cp314-cp314-musllinux_1_2_x86_64.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.
Potentially problematic release.
This version of passagemath-pari might be problematic. Click here for more details.
- PARIKernel/__init__.py +2 -0
- PARIKernel/__main__.py +5 -0
- PARIKernel/io.cpython-314-x86_64-linux-musl.so +0 -0
- PARIKernel/io.pxd +7 -0
- PARIKernel/io.pyx +84 -0
- PARIKernel/kernel.cpython-314-x86_64-linux-musl.so +0 -0
- PARIKernel/kernel.pyx +260 -0
- PARIKernel/paridecl.pxd +95 -0
- PARIKernel/svg.cpython-314-x86_64-linux-musl.so +0 -0
- PARIKernel/svg.pyx +52 -0
- cypari2/__init__.py +8 -0
- cypari2/auto_paridecl.pxd +1070 -0
- cypari2/closure.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/closure.pxd +5 -0
- cypari2/closure.pyx +246 -0
- cypari2/convert.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/convert.pxd +80 -0
- cypari2/convert.pyx +613 -0
- cypari2/custom_block.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/custom_block.pyx +30 -0
- cypari2/cypari.h +13 -0
- cypari2/gen.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/gen.pxd +69 -0
- cypari2/gen.pyx +4819 -0
- cypari2/handle_error.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/handle_error.pxd +7 -0
- cypari2/handle_error.pyx +232 -0
- cypari2/pari_instance.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/pari_instance.pxd +27 -0
- cypari2/pari_instance.pyx +1438 -0
- cypari2/paridecl.pxd +5353 -0
- cypari2/paripriv.pxd +34 -0
- cypari2/pycore_long.h +98 -0
- cypari2/pycore_long.pxd +9 -0
- cypari2/stack.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/stack.pxd +27 -0
- cypari2/stack.pyx +278 -0
- cypari2/string_utils.cpython-314-x86_64-linux-musl.so +0 -0
- cypari2/string_utils.pxd +29 -0
- cypari2/string_utils.pyx +65 -0
- cypari2/types.pxd +147 -0
- passagemath_pari-10.6.32.data/data/etc/jupyter/nbconfig/notebook.d/gp-mode.json +5 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.js +28 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.json +6 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/logo-64x64.png +0 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/kernel.json +13 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-32x32.png +0 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-64x64.png +0 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-svg.svg +75 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/gp.js +284 -0
- passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/main.js +15 -0
- passagemath_pari-10.6.32.dist-info/METADATA +209 -0
- passagemath_pari-10.6.32.dist-info/RECORD +331 -0
- passagemath_pari-10.6.32.dist-info/WHEEL +5 -0
- passagemath_pari-10.6.32.dist-info/top_level.txt +4 -0
- passagemath_pari.libs/libcrypto-f04afe95.so.3 +0 -0
- passagemath_pari.libs/libflint-fd6f12fc.so.21.0.0 +0 -0
- passagemath_pari.libs/libgcc_s-0cd532bd.so.1 +0 -0
- passagemath_pari.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
- passagemath_pari.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
- passagemath_pari.libs/libgivaro-9a94c711.so.9.2.1 +0 -0
- passagemath_pari.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_pari.libs/libgmpxx-9e08595c.so.4.7.0 +0 -0
- passagemath_pari.libs/libgsl-42cda06f.so.28.0.0 +0 -0
- passagemath_pari.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
- passagemath_pari.libs/libncursesw-9c9e32c3.so.6.5 +0 -0
- passagemath_pari.libs/libntl-26885ca2.so.44.0.1 +0 -0
- passagemath_pari.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
- passagemath_pari.libs/libpari-gmp-tls-f31f908f.so.2.17.2 +0 -0
- passagemath_pari.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
- passagemath_pari.libs/libreadline-06542304.so.8.2 +0 -0
- passagemath_pari.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
- passagemath_pari.libs/libuuid-f3770415.so.1.3.0 +0 -0
- passagemath_pari.libs/libxeus-735780ff.so.13.1.0 +0 -0
- passagemath_pari.libs/libxeus-zmq-c68577b4.so.6.0.1 +0 -0
- passagemath_pari.libs/libzmq-1ba9a3da.so.5.2.5 +0 -0
- sage/all__sagemath_pari.py +26 -0
- sage/databases/all__sagemath_pari.py +7 -0
- sage/databases/conway.py +274 -0
- sage/ext/all__sagemath_pari.py +1 -0
- sage/ext/memory.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/memory.pyx +98 -0
- sage/ext_data/pari/buzzard/DimensionSk.g +286 -0
- sage/ext_data/pari/buzzard/Tpprog.g +179 -0
- sage/ext_data/pari/buzzard/genusn.g +129 -0
- sage/ext_data/pari/dokchitser/computel.gp +740 -0
- sage/ext_data/pari/dokchitser/computel.gp.template +740 -0
- sage/ext_data/pari/dokchitser/ex-bsw +43 -0
- sage/ext_data/pari/dokchitser/ex-chgen +48 -0
- sage/ext_data/pari/dokchitser/ex-chqua +37 -0
- sage/ext_data/pari/dokchitser/ex-delta +35 -0
- sage/ext_data/pari/dokchitser/ex-eisen +30 -0
- sage/ext_data/pari/dokchitser/ex-gen2 +38 -0
- sage/ext_data/pari/dokchitser/ex-gen3 +49 -0
- sage/ext_data/pari/dokchitser/ex-gen4 +54 -0
- sage/ext_data/pari/dokchitser/ex-nf +48 -0
- sage/ext_data/pari/dokchitser/ex-shin +50 -0
- sage/ext_data/pari/dokchitser/ex-tau2 +30 -0
- sage/ext_data/pari/dokchitser/ex-zeta +27 -0
- sage/ext_data/pari/dokchitser/ex-zeta2 +47 -0
- sage/ext_data/pari/dokchitser/testall +13 -0
- sage/ext_data/pari/simon/ell.gp +2129 -0
- sage/ext_data/pari/simon/ellQ.gp +2151 -0
- sage/ext_data/pari/simon/ellcommon.gp +126 -0
- sage/ext_data/pari/simon/qfsolve.gp +722 -0
- sage/ext_data/pari/simon/resultant3.gp +306 -0
- sage/groups/all__sagemath_pari.py +3 -0
- sage/groups/pari_group.py +175 -0
- sage/interfaces/all__sagemath_pari.py +1 -0
- sage/interfaces/genus2reduction.py +464 -0
- sage/interfaces/gp.py +1114 -0
- sage/libs/all__sagemath_pari.py +2 -0
- sage/libs/linkages/__init__.py +1 -0
- sage/libs/linkages/padics/API.pxi +617 -0
- sage/libs/linkages/padics/Polynomial_ram.pxi +388 -0
- sage/libs/linkages/padics/Polynomial_shared.pxi +554 -0
- sage/libs/linkages/padics/__init__.py +1 -0
- sage/libs/linkages/padics/fmpz_poly_unram.pxi +869 -0
- sage/libs/linkages/padics/mpz.pxi +691 -0
- sage/libs/linkages/padics/relaxed/API.pxi +518 -0
- sage/libs/linkages/padics/relaxed/__init__.py +1 -0
- sage/libs/linkages/padics/relaxed/flint.pxi +543 -0
- sage/libs/linkages/padics/unram_shared.pxi +247 -0
- sage/libs/pari/__init__.py +210 -0
- sage/libs/pari/all.py +5 -0
- sage/libs/pari/convert_flint.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/convert_flint.pxd +14 -0
- sage/libs/pari/convert_flint.pyx +159 -0
- sage/libs/pari/convert_gmp.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/convert_gmp.pxd +14 -0
- sage/libs/pari/convert_gmp.pyx +210 -0
- sage/libs/pari/convert_sage.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/convert_sage.pxd +16 -0
- sage/libs/pari/convert_sage.pyx +588 -0
- sage/libs/pari/convert_sage_complex_double.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/convert_sage_complex_double.pxd +14 -0
- sage/libs/pari/convert_sage_complex_double.pyx +132 -0
- sage/libs/pari/convert_sage_matrix.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/convert_sage_matrix.pyx +106 -0
- sage/libs/pari/convert_sage_real_double.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/convert_sage_real_double.pxd +5 -0
- sage/libs/pari/convert_sage_real_double.pyx +14 -0
- sage/libs/pari/convert_sage_real_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/convert_sage_real_mpfr.pxd +7 -0
- sage/libs/pari/convert_sage_real_mpfr.pyx +108 -0
- sage/libs/pari/misc.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/pari/misc.pxd +4 -0
- sage/libs/pari/misc.pyx +26 -0
- sage/libs/pari/tests.py +1848 -0
- sage/matrix/all__sagemath_pari.py +1 -0
- sage/matrix/matrix_integer_pari.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_integer_pari.pyx +187 -0
- sage/matrix/matrix_rational_pari.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_rational_pari.pyx +160 -0
- sage/quadratic_forms/all__sagemath_pari.py +10 -0
- sage/quadratic_forms/genera/all.py +9 -0
- sage/quadratic_forms/genera/genus.py +3506 -0
- sage/quadratic_forms/genera/normal_form.py +1519 -0
- sage/quadratic_forms/genera/spinor_genus.py +243 -0
- sage/quadratic_forms/qfsolve.py +255 -0
- sage/quadratic_forms/quadratic_form__automorphisms.py +427 -0
- sage/quadratic_forms/quadratic_form__genus.py +141 -0
- sage/quadratic_forms/quadratic_form__local_density_interfaces.py +140 -0
- sage/quadratic_forms/quadratic_form__local_normal_form.py +421 -0
- sage/quadratic_forms/quadratic_form__local_representation_conditions.py +889 -0
- sage/quadratic_forms/quadratic_form__mass.py +69 -0
- sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +663 -0
- sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +373 -0
- sage/quadratic_forms/quadratic_form__siegel_product.py +198 -0
- sage/quadratic_forms/special_values.py +323 -0
- sage/rings/all__sagemath_pari.py +15 -0
- sage/rings/factorint_pari.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/factorint_pari.pyx +80 -0
- sage/rings/finite_rings/all__sagemath_pari.py +1 -0
- sage/rings/finite_rings/element_givaro.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_givaro.pxd +91 -0
- sage/rings/finite_rings/element_givaro.pyx +1769 -0
- sage/rings/finite_rings/element_ntl_gf2e.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_ntl_gf2e.pxd +22 -0
- sage/rings/finite_rings/element_ntl_gf2e.pyx +1333 -0
- sage/rings/finite_rings/element_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/finite_rings/element_pari_ffelt.pxd +13 -0
- sage/rings/finite_rings/element_pari_ffelt.pyx +1441 -0
- sage/rings/finite_rings/finite_field_givaro.py +612 -0
- sage/rings/finite_rings/finite_field_pari_ffelt.py +238 -0
- sage/rings/finite_rings/hom_finite_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/finite_rings/hom_finite_field_givaro.pxd +28 -0
- sage/rings/finite_rings/hom_finite_field_givaro.pyx +280 -0
- sage/rings/finite_rings/residue_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field_givaro.pyx +133 -0
- sage/rings/finite_rings/residue_field_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/finite_rings/residue_field_pari_ffelt.pyx +128 -0
- sage/rings/function_field/all__sagemath_pari.py +1 -0
- sage/rings/function_field/valuation.py +1450 -0
- sage/rings/function_field/valuation_ring.py +212 -0
- sage/rings/number_field/all__sagemath_pari.py +14 -0
- sage/rings/number_field/totallyreal.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/number_field/totallyreal.pyx +509 -0
- sage/rings/number_field/totallyreal_data.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/number_field/totallyreal_data.pxd +26 -0
- sage/rings/number_field/totallyreal_data.pyx +928 -0
- sage/rings/number_field/totallyreal_phc.py +144 -0
- sage/rings/number_field/totallyreal_rel.py +1018 -0
- sage/rings/padics/CA_template.pxi +1847 -0
- sage/rings/padics/CA_template_header.pxi +50 -0
- sage/rings/padics/CR_template.pxi +2563 -0
- sage/rings/padics/CR_template_header.pxi +57 -0
- sage/rings/padics/FM_template.pxi +1575 -0
- sage/rings/padics/FM_template_header.pxi +50 -0
- sage/rings/padics/FP_template.pxi +2176 -0
- sage/rings/padics/FP_template_header.pxi +57 -0
- sage/rings/padics/all.py +3 -0
- sage/rings/padics/all__sagemath_pari.py +11 -0
- sage/rings/padics/common_conversion.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/common_conversion.pxd +15 -0
- sage/rings/padics/common_conversion.pyx +508 -0
- sage/rings/padics/eisenstein_extension_generic.py +232 -0
- sage/rings/padics/factory.py +3623 -0
- sage/rings/padics/generic_nodes.py +1615 -0
- sage/rings/padics/lattice_precision.py +2889 -0
- sage/rings/padics/morphism.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/morphism.pxd +11 -0
- sage/rings/padics/morphism.pyx +366 -0
- sage/rings/padics/padic_base_generic.py +467 -0
- sage/rings/padics/padic_base_leaves.py +1235 -0
- sage/rings/padics/padic_capped_absolute_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_capped_absolute_element.pxd +15 -0
- sage/rings/padics/padic_capped_absolute_element.pyx +520 -0
- sage/rings/padics/padic_capped_relative_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_capped_relative_element.pxd +14 -0
- sage/rings/padics/padic_capped_relative_element.pyx +614 -0
- sage/rings/padics/padic_extension_generic.py +990 -0
- sage/rings/padics/padic_extension_leaves.py +738 -0
- sage/rings/padics/padic_fixed_mod_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_fixed_mod_element.pxd +15 -0
- sage/rings/padics/padic_fixed_mod_element.pyx +584 -0
- sage/rings/padics/padic_floating_point_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_floating_point_element.pxd +14 -0
- sage/rings/padics/padic_floating_point_element.pyx +447 -0
- sage/rings/padics/padic_generic_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_generic_element.pxd +48 -0
- sage/rings/padics/padic_generic_element.pyx +4642 -0
- sage/rings/padics/padic_lattice_element.py +1342 -0
- sage/rings/padics/padic_printing.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_printing.pxd +38 -0
- sage/rings/padics/padic_printing.pyx +1505 -0
- sage/rings/padics/padic_relaxed_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_relaxed_element.pxd +56 -0
- sage/rings/padics/padic_relaxed_element.pyx +18 -0
- sage/rings/padics/padic_relaxed_errors.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/padic_relaxed_errors.pxd +11 -0
- sage/rings/padics/padic_relaxed_errors.pyx +71 -0
- sage/rings/padics/padic_template_element.pxi +1212 -0
- sage/rings/padics/padic_template_element_header.pxi +50 -0
- sage/rings/padics/padic_valuation.py +1423 -0
- sage/rings/padics/pow_computer_flint.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer_flint.pxd +38 -0
- sage/rings/padics/pow_computer_flint.pyx +641 -0
- sage/rings/padics/pow_computer_relative.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/pow_computer_relative.pxd +29 -0
- sage/rings/padics/pow_computer_relative.pyx +415 -0
- sage/rings/padics/qadic_flint_CA.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/qadic_flint_CA.pxd +21 -0
- sage/rings/padics/qadic_flint_CA.pyx +130 -0
- sage/rings/padics/qadic_flint_CR.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/qadic_flint_CR.pxd +13 -0
- sage/rings/padics/qadic_flint_CR.pyx +172 -0
- sage/rings/padics/qadic_flint_FM.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/qadic_flint_FM.pxd +14 -0
- sage/rings/padics/qadic_flint_FM.pyx +111 -0
- sage/rings/padics/qadic_flint_FP.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/qadic_flint_FP.pxd +12 -0
- sage/rings/padics/qadic_flint_FP.pyx +165 -0
- sage/rings/padics/relative_extension_leaves.py +429 -0
- sage/rings/padics/relative_ramified_CA.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/relative_ramified_CA.pxd +9 -0
- sage/rings/padics/relative_ramified_CA.pyx +33 -0
- sage/rings/padics/relative_ramified_CR.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/relative_ramified_CR.pxd +8 -0
- sage/rings/padics/relative_ramified_CR.pyx +33 -0
- sage/rings/padics/relative_ramified_FM.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/relative_ramified_FM.pxd +9 -0
- sage/rings/padics/relative_ramified_FM.pyx +33 -0
- sage/rings/padics/relative_ramified_FP.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/padics/relative_ramified_FP.pxd +8 -0
- sage/rings/padics/relative_ramified_FP.pyx +33 -0
- sage/rings/padics/relaxed_template.pxi +4229 -0
- sage/rings/padics/relaxed_template_header.pxi +160 -0
- sage/rings/padics/tests.py +35 -0
- sage/rings/padics/tutorial.py +341 -0
- sage/rings/padics/unramified_extension_generic.py +335 -0
- sage/rings/padics/witt_vector.py +917 -0
- sage/rings/padics/witt_vector_ring.py +934 -0
- sage/rings/pari_ring.py +235 -0
- sage/rings/polynomial/all__sagemath_pari.py +1 -0
- sage/rings/polynomial/padics/all.py +1 -0
- sage/rings/polynomial/padics/polynomial_padic.py +360 -0
- sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +1324 -0
- sage/rings/polynomial/padics/polynomial_padic_flat.py +72 -0
- sage/rings/power_series_pari.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/power_series_pari.pxd +6 -0
- sage/rings/power_series_pari.pyx +934 -0
- sage/rings/tate_algebra.py +1282 -0
- sage/rings/tate_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/tate_algebra_element.pxd +49 -0
- sage/rings/tate_algebra_element.pyx +3464 -0
- sage/rings/tate_algebra_ideal.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/tate_algebra_ideal.pxd +7 -0
- sage/rings/tate_algebra_ideal.pyx +1307 -0
- sage/rings/valuation/all.py +7 -0
- sage/rings/valuation/augmented_valuation.py +2118 -0
- sage/rings/valuation/developing_valuation.py +362 -0
- sage/rings/valuation/gauss_valuation.py +812 -0
- sage/rings/valuation/inductive_valuation.py +1686 -0
- sage/rings/valuation/limit_valuation.py +946 -0
- sage/rings/valuation/mapped_valuation.py +656 -0
- sage/rings/valuation/scaled_valuation.py +322 -0
- sage/rings/valuation/trivial_valuation.py +382 -0
- sage/rings/valuation/valuation.py +1119 -0
- sage/rings/valuation/valuation_space.py +1615 -0
- sage/rings/valuation/valuations_catalog.py +10 -0
- sage/rings/valuation/value_group.py +697 -0
- sage/schemes/all__sagemath_pari.py +1 -0
- sage/schemes/elliptic_curves/all__sagemath_pari.py +1 -0
- sage/schemes/elliptic_curves/descent_two_isogeny_pari.cpython-314-x86_64-linux-musl.so +0 -0
- sage/schemes/elliptic_curves/descent_two_isogeny_pari.pyx +46 -0
- sage_wheels/bin/gp +0 -0
- sage_wheels/bin/gp2c +0 -0
- sage_wheels/bin/gp2c-run +57 -0
- sage_wheels/bin/xeus-gp +0 -0
- sage_wheels/share/gp2c/func.dsc +18414 -0
|
@@ -0,0 +1,2176 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
"""
|
|
3
|
+
Floating point template for complete discrete valuation rings
|
|
4
|
+
|
|
5
|
+
In order to use this template you need to write a linkage file and
|
|
6
|
+
gluing file. For an example see ``mpz_linkage.pxi`` (linkage file) and
|
|
7
|
+
``padic_floating_point_element.pyx`` (gluing file).
|
|
8
|
+
|
|
9
|
+
The linkage file implements a common API that is then used in the
|
|
10
|
+
class :class:`FPElement` defined here. See ``sage/libs/linkages/padics/API.pxi``
|
|
11
|
+
for the functions needed.
|
|
12
|
+
|
|
13
|
+
The gluing file does the following:
|
|
14
|
+
|
|
15
|
+
- ``ctypedef``'s ``celement`` to be the appropriate type (e.g. ``mpz_t``)
|
|
16
|
+
- includes the linkage file
|
|
17
|
+
- includes this template
|
|
18
|
+
- defines a concrete class inheriting from :class:`FPElement`, and implements
|
|
19
|
+
any desired extra methods
|
|
20
|
+
|
|
21
|
+
AUTHORS:
|
|
22
|
+
|
|
23
|
+
- David Roe (2016-03-21) -- initial version
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
#*****************************************************************************
|
|
27
|
+
# Copyright (C) 2007-2016 David Roe <roed.math@gmail.com>
|
|
28
|
+
# William Stein <wstein@gmail.com>
|
|
29
|
+
#
|
|
30
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
31
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
32
|
+
# the License, or (at your option) any later version.
|
|
33
|
+
#
|
|
34
|
+
# http://www.gnu.org/licenses/
|
|
35
|
+
#*****************************************************************************
|
|
36
|
+
|
|
37
|
+
from sage.ext.stdsage cimport PY_NEW
|
|
38
|
+
include "padic_template_element.pxi"
|
|
39
|
+
from cpython.long cimport *
|
|
40
|
+
|
|
41
|
+
from sage.structure.element cimport Element
|
|
42
|
+
from sage.rings.padics.common_conversion cimport comb_prec, _process_args_and_kwds
|
|
43
|
+
from sage.rings.integer_ring import ZZ
|
|
44
|
+
from sage.rings.rational_field import QQ
|
|
45
|
+
from sage.categories.sets_cat import Sets
|
|
46
|
+
from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
|
|
47
|
+
from sage.categories.homset import Hom
|
|
48
|
+
|
|
49
|
+
cdef inline bint overunderflow(long* ordp, celement unit, PowComputer_ prime_pow) noexcept:
|
|
50
|
+
"""
|
|
51
|
+
Check for over and underflow. If detected, sets ordp and unit
|
|
52
|
+
appropriately, and returns True. If not, returns False.
|
|
53
|
+
"""
|
|
54
|
+
if ordp[0] >= maxordp:
|
|
55
|
+
ordp[0] = maxordp
|
|
56
|
+
csetzero(unit, prime_pow)
|
|
57
|
+
elif ordp[0] <= minusmaxordp:
|
|
58
|
+
ordp[0] = minusmaxordp
|
|
59
|
+
csetone(unit, prime_pow)
|
|
60
|
+
else:
|
|
61
|
+
return False
|
|
62
|
+
return True
|
|
63
|
+
|
|
64
|
+
cdef inline bint overunderflow_mpz(long* ordp, mpz_t ordp_mpz, celement unit, PowComputer_ prime_pow) noexcept:
|
|
65
|
+
"""
|
|
66
|
+
Check for over and underflow with an mpz_t ordp. If detected, sets ordp and unit
|
|
67
|
+
appropriately, and returns True. If not, returns False.
|
|
68
|
+
"""
|
|
69
|
+
if mpz_fits_slong_p(ordp_mpz) == 0 or mpz_cmp_si(ordp_mpz, maxordp) >= 0 or mpz_cmp_si(ordp_mpz, minusmaxordp) <= 0:
|
|
70
|
+
if mpz_sgn(ordp_mpz) > 0:
|
|
71
|
+
ordp[0] = maxordp
|
|
72
|
+
csetzero(unit, prime_pow)
|
|
73
|
+
else:
|
|
74
|
+
ordp[0] = minusmaxordp
|
|
75
|
+
csetone(unit, prime_pow)
|
|
76
|
+
return True
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
cdef inline bint very_pos_val(long ordp) noexcept:
|
|
80
|
+
return ordp >= maxordp
|
|
81
|
+
|
|
82
|
+
cdef inline bint very_neg_val(long ordp) noexcept:
|
|
83
|
+
return ordp <= minusmaxordp
|
|
84
|
+
|
|
85
|
+
cdef inline bint huge_val(long ordp) noexcept:
|
|
86
|
+
return very_pos_val(ordp) or very_neg_val(ordp)
|
|
87
|
+
|
|
88
|
+
cdef class FPElement(pAdicTemplateElement):
|
|
89
|
+
cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1:
|
|
90
|
+
"""
|
|
91
|
+
Set the value of this element from given defining data.
|
|
92
|
+
|
|
93
|
+
This function is intended for use in conversion, and should
|
|
94
|
+
not be called on an element created with :meth:`_new_c`.
|
|
95
|
+
|
|
96
|
+
INPUT:
|
|
97
|
+
|
|
98
|
+
- ``x`` -- data defining a `p`-adic element: int, long,
|
|
99
|
+
Integer, Rational, other `p`-adic element...
|
|
100
|
+
|
|
101
|
+
- ``val`` -- the valuation of the resulting element
|
|
102
|
+
|
|
103
|
+
- ``xprec -- an inherent precision of ``x``, if ``val``
|
|
104
|
+
is larger then the result will be zero
|
|
105
|
+
|
|
106
|
+
- ``absprec`` -- an absolute precision cap for this element,
|
|
107
|
+
if ``val`` is larger then the result will be zero
|
|
108
|
+
|
|
109
|
+
- ``relprec`` -- a relative precision cap for this element
|
|
110
|
+
(unused; for compatibility with other `p`-adic precision
|
|
111
|
+
modes)
|
|
112
|
+
|
|
113
|
+
TESTS::
|
|
114
|
+
|
|
115
|
+
sage: R = ZpFP(5)
|
|
116
|
+
sage: a = R(17,5); a # indirect doctest
|
|
117
|
+
2 + 3*5
|
|
118
|
+
sage: R(15) # indirect doctest
|
|
119
|
+
3*5
|
|
120
|
+
|
|
121
|
+
sage: R = ZpFP(5,5)
|
|
122
|
+
sage: a = R(25/9); a # indirect doctest
|
|
123
|
+
4*5^2 + 2*5^3 + 5^5 + 2*5^6
|
|
124
|
+
sage: R(ZpCR(5)(25/9)) == a
|
|
125
|
+
True
|
|
126
|
+
sage: R(5) - R(5)
|
|
127
|
+
0
|
|
128
|
+
|
|
129
|
+
We check that :issue:`23966` is resolved::
|
|
130
|
+
|
|
131
|
+
sage: R = ZpFM(2)
|
|
132
|
+
sage: K = R.fraction_field()
|
|
133
|
+
sage: K(R.zero())
|
|
134
|
+
0
|
|
135
|
+
"""
|
|
136
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
137
|
+
polyt = type(self.prime_pow.modulus)
|
|
138
|
+
self.unit = <celement>polyt.__new__(polyt)
|
|
139
|
+
cconstruct(self.unit, self.prime_pow)
|
|
140
|
+
if val >= xprec or val >= absprec:
|
|
141
|
+
self._set_exact_zero()
|
|
142
|
+
elif very_neg_val(val):
|
|
143
|
+
self._set_infinity()
|
|
144
|
+
else:
|
|
145
|
+
self.ordp = val
|
|
146
|
+
if isinstance(x, FPElement) and x.parent() is self.parent():
|
|
147
|
+
ccopy(self.unit, (<FPElement>x).unit, self.prime_pow)
|
|
148
|
+
else:
|
|
149
|
+
cconv(self.unit, x, self.prime_pow.ram_prec_cap, val, self.prime_pow)
|
|
150
|
+
|
|
151
|
+
cdef int _set_exact_zero(self) except -1:
|
|
152
|
+
"""
|
|
153
|
+
Set this element to zero.
|
|
154
|
+
|
|
155
|
+
TESTS::
|
|
156
|
+
|
|
157
|
+
sage: R = Zp(5); R(0) # indirect doctest
|
|
158
|
+
0
|
|
159
|
+
"""
|
|
160
|
+
csetzero(self.unit, self.prime_pow)
|
|
161
|
+
self.ordp = maxordp
|
|
162
|
+
|
|
163
|
+
cdef int _set_infinity(self) except -1:
|
|
164
|
+
"""
|
|
165
|
+
Set this element to zero.
|
|
166
|
+
|
|
167
|
+
TESTS::
|
|
168
|
+
|
|
169
|
+
sage: R = Zp(5); R(0) # indirect doctest
|
|
170
|
+
0
|
|
171
|
+
"""
|
|
172
|
+
csetone(self.unit, self.prime_pow)
|
|
173
|
+
self.ordp = minusmaxordp
|
|
174
|
+
|
|
175
|
+
cdef FPElement _new_c(self):
|
|
176
|
+
"""
|
|
177
|
+
Create a new element with the same basic info.
|
|
178
|
+
|
|
179
|
+
TESTS::
|
|
180
|
+
|
|
181
|
+
sage: R = ZpFP(5); R(6) * R(7) # indirect doctest
|
|
182
|
+
2 + 3*5 + 5^2
|
|
183
|
+
|
|
184
|
+
sage: # needs sage.libs.flint
|
|
185
|
+
sage: R.<a> = ZqFP(25)
|
|
186
|
+
sage: S.<x> = ZZ[]
|
|
187
|
+
sage: W.<w> = R.ext(x^2 - 5)
|
|
188
|
+
sage: w * (w+1) # indirect doctest
|
|
189
|
+
w + w^2
|
|
190
|
+
"""
|
|
191
|
+
cdef type t = type(self)
|
|
192
|
+
cdef FPElement ans = t.__new__(t)
|
|
193
|
+
ans._parent = self._parent
|
|
194
|
+
ans.prime_pow = self.prime_pow
|
|
195
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
196
|
+
polyt = type(self.prime_pow.modulus)
|
|
197
|
+
ans.unit = <celement>polyt.__new__(polyt)
|
|
198
|
+
cconstruct(ans.unit, ans.prime_pow)
|
|
199
|
+
return ans
|
|
200
|
+
|
|
201
|
+
cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec):
|
|
202
|
+
"""
|
|
203
|
+
Create a new element with a given value and absolute precision.
|
|
204
|
+
|
|
205
|
+
Used by code that doesn't know the precision type.
|
|
206
|
+
"""
|
|
207
|
+
cdef FPElement ans = self._new_c()
|
|
208
|
+
ans.ordp = 0
|
|
209
|
+
ccopy(ans.unit, value, ans.prime_pow)
|
|
210
|
+
ans._normalize()
|
|
211
|
+
return ans
|
|
212
|
+
|
|
213
|
+
cdef int _get_unit(self, celement value) except -1:
|
|
214
|
+
"""
|
|
215
|
+
Set ``value`` to the unit of this `p`-adic element.
|
|
216
|
+
"""
|
|
217
|
+
ccopy(value, self.unit, self.prime_pow)
|
|
218
|
+
|
|
219
|
+
cdef int check_preccap(self) except -1:
|
|
220
|
+
"""
|
|
221
|
+
Check that the precision of this element does not exceed the
|
|
222
|
+
precision cap. Does nothing for floating point elements.
|
|
223
|
+
|
|
224
|
+
TESTS::
|
|
225
|
+
|
|
226
|
+
sage: ZpFP(5)(1).lift_to_precision(30) # indirect doctest
|
|
227
|
+
1
|
|
228
|
+
"""
|
|
229
|
+
pass
|
|
230
|
+
|
|
231
|
+
def __copy__(self):
|
|
232
|
+
"""
|
|
233
|
+
Return a copy of this element.
|
|
234
|
+
|
|
235
|
+
EXAMPLES::
|
|
236
|
+
|
|
237
|
+
sage: a = ZpFP(5,6)(17); b = copy(a)
|
|
238
|
+
sage: a == b
|
|
239
|
+
True
|
|
240
|
+
sage: a is b
|
|
241
|
+
False
|
|
242
|
+
"""
|
|
243
|
+
cdef FPElement ans = self._new_c()
|
|
244
|
+
ans.ordp = self.ordp
|
|
245
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
246
|
+
return ans
|
|
247
|
+
|
|
248
|
+
cdef int _normalize(self) except -1:
|
|
249
|
+
"""
|
|
250
|
+
Normalize this element, so that ``self.ordp`` is correct.
|
|
251
|
+
|
|
252
|
+
TESTS::
|
|
253
|
+
|
|
254
|
+
sage: R = ZpFP(5)
|
|
255
|
+
sage: R(6) + R(4) # indirect doctest
|
|
256
|
+
2*5
|
|
257
|
+
"""
|
|
258
|
+
cdef long diff
|
|
259
|
+
cdef bint is_zero
|
|
260
|
+
if very_pos_val(self.ordp):
|
|
261
|
+
self._set_exact_zero()
|
|
262
|
+
elif very_neg_val(self.ordp):
|
|
263
|
+
self._set_infinity()
|
|
264
|
+
else:
|
|
265
|
+
is_zero = creduce(self.unit, self.unit, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
266
|
+
if is_zero:
|
|
267
|
+
self.ordp = maxordp
|
|
268
|
+
else:
|
|
269
|
+
diff = cremove(self.unit, self.unit, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
270
|
+
self.ordp += diff
|
|
271
|
+
if very_pos_val(self.ordp):
|
|
272
|
+
self._set_exact_zero()
|
|
273
|
+
|
|
274
|
+
def __dealloc__(self):
|
|
275
|
+
"""
|
|
276
|
+
Deallocate the underlying data structure.
|
|
277
|
+
|
|
278
|
+
TESTS::
|
|
279
|
+
|
|
280
|
+
sage: R = ZpFP(5)
|
|
281
|
+
sage: a = R(17)
|
|
282
|
+
sage: del(a)
|
|
283
|
+
"""
|
|
284
|
+
cdestruct(self.unit, self.prime_pow)
|
|
285
|
+
|
|
286
|
+
def __reduce__(self):
|
|
287
|
+
"""
|
|
288
|
+
Return a tuple of a function and data that can be used to unpickle this
|
|
289
|
+
element.
|
|
290
|
+
|
|
291
|
+
EXAMPLES::
|
|
292
|
+
|
|
293
|
+
sage: a = ZpFP(5)(-3)
|
|
294
|
+
sage: type(a)
|
|
295
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicFloatingPointElement'>
|
|
296
|
+
sage: loads(dumps(a)) == a
|
|
297
|
+
True
|
|
298
|
+
"""
|
|
299
|
+
return unpickle_fpe_v2, (self.__class__, self.parent(), cpickle(self.unit, self.prime_pow), self.ordp)
|
|
300
|
+
|
|
301
|
+
# def __richcmp__(self, right, int op):
|
|
302
|
+
# """
|
|
303
|
+
# Compare this element to ``right`` using the comparison operator ``op``.
|
|
304
|
+
#
|
|
305
|
+
# TESTS::
|
|
306
|
+
#
|
|
307
|
+
# sage: R = ZpFP(5)
|
|
308
|
+
# sage: a = R(17)
|
|
309
|
+
# sage: b = R(21)
|
|
310
|
+
# sage: a == b
|
|
311
|
+
# False
|
|
312
|
+
# sage: a < b
|
|
313
|
+
# True
|
|
314
|
+
# """
|
|
315
|
+
# return (<Element>self)._richcmp(right, op)
|
|
316
|
+
|
|
317
|
+
cpdef _neg_(self):
|
|
318
|
+
r"""
|
|
319
|
+
Return the additive inverse of this element.
|
|
320
|
+
|
|
321
|
+
EXAMPLES::
|
|
322
|
+
|
|
323
|
+
sage: R = Zp(7, 4, 'floating-point', 'series')
|
|
324
|
+
sage: -R(7) # indirect doctest
|
|
325
|
+
6*7 + 6*7^2 + 6*7^3 + 6*7^4
|
|
326
|
+
"""
|
|
327
|
+
cdef FPElement ans = self._new_c()
|
|
328
|
+
ans.ordp = self.ordp
|
|
329
|
+
if huge_val(self.ordp): # zero or infinity
|
|
330
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
331
|
+
else:
|
|
332
|
+
cneg(ans.unit, self.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
333
|
+
creduce_small(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
334
|
+
return ans
|
|
335
|
+
|
|
336
|
+
cpdef _add_(self, _right):
|
|
337
|
+
r"""
|
|
338
|
+
Return the sum of this element and ``_right``.
|
|
339
|
+
|
|
340
|
+
EXAMPLES::
|
|
341
|
+
|
|
342
|
+
sage: R = Zp(7, 4, 'floating-point', 'series')
|
|
343
|
+
sage: x = R(1721); x
|
|
344
|
+
6 + 5*7^3
|
|
345
|
+
sage: y = R(1373); y
|
|
346
|
+
1 + 4*7^3
|
|
347
|
+
sage: x + y # indirect doctest
|
|
348
|
+
7 + 2*7^3
|
|
349
|
+
"""
|
|
350
|
+
cdef FPElement ans
|
|
351
|
+
cdef FPElement right = _right
|
|
352
|
+
cdef long tmpL
|
|
353
|
+
if self.ordp == right.ordp:
|
|
354
|
+
ans = self._new_c()
|
|
355
|
+
ans.ordp = self.ordp
|
|
356
|
+
if huge_val(ans.ordp):
|
|
357
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
358
|
+
else:
|
|
359
|
+
cadd(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
360
|
+
ans._normalize() # safer than trying to leave unnormalized
|
|
361
|
+
else:
|
|
362
|
+
if self.ordp > right.ordp:
|
|
363
|
+
# Addition is commutative, swap so self.ordp < right.ordp
|
|
364
|
+
ans = right
|
|
365
|
+
right = self
|
|
366
|
+
self = ans
|
|
367
|
+
tmpL = right.ordp - self.ordp
|
|
368
|
+
if tmpL > self.prime_pow.ram_prec_cap:
|
|
369
|
+
return self
|
|
370
|
+
ans = self._new_c()
|
|
371
|
+
ans.ordp = self.ordp
|
|
372
|
+
if huge_val(ans.ordp):
|
|
373
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
374
|
+
else:
|
|
375
|
+
cshift_notrunc(ans.unit, right.unit, tmpL, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
|
|
376
|
+
cadd(ans.unit, ans.unit, self.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
377
|
+
creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
378
|
+
return ans
|
|
379
|
+
|
|
380
|
+
cpdef _sub_(self, _right):
|
|
381
|
+
r"""
|
|
382
|
+
Return the difference of this element and ``_right``.
|
|
383
|
+
|
|
384
|
+
EXAMPLES::
|
|
385
|
+
|
|
386
|
+
sage: R = Zp(7, 4, 'floating-point', 'series')
|
|
387
|
+
sage: x = R(1721); x
|
|
388
|
+
6 + 5*7^3
|
|
389
|
+
sage: y = R(1373); y
|
|
390
|
+
1 + 4*7^3
|
|
391
|
+
sage: x - y # indirect doctest
|
|
392
|
+
5 + 7^3
|
|
393
|
+
"""
|
|
394
|
+
cdef FPElement ans
|
|
395
|
+
cdef FPElement right = _right
|
|
396
|
+
cdef long tmpL
|
|
397
|
+
if self.ordp == right.ordp:
|
|
398
|
+
ans = self._new_c()
|
|
399
|
+
ans.ordp = self.ordp
|
|
400
|
+
if huge_val(ans.ordp):
|
|
401
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
402
|
+
else:
|
|
403
|
+
csub(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
404
|
+
ans._normalize() # safer than trying to leave unnormalized
|
|
405
|
+
elif self.ordp < right.ordp:
|
|
406
|
+
tmpL = right.ordp - self.ordp
|
|
407
|
+
if tmpL > self.prime_pow.ram_prec_cap:
|
|
408
|
+
return self
|
|
409
|
+
ans = self._new_c()
|
|
410
|
+
ans.ordp = self.ordp
|
|
411
|
+
if huge_val(ans.ordp):
|
|
412
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
413
|
+
else:
|
|
414
|
+
cshift_notrunc(ans.unit, right.unit, tmpL, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
|
|
415
|
+
csub(ans.unit, self.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
416
|
+
creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
417
|
+
else:
|
|
418
|
+
tmpL = self.ordp - right.ordp
|
|
419
|
+
if tmpL > self.prime_pow.ram_prec_cap:
|
|
420
|
+
return right._neg_()
|
|
421
|
+
ans = self._new_c()
|
|
422
|
+
ans.ordp = right.ordp
|
|
423
|
+
if huge_val(ans.ordp):
|
|
424
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
425
|
+
else:
|
|
426
|
+
cshift_notrunc(ans.unit, self.unit, tmpL, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
|
|
427
|
+
csub(ans.unit, ans.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
428
|
+
creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
429
|
+
return ans
|
|
430
|
+
|
|
431
|
+
def __invert__(self):
|
|
432
|
+
r"""
|
|
433
|
+
Return multiplicative inverse of this element.
|
|
434
|
+
|
|
435
|
+
EXAMPLES::
|
|
436
|
+
|
|
437
|
+
sage: R = Zp(7, 4, 'floating-point', 'series')
|
|
438
|
+
sage: ~R(2)
|
|
439
|
+
4 + 3*7 + 3*7^2 + 3*7^3
|
|
440
|
+
sage: ~R(0)
|
|
441
|
+
infinity
|
|
442
|
+
sage: ~R(7)
|
|
443
|
+
7^-1
|
|
444
|
+
"""
|
|
445
|
+
# Input should be normalized!
|
|
446
|
+
cdef FPElement ans = self._new_c()
|
|
447
|
+
if ans.prime_pow.in_field == 0:
|
|
448
|
+
ans._parent = self._parent.fraction_field()
|
|
449
|
+
ans.prime_pow = ans._parent.prime_pow
|
|
450
|
+
ans.ordp = -self.ordp
|
|
451
|
+
if very_pos_val(ans.ordp):
|
|
452
|
+
csetone(ans.unit, ans.prime_pow)
|
|
453
|
+
elif very_neg_val(ans.ordp):
|
|
454
|
+
csetzero(ans.unit, ans.prime_pow)
|
|
455
|
+
else:
|
|
456
|
+
cinvert(ans.unit, self.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
457
|
+
return ans
|
|
458
|
+
|
|
459
|
+
cpdef _mul_(self, _right):
|
|
460
|
+
r"""
|
|
461
|
+
Return the product of this element and ``_right``.
|
|
462
|
+
|
|
463
|
+
EXAMPLES::
|
|
464
|
+
|
|
465
|
+
sage: R = Zp(7, 4, 'floating-point', 'series')
|
|
466
|
+
sage: R(3) * R(2) # indirect doctest
|
|
467
|
+
6
|
|
468
|
+
sage: R(1/2) * R(2)
|
|
469
|
+
1
|
|
470
|
+
"""
|
|
471
|
+
cdef FPElement right = _right
|
|
472
|
+
if very_pos_val(self.ordp):
|
|
473
|
+
if very_neg_val(right.ordp):
|
|
474
|
+
raise ZeroDivisionError("Cannot multiply 0 by infinity")
|
|
475
|
+
return self
|
|
476
|
+
elif very_pos_val(right.ordp):
|
|
477
|
+
if very_neg_val(self.ordp):
|
|
478
|
+
raise ZeroDivisionError("Cannot multiply 0 by infinity")
|
|
479
|
+
return right
|
|
480
|
+
elif very_neg_val(self.ordp):
|
|
481
|
+
return self
|
|
482
|
+
elif very_neg_val(right.ordp):
|
|
483
|
+
return right
|
|
484
|
+
cdef FPElement ans = self._new_c()
|
|
485
|
+
ans.ordp = self.ordp + right.ordp
|
|
486
|
+
if overunderflow(&ans.ordp, ans.unit, ans.prime_pow):
|
|
487
|
+
return ans
|
|
488
|
+
cmul(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
489
|
+
creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
490
|
+
return ans
|
|
491
|
+
|
|
492
|
+
cpdef _div_(self, _right):
|
|
493
|
+
r"""
|
|
494
|
+
Return the quotient of this element and ``right``.
|
|
495
|
+
|
|
496
|
+
EXAMPLES::
|
|
497
|
+
|
|
498
|
+
sage: R = Zp(7, 4, 'floating-point', 'series')
|
|
499
|
+
sage: R(3) / R(2) # indirect doctest
|
|
500
|
+
5 + 3*7 + 3*7^2 + 3*7^3
|
|
501
|
+
sage: R(5) / R(0)
|
|
502
|
+
infinity
|
|
503
|
+
sage: R(7) / R(49)
|
|
504
|
+
7^-1
|
|
505
|
+
"""
|
|
506
|
+
# Input should be normalized!
|
|
507
|
+
cdef FPElement right = _right
|
|
508
|
+
cdef FPElement ans = self._new_c()
|
|
509
|
+
if ans.prime_pow.in_field == 0:
|
|
510
|
+
ans._parent = self._parent.fraction_field()
|
|
511
|
+
ans.prime_pow = ans._parent.prime_pow
|
|
512
|
+
if very_pos_val(self.ordp):
|
|
513
|
+
if very_pos_val(right.ordp):
|
|
514
|
+
raise ZeroDivisionError("Cannot divide 0 by 0")
|
|
515
|
+
ans._set_exact_zero()
|
|
516
|
+
elif very_neg_val(right.ordp):
|
|
517
|
+
if very_neg_val(self.ordp):
|
|
518
|
+
raise ZeroDivisionError("Cannot divide infinity by infinity")
|
|
519
|
+
ans._set_exact_zero()
|
|
520
|
+
elif very_neg_val(self.ordp) or very_pos_val(right.ordp):
|
|
521
|
+
ans._set_infinity()
|
|
522
|
+
else:
|
|
523
|
+
ans.ordp = self.ordp - right.ordp
|
|
524
|
+
if overunderflow(&ans.ordp, ans.unit, ans.prime_pow):
|
|
525
|
+
return ans
|
|
526
|
+
cdivunit(ans.unit, self.unit, right.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
527
|
+
creduce(ans.unit, ans.unit, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
528
|
+
return ans
|
|
529
|
+
|
|
530
|
+
def _quo_rem(self, _right):
|
|
531
|
+
"""
|
|
532
|
+
Quotient with remainder.
|
|
533
|
+
|
|
534
|
+
We choose the remainder to have the same `p`-adic expansion
|
|
535
|
+
as the numerator, but truncated at the valuation of the denominator.
|
|
536
|
+
|
|
537
|
+
EXAMPLES::
|
|
538
|
+
|
|
539
|
+
sage: R = ZpFP(3, 5)
|
|
540
|
+
sage: R(12).quo_rem(R(2)) # indirect doctest
|
|
541
|
+
(2*3, 0)
|
|
542
|
+
sage: R(2).quo_rem(R(12))
|
|
543
|
+
(0, 2)
|
|
544
|
+
sage: q, r = R(4).quo_rem(R(12)); q, r
|
|
545
|
+
(1 + 2*3 + 2*3^3, 1)
|
|
546
|
+
sage: 12*q + r == 4
|
|
547
|
+
True
|
|
548
|
+
|
|
549
|
+
For fields the normal quotient always has remainder 0:
|
|
550
|
+
|
|
551
|
+
sage: K = QpFP(3, 5)
|
|
552
|
+
sage: K(12).quo_rem(K(2))
|
|
553
|
+
(2*3, 0)
|
|
554
|
+
sage: q, r = K(4).quo_rem(K(12)); q, r
|
|
555
|
+
(3^-1, 0)
|
|
556
|
+
sage: 12*q + r == 4
|
|
557
|
+
True
|
|
558
|
+
|
|
559
|
+
You can get the same behavior for fields as for rings
|
|
560
|
+
by using integral=True::
|
|
561
|
+
|
|
562
|
+
sage: K(12).quo_rem(K(2), integral=True)
|
|
563
|
+
(2*3, 0)
|
|
564
|
+
sage: K(2).quo_rem(K(12), integral=True)
|
|
565
|
+
(0, 2)
|
|
566
|
+
"""
|
|
567
|
+
cdef FPElement right = _right
|
|
568
|
+
if very_pos_val(right.ordp):
|
|
569
|
+
raise ZeroDivisionError("Cannot find quo_rem by 0")
|
|
570
|
+
elif very_neg_val(right.ordp):
|
|
571
|
+
raise ZeroDivisionError("Cannot find quo_rem by infinity")
|
|
572
|
+
if huge_val(self.ordp):
|
|
573
|
+
return self, self
|
|
574
|
+
cdef FPElement q = self._new_c()
|
|
575
|
+
cdef FPElement r = self._new_c()
|
|
576
|
+
cdef long diff = self.ordp - right.ordp
|
|
577
|
+
if diff >= 0:
|
|
578
|
+
q.ordp = diff
|
|
579
|
+
cdivunit(q.unit, self.unit, right.unit, q.prime_pow.ram_prec_cap, q.prime_pow)
|
|
580
|
+
r._set_exact_zero()
|
|
581
|
+
else:
|
|
582
|
+
r.ordp = self.ordp
|
|
583
|
+
q.ordp = 0
|
|
584
|
+
cshift(q.prime_pow.shift_rem, r.unit, self.unit, diff, q.prime_pow.ram_prec_cap, q.prime_pow, False)
|
|
585
|
+
cdivunit(q.unit, q.prime_pow.shift_rem, right.unit, q.prime_pow.ram_prec_cap, q.prime_pow)
|
|
586
|
+
q._normalize()
|
|
587
|
+
return q, r
|
|
588
|
+
|
|
589
|
+
def __pow__(FPElement self, _right, dummy): # NOTE: dummy ignored, always use self.prime_pow.ram_prec_cap
|
|
590
|
+
"""
|
|
591
|
+
Exponentiation by an integer
|
|
592
|
+
|
|
593
|
+
EXAMPLES::
|
|
594
|
+
|
|
595
|
+
sage: R = ZpFP(11, 5)
|
|
596
|
+
sage: R(1/2)^5
|
|
597
|
+
10 + 7*11 + 11^2 + 5*11^3 + 4*11^4
|
|
598
|
+
sage: R(1/32)
|
|
599
|
+
10 + 7*11 + 11^2 + 5*11^3 + 4*11^4
|
|
600
|
+
sage: R(1/2)^5 == R(1/32)
|
|
601
|
+
True
|
|
602
|
+
sage: R(3)^1000 # indirect doctest
|
|
603
|
+
1 + 4*11^2 + 3*11^3 + 7*11^4
|
|
604
|
+
sage: R(11)^-1
|
|
605
|
+
11^-1
|
|
606
|
+
|
|
607
|
+
TESTS:
|
|
608
|
+
|
|
609
|
+
Check that :issue:`31875` is fixed::
|
|
610
|
+
|
|
611
|
+
sage: R(1)^R(0)
|
|
612
|
+
1
|
|
613
|
+
|
|
614
|
+
sage: S.<a> = ZqFP(4) # needs sage.libs.flint
|
|
615
|
+
sage: S(1)^S(0) # needs sage.libs.flint
|
|
616
|
+
1
|
|
617
|
+
"""
|
|
618
|
+
cdef long dummyL
|
|
619
|
+
cdef mpz_t tmp
|
|
620
|
+
cdef Integer right
|
|
621
|
+
cdef FPElement base, pright, ans
|
|
622
|
+
cdef bint exact_exp
|
|
623
|
+
if isinstance(_right, (Integer, int, Rational)):
|
|
624
|
+
if _right < 0:
|
|
625
|
+
self = ~self
|
|
626
|
+
_right = -_right
|
|
627
|
+
exact_exp = True
|
|
628
|
+
elif self.parent() is _right.parent():
|
|
629
|
+
# For extension elements, we need to switch to the
|
|
630
|
+
# fraction field sometimes in highly ramified extensions.
|
|
631
|
+
exact_exp = (<FPElement>_right)._is_exact_zero()
|
|
632
|
+
pright = _right
|
|
633
|
+
else:
|
|
634
|
+
self, _right = canonical_coercion(self, _right)
|
|
635
|
+
return self.__pow__(_right, dummy)
|
|
636
|
+
if exact_exp and _right == 0:
|
|
637
|
+
ans = self._new_c()
|
|
638
|
+
ans.ordp = 0
|
|
639
|
+
csetone(ans.unit, ans.prime_pow)
|
|
640
|
+
return ans
|
|
641
|
+
if huge_val(self.ordp):
|
|
642
|
+
if exact_exp:
|
|
643
|
+
# We may assume from above that right > 0
|
|
644
|
+
return self
|
|
645
|
+
else:
|
|
646
|
+
# log(0) and log(infinity) not defined
|
|
647
|
+
raise ValueError("0^x and inf^x not defined for p-adic x")
|
|
648
|
+
ans = self._new_c()
|
|
649
|
+
if exact_exp:
|
|
650
|
+
# exact_pow_helper is defined in padic_template_element.pxi
|
|
651
|
+
right = exact_pow_helper(&dummyL, self.prime_pow.ram_prec_cap, _right, self.prime_pow)
|
|
652
|
+
mpz_init(tmp)
|
|
653
|
+
try:
|
|
654
|
+
mpz_mul_si(tmp, right.value, self.ordp)
|
|
655
|
+
if overunderflow_mpz(&ans.ordp, tmp, ans.unit, ans.prime_pow):
|
|
656
|
+
return ans
|
|
657
|
+
else:
|
|
658
|
+
ans.ordp = mpz_get_si(tmp)
|
|
659
|
+
finally:
|
|
660
|
+
mpz_clear(tmp)
|
|
661
|
+
cpow(ans.unit, self.unit, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
662
|
+
else:
|
|
663
|
+
# padic_pow_helper is defined in padic_template_element.pxi
|
|
664
|
+
dummyL = padic_pow_helper(ans.unit, self.unit, self.ordp, self.prime_pow.ram_prec_cap,
|
|
665
|
+
pright.unit, pright.ordp, pright.prime_pow.ram_prec_cap, self.prime_pow)
|
|
666
|
+
ans.ordp = 0
|
|
667
|
+
return ans
|
|
668
|
+
|
|
669
|
+
cdef pAdicTemplateElement _lshift_c(self, long shift):
|
|
670
|
+
r"""
|
|
671
|
+
Multiply ``self`` by `\pi^{shift}`.
|
|
672
|
+
|
|
673
|
+
Negative shifts may truncate the result if the parent is not a
|
|
674
|
+
field.
|
|
675
|
+
|
|
676
|
+
EXAMPLES:
|
|
677
|
+
|
|
678
|
+
We create a floating point ring::
|
|
679
|
+
|
|
680
|
+
sage: R = ZpFP(5, 20); a = R(1000); a
|
|
681
|
+
3*5^3 + 5^4
|
|
682
|
+
|
|
683
|
+
Shifting to the right is the same as dividing by a power of
|
|
684
|
+
the uniformizer `\pi` of the `p`-adic ring.::
|
|
685
|
+
|
|
686
|
+
sage: a >> 1
|
|
687
|
+
3*5^2 + 5^3
|
|
688
|
+
|
|
689
|
+
Shifting to the left is the same as multiplying by a power of
|
|
690
|
+
`\pi`::
|
|
691
|
+
|
|
692
|
+
sage: a << 2
|
|
693
|
+
3*5^5 + 5^6
|
|
694
|
+
sage: a*5^2
|
|
695
|
+
3*5^5 + 5^6
|
|
696
|
+
|
|
697
|
+
Shifting by a negative integer to the left is the same as
|
|
698
|
+
right shifting by the absolute value::
|
|
699
|
+
|
|
700
|
+
sage: a << -3
|
|
701
|
+
3 + 5
|
|
702
|
+
sage: a >> 3
|
|
703
|
+
3 + 5
|
|
704
|
+
"""
|
|
705
|
+
if shift < 0:
|
|
706
|
+
return self._rshift_c(-shift)
|
|
707
|
+
elif shift == 0:
|
|
708
|
+
return self
|
|
709
|
+
cdef FPElement ans = self._new_c()
|
|
710
|
+
# check both in case of overflow in sum; this case also includes self.ordp = maxordp
|
|
711
|
+
if very_pos_val(shift) or very_pos_val(self.ordp + shift):
|
|
712
|
+
# need to check that we're not shifting infinity
|
|
713
|
+
if very_neg_val(self.ordp):
|
|
714
|
+
raise ZeroDivisionError("Cannot multiply zero by infinity")
|
|
715
|
+
ans.ordp = maxordp
|
|
716
|
+
csetzero(ans.unit, ans.prime_pow)
|
|
717
|
+
else:
|
|
718
|
+
ans.ordp = self.ordp + shift
|
|
719
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
720
|
+
return ans
|
|
721
|
+
|
|
722
|
+
cdef pAdicTemplateElement _rshift_c(self, long shift):
|
|
723
|
+
r"""
|
|
724
|
+
Divide by `\pi^{shift}`.
|
|
725
|
+
|
|
726
|
+
Positive shifts may truncate the result if the parent is not a
|
|
727
|
+
field.
|
|
728
|
+
|
|
729
|
+
EXAMPLES::
|
|
730
|
+
|
|
731
|
+
sage: R = ZpFP(997, 7); a = R(123456878908); a
|
|
732
|
+
964*997 + 572*997^2 + 124*997^3
|
|
733
|
+
|
|
734
|
+
Shifting to the right divides by a power of `\pi`, but
|
|
735
|
+
dropping terms with negative valuation::
|
|
736
|
+
|
|
737
|
+
sage: a >> 3
|
|
738
|
+
124
|
|
739
|
+
|
|
740
|
+
A negative shift multiplies by that power of `\pi`::
|
|
741
|
+
|
|
742
|
+
sage: a >> -3
|
|
743
|
+
964*997^4 + 572*997^5 + 124*997^6
|
|
744
|
+
"""
|
|
745
|
+
if shift == 0:
|
|
746
|
+
return self
|
|
747
|
+
elif very_pos_val(self.ordp):
|
|
748
|
+
if very_pos_val(shift):
|
|
749
|
+
raise ZeroDivisionError("Cannot divide zero by zero")
|
|
750
|
+
return self
|
|
751
|
+
elif very_neg_val(self.ordp):
|
|
752
|
+
if very_neg_val(shift):
|
|
753
|
+
raise ZeroDivisionError("Cannot divide infinity by infinity")
|
|
754
|
+
return self
|
|
755
|
+
cdef FPElement ans = self._new_c()
|
|
756
|
+
cdef long diff
|
|
757
|
+
if self.prime_pow.in_field == 1 or shift <= self.ordp:
|
|
758
|
+
if very_pos_val(shift):
|
|
759
|
+
ans._set_infinity()
|
|
760
|
+
elif very_neg_val(shift):
|
|
761
|
+
ans._set_exact_zero()
|
|
762
|
+
else:
|
|
763
|
+
ans.ordp = self.ordp - shift
|
|
764
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
765
|
+
else:
|
|
766
|
+
diff = shift - self.ordp
|
|
767
|
+
if diff >= self.prime_pow.ram_prec_cap:
|
|
768
|
+
ans._set_exact_zero()
|
|
769
|
+
else:
|
|
770
|
+
ans.ordp = 0
|
|
771
|
+
cshift(ans.unit, ans.prime_pow.shift_rem, self.unit, -diff, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
|
|
772
|
+
ans._normalize()
|
|
773
|
+
return ans
|
|
774
|
+
|
|
775
|
+
def _repr_(self, mode=None, do_latex=False):
|
|
776
|
+
"""
|
|
777
|
+
Return a string representation of this element.
|
|
778
|
+
|
|
779
|
+
INPUT:
|
|
780
|
+
|
|
781
|
+
- ``mode`` -- allows one to override the default print mode of
|
|
782
|
+
the parent (default: ``None``)
|
|
783
|
+
|
|
784
|
+
- ``do_latex`` -- whether to return a latex representation or
|
|
785
|
+
a normal one
|
|
786
|
+
|
|
787
|
+
EXAMPLES::
|
|
788
|
+
|
|
789
|
+
sage: ZpFP(5,5)(1/3) # indirect doctest
|
|
790
|
+
2 + 3*5 + 5^2 + 3*5^3 + 5^4
|
|
791
|
+
sage: ~QpFP(5,5)(0)
|
|
792
|
+
infinity
|
|
793
|
+
"""
|
|
794
|
+
if very_neg_val(self.ordp):
|
|
795
|
+
return "infinity"
|
|
796
|
+
return self.parent()._printer.repr_gen(self, do_latex, mode=mode)
|
|
797
|
+
|
|
798
|
+
def add_bigoh(self, absprec):
|
|
799
|
+
r"""
|
|
800
|
+
Return a new element truncated modulo `\pi^{\mbox{absprec}}`.
|
|
801
|
+
|
|
802
|
+
INPUT:
|
|
803
|
+
|
|
804
|
+
- ``absprec`` -- integer or infinity
|
|
805
|
+
|
|
806
|
+
OUTPUT: a new element truncated modulo `\pi^{\mbox{absprec}}`
|
|
807
|
+
|
|
808
|
+
EXAMPLES::
|
|
809
|
+
|
|
810
|
+
sage: R = Zp(7,4,'floating-point','series'); a = R(8); a.add_bigoh(1)
|
|
811
|
+
1
|
|
812
|
+
"""
|
|
813
|
+
cdef long aprec, newprec
|
|
814
|
+
if absprec is infinity or very_neg_val(self.ordp):
|
|
815
|
+
return self
|
|
816
|
+
elif isinstance(absprec, int):
|
|
817
|
+
aprec = absprec
|
|
818
|
+
else:
|
|
819
|
+
if not isinstance(absprec, Integer):
|
|
820
|
+
absprec = Integer(absprec)
|
|
821
|
+
if mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
822
|
+
if mpz_sgn((<Integer>absprec).value) > 0:
|
|
823
|
+
return self
|
|
824
|
+
aprec = minusmaxordp
|
|
825
|
+
else:
|
|
826
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
827
|
+
if aprec >= self.ordp + self.prime_pow.ram_prec_cap:
|
|
828
|
+
return self
|
|
829
|
+
cdef FPElement ans = self._new_c()
|
|
830
|
+
if aprec <= self.ordp:
|
|
831
|
+
ans._set_exact_zero()
|
|
832
|
+
if aprec < 0:
|
|
833
|
+
return self.parent().fraction_field()(0)
|
|
834
|
+
else:
|
|
835
|
+
ans.ordp = self.ordp
|
|
836
|
+
creduce(ans.unit, self.unit, aprec - self.ordp, ans.prime_pow)
|
|
837
|
+
return ans
|
|
838
|
+
|
|
839
|
+
cpdef bint _is_exact_zero(self) except -1:
|
|
840
|
+
"""
|
|
841
|
+
Test whether this element is exactly zero.
|
|
842
|
+
|
|
843
|
+
EXAMPLES::
|
|
844
|
+
|
|
845
|
+
sage: R = Zp(7,4,'floating-point','series'); a = R(8); a._is_exact_zero()
|
|
846
|
+
False
|
|
847
|
+
sage: b = R(0); b._is_exact_zero()
|
|
848
|
+
True
|
|
849
|
+
"""
|
|
850
|
+
return very_pos_val(self.ordp)
|
|
851
|
+
|
|
852
|
+
cpdef bint _is_inexact_zero(self) except -1:
|
|
853
|
+
"""
|
|
854
|
+
Return ``True`` if ``self`` is indistinguishable from zero.
|
|
855
|
+
|
|
856
|
+
EXAMPLES::
|
|
857
|
+
|
|
858
|
+
sage: R = ZpFP(7, 5)
|
|
859
|
+
sage: R(14)._is_inexact_zero()
|
|
860
|
+
False
|
|
861
|
+
sage: R(0)._is_inexact_zero()
|
|
862
|
+
True
|
|
863
|
+
"""
|
|
864
|
+
return very_pos_val(self.ordp)
|
|
865
|
+
|
|
866
|
+
def is_zero(self, absprec=None):
|
|
867
|
+
r"""
|
|
868
|
+
Return whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`.
|
|
869
|
+
|
|
870
|
+
INPUT:
|
|
871
|
+
|
|
872
|
+
- ``absprec`` -- integer
|
|
873
|
+
|
|
874
|
+
EXAMPLES::
|
|
875
|
+
|
|
876
|
+
sage: R = ZpFP(17, 6)
|
|
877
|
+
sage: R(0).is_zero()
|
|
878
|
+
True
|
|
879
|
+
sage: R(17^6).is_zero()
|
|
880
|
+
False
|
|
881
|
+
sage: R(17^2).is_zero(absprec=2)
|
|
882
|
+
True
|
|
883
|
+
"""
|
|
884
|
+
if absprec is None:
|
|
885
|
+
return very_pos_val(self.ordp)
|
|
886
|
+
if very_pos_val(self.ordp):
|
|
887
|
+
return True
|
|
888
|
+
if absprec is infinity:
|
|
889
|
+
return False
|
|
890
|
+
if isinstance(absprec, int):
|
|
891
|
+
return self.ordp >= absprec
|
|
892
|
+
if not isinstance(absprec, Integer):
|
|
893
|
+
absprec = Integer(absprec)
|
|
894
|
+
return mpz_cmp_si((<Integer>absprec).value, self.ordp) <= 0
|
|
895
|
+
|
|
896
|
+
def __bool__(self):
|
|
897
|
+
"""
|
|
898
|
+
Return ``True`` if this element is distinguishable from zero.
|
|
899
|
+
|
|
900
|
+
For most applications, explicitly specifying the power of `p`
|
|
901
|
+
modulo which the element is supposed to be nonzero is preferable.
|
|
902
|
+
|
|
903
|
+
EXAMPLES::
|
|
904
|
+
|
|
905
|
+
sage: R = ZpFP(5); a = R(0); b = R(75)
|
|
906
|
+
sage: bool(a), bool(b) # indirect doctest
|
|
907
|
+
(False, True)
|
|
908
|
+
"""
|
|
909
|
+
return not very_pos_val(self.ordp)
|
|
910
|
+
|
|
911
|
+
def is_equal_to(self, _right, absprec=None):
|
|
912
|
+
r"""
|
|
913
|
+
Return whether this element is equal to ``right`` modulo `p^{\mbox{absprec}}`.
|
|
914
|
+
|
|
915
|
+
If ``absprec`` is ``None``, determines whether ``self`` and ``right``
|
|
916
|
+
have the same value.
|
|
917
|
+
|
|
918
|
+
INPUT:
|
|
919
|
+
|
|
920
|
+
- ``right`` -- a `p`-adic element with the same parent
|
|
921
|
+
- ``absprec`` -- positive integer or ``None`` (default: ``None``)
|
|
922
|
+
|
|
923
|
+
EXAMPLES::
|
|
924
|
+
|
|
925
|
+
sage: R = ZpFP(2, 6)
|
|
926
|
+
sage: R(13).is_equal_to(R(13))
|
|
927
|
+
True
|
|
928
|
+
sage: R(13).is_equal_to(R(13+2^10))
|
|
929
|
+
True
|
|
930
|
+
sage: R(13).is_equal_to(R(17), 2)
|
|
931
|
+
True
|
|
932
|
+
sage: R(13).is_equal_to(R(17), 5)
|
|
933
|
+
False
|
|
934
|
+
"""
|
|
935
|
+
cdef FPElement right
|
|
936
|
+
cdef long aprec, rprec
|
|
937
|
+
if self.parent() is _right.parent():
|
|
938
|
+
right = _right
|
|
939
|
+
else:
|
|
940
|
+
right = self.parent().coerce(_right)
|
|
941
|
+
if very_neg_val(self.ordp):
|
|
942
|
+
if very_neg_val(right.ordp):
|
|
943
|
+
return True
|
|
944
|
+
return False
|
|
945
|
+
elif very_neg_val(right.ordp):
|
|
946
|
+
return False
|
|
947
|
+
if absprec is None or absprec is infinity:
|
|
948
|
+
return ((self.ordp == right.ordp) and
|
|
949
|
+
(ccmp(self.unit, right.unit, self.prime_pow.ram_prec_cap, False, False, self.prime_pow) == 0))
|
|
950
|
+
if not isinstance(absprec, Integer):
|
|
951
|
+
absprec = Integer(absprec)
|
|
952
|
+
if mpz_cmp_si((<Integer>absprec).value, self.ordp) <= 0:
|
|
953
|
+
if mpz_cmp_si((<Integer>absprec).value, right.ordp) <= 0:
|
|
954
|
+
return True
|
|
955
|
+
return False
|
|
956
|
+
elif mpz_cmp_si((<Integer>absprec).value, right.ordp) <= 0:
|
|
957
|
+
return False
|
|
958
|
+
if self.ordp != right.ordp:
|
|
959
|
+
return False
|
|
960
|
+
if mpz_cmp_si((<Integer>absprec).value, maxordp) >= 0:
|
|
961
|
+
return ccmp(self.unit, right.unit, self.prime_pow.ram_prec_cap, False, False, self.prime_pow) == 0
|
|
962
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
963
|
+
rprec = aprec - self.ordp
|
|
964
|
+
if rprec > self.prime_pow.ram_prec_cap:
|
|
965
|
+
rprec = self.prime_pow.ram_prec_cap
|
|
966
|
+
return ccmp(self.unit,
|
|
967
|
+
right.unit,
|
|
968
|
+
rprec,
|
|
969
|
+
rprec < self.prime_pow.ram_prec_cap,
|
|
970
|
+
rprec < right.prime_pow.ram_prec_cap,
|
|
971
|
+
self.prime_pow) == 0
|
|
972
|
+
|
|
973
|
+
cdef int _cmp_units(self, pAdicGenericElement _right) except -2:
|
|
974
|
+
"""
|
|
975
|
+
Comparison of units, used in equality testing.
|
|
976
|
+
|
|
977
|
+
EXAMPLES::
|
|
978
|
+
|
|
979
|
+
sage: R = ZpFP(5)
|
|
980
|
+
sage: a = R(17); b = R(0,3); c = R(85,7); d = R(2, 1)
|
|
981
|
+
sage: any([a == b, a == c, b == c, b == d, c == d, a == d]) # indirect doctest
|
|
982
|
+
False
|
|
983
|
+
sage: all([a == a, b == b, c == c, d == d])
|
|
984
|
+
True
|
|
985
|
+
"""
|
|
986
|
+
cdef FPElement right = _right
|
|
987
|
+
return ccmp(self.unit, right.unit, self.prime_pow.ram_prec_cap, False, False, self.prime_pow)
|
|
988
|
+
|
|
989
|
+
cdef pAdicTemplateElement lift_to_precision_c(self, long absprec):
|
|
990
|
+
"""
|
|
991
|
+
Lift this element to another with precision at least absprec.
|
|
992
|
+
|
|
993
|
+
Since floating point elements don't track precision, this
|
|
994
|
+
function just returns the same element.
|
|
995
|
+
|
|
996
|
+
EXAMPLES::
|
|
997
|
+
|
|
998
|
+
sage: R = ZpFP(5)
|
|
999
|
+
sage: a = R(77, 2); a
|
|
1000
|
+
2
|
|
1001
|
+
sage: a.lift_to_precision(17) # indirect doctest
|
|
1002
|
+
2
|
|
1003
|
+
"""
|
|
1004
|
+
return self
|
|
1005
|
+
|
|
1006
|
+
def _teichmuller_set_unsafe(self):
|
|
1007
|
+
"""
|
|
1008
|
+
Set this element to the Teichmuller representative with the
|
|
1009
|
+
same residue.
|
|
1010
|
+
|
|
1011
|
+
.. WARNING::
|
|
1012
|
+
|
|
1013
|
+
This function modifies the element, which is not safe.
|
|
1014
|
+
Elements are supposed to be immutable.
|
|
1015
|
+
|
|
1016
|
+
EXAMPLES::
|
|
1017
|
+
|
|
1018
|
+
sage: R = ZpFP(17,5); a = R(11)
|
|
1019
|
+
sage: a
|
|
1020
|
+
11
|
|
1021
|
+
sage: a._teichmuller_set_unsafe(); a
|
|
1022
|
+
11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4
|
|
1023
|
+
sage: E = a.expansion(lift_mode='teichmuller'); E
|
|
1024
|
+
17-adic expansion of 11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4 (teichmuller)
|
|
1025
|
+
sage: list(E)
|
|
1026
|
+
[11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4, 0, 0, 0, 0]
|
|
1027
|
+
|
|
1028
|
+
Note that if you set an element which is congruent to 0 you
|
|
1029
|
+
get 0 to maximum precision::
|
|
1030
|
+
|
|
1031
|
+
sage: b = R(17*5); b
|
|
1032
|
+
5*17
|
|
1033
|
+
sage: b._teichmuller_set_unsafe(); b
|
|
1034
|
+
0
|
|
1035
|
+
"""
|
|
1036
|
+
if self.ordp > 0:
|
|
1037
|
+
self._set_exact_zero()
|
|
1038
|
+
elif self.ordp < 0:
|
|
1039
|
+
raise ValueError("cannot set negative valuation element to Teichmuller representative.")
|
|
1040
|
+
else:
|
|
1041
|
+
cteichmuller(self.unit, self.unit, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
1042
|
+
|
|
1043
|
+
def _polynomial_list(self, pad=False):
|
|
1044
|
+
"""
|
|
1045
|
+
Return the coefficient list for a polynomial over the base ring
|
|
1046
|
+
yielding this element.
|
|
1047
|
+
|
|
1048
|
+
INPUT:
|
|
1049
|
+
|
|
1050
|
+
- ``pad`` -- whether to pad the result with zeros of the appropriate precision
|
|
1051
|
+
|
|
1052
|
+
EXAMPLES::
|
|
1053
|
+
|
|
1054
|
+
sage: # needs sage.libs.flint
|
|
1055
|
+
sage: R.<x> = ZZ[]
|
|
1056
|
+
sage: K.<a> = QqFP(5^3)
|
|
1057
|
+
sage: W.<w> = K.extension(x^3 - 5)
|
|
1058
|
+
sage: (1 + w)._polynomial_list()
|
|
1059
|
+
[1, 1]
|
|
1060
|
+
sage: (1 + w)._polynomial_list(pad=True)
|
|
1061
|
+
[1, 1, 0]
|
|
1062
|
+
"""
|
|
1063
|
+
R = self.base_ring()
|
|
1064
|
+
if very_pos_val(self.ordp):
|
|
1065
|
+
L = []
|
|
1066
|
+
elif very_neg_val(self.ordp):
|
|
1067
|
+
L = [~R(0)]
|
|
1068
|
+
else:
|
|
1069
|
+
L = ccoefficients(self.unit, self.ordp, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
1070
|
+
if pad:
|
|
1071
|
+
n = self.parent().relative_degree()
|
|
1072
|
+
L.extend([R.zero()] * (n - len(L)))
|
|
1073
|
+
return L
|
|
1074
|
+
|
|
1075
|
+
def polynomial(self, var='x'):
|
|
1076
|
+
"""
|
|
1077
|
+
Return a polynomial over the base ring that yields this element
|
|
1078
|
+
when evaluated at the generator of the parent.
|
|
1079
|
+
|
|
1080
|
+
INPUT:
|
|
1081
|
+
|
|
1082
|
+
- ``var`` -- string, the variable name for the polynomial
|
|
1083
|
+
|
|
1084
|
+
EXAMPLES::
|
|
1085
|
+
|
|
1086
|
+
sage: # needs sage.libs.flint
|
|
1087
|
+
sage: K.<a> = QqFP(5^3)
|
|
1088
|
+
sage: a.polynomial()
|
|
1089
|
+
x
|
|
1090
|
+
sage: a.polynomial(var='y')
|
|
1091
|
+
y
|
|
1092
|
+
sage: (5*a^2 + K(25, 4)).polynomial()
|
|
1093
|
+
5*x^2 + 5^2
|
|
1094
|
+
"""
|
|
1095
|
+
R = self.base_ring()
|
|
1096
|
+
S = R[var]
|
|
1097
|
+
return S(self._polynomial_list())
|
|
1098
|
+
|
|
1099
|
+
def precision_absolute(self):
|
|
1100
|
+
"""
|
|
1101
|
+
The absolute precision of this element.
|
|
1102
|
+
|
|
1103
|
+
EXAMPLES::
|
|
1104
|
+
|
|
1105
|
+
sage: R = Zp(7,4,'floating-point'); a = R(7); a.precision_absolute()
|
|
1106
|
+
5
|
|
1107
|
+
sage: R(0).precision_absolute()
|
|
1108
|
+
+Infinity
|
|
1109
|
+
sage: (~R(0)).precision_absolute()
|
|
1110
|
+
-Infinity
|
|
1111
|
+
"""
|
|
1112
|
+
if very_pos_val(self.ordp):
|
|
1113
|
+
return infinity
|
|
1114
|
+
elif very_neg_val(self.ordp):
|
|
1115
|
+
return -infinity
|
|
1116
|
+
cdef Integer ans = PY_NEW(Integer)
|
|
1117
|
+
mpz_set_si(ans.value, self.ordp + self.prime_pow.ram_prec_cap)
|
|
1118
|
+
return ans
|
|
1119
|
+
|
|
1120
|
+
def precision_relative(self):
|
|
1121
|
+
r"""
|
|
1122
|
+
The relative precision of this element.
|
|
1123
|
+
|
|
1124
|
+
EXAMPLES::
|
|
1125
|
+
|
|
1126
|
+
sage: R = Zp(7,4,'floating-point'); a = R(7); a.precision_relative()
|
|
1127
|
+
4
|
|
1128
|
+
sage: R(0).precision_relative()
|
|
1129
|
+
0
|
|
1130
|
+
sage: (~R(0)).precision_relative()
|
|
1131
|
+
0
|
|
1132
|
+
"""
|
|
1133
|
+
cdef Integer ans = PY_NEW(Integer)
|
|
1134
|
+
if huge_val(self.ordp):
|
|
1135
|
+
mpz_set_si(ans.value, 0)
|
|
1136
|
+
else:
|
|
1137
|
+
mpz_set_si(ans.value, self.prime_pow.ram_prec_cap)
|
|
1138
|
+
return ans
|
|
1139
|
+
|
|
1140
|
+
cpdef pAdicTemplateElement unit_part(FPElement self):
|
|
1141
|
+
r"""
|
|
1142
|
+
Return the unit part of this element.
|
|
1143
|
+
|
|
1144
|
+
If the valuation of this element is positive, then the high
|
|
1145
|
+
digits of the result will be zero.
|
|
1146
|
+
|
|
1147
|
+
EXAMPLES::
|
|
1148
|
+
|
|
1149
|
+
sage: R = Zp(17, 4, 'floating-point')
|
|
1150
|
+
sage: R(5).unit_part()
|
|
1151
|
+
5
|
|
1152
|
+
sage: R(18*17).unit_part()
|
|
1153
|
+
1 + 17
|
|
1154
|
+
sage: R(0).unit_part()
|
|
1155
|
+
Traceback (most recent call last):
|
|
1156
|
+
...
|
|
1157
|
+
ValueError: unit part of 0 and infinity not defined
|
|
1158
|
+
sage: type(R(5).unit_part())
|
|
1159
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicFloatingPointElement'>
|
|
1160
|
+
sage: R = ZpFP(5, 5); a = R(75); a.unit_part()
|
|
1161
|
+
3
|
|
1162
|
+
"""
|
|
1163
|
+
if huge_val(self.ordp):
|
|
1164
|
+
raise ValueError("unit part of 0 and infinity not defined")
|
|
1165
|
+
cdef FPElement ans = (<FPElement>self)._new_c()
|
|
1166
|
+
ans.ordp = 0
|
|
1167
|
+
ccopy(ans.unit, (<FPElement>self).unit, ans.prime_pow)
|
|
1168
|
+
return ans
|
|
1169
|
+
|
|
1170
|
+
cdef long valuation_c(self) noexcept:
|
|
1171
|
+
"""
|
|
1172
|
+
Return the valuation of this element.
|
|
1173
|
+
|
|
1174
|
+
If this element is an exact zero, returns ``maxordp``, which is defined as
|
|
1175
|
+
``(1L << (sizeof(long) * 8 - 2))-1``.
|
|
1176
|
+
|
|
1177
|
+
If this element is infinity, returns ``-maxordp``.
|
|
1178
|
+
|
|
1179
|
+
TESTS::
|
|
1180
|
+
|
|
1181
|
+
sage: R = ZpFP(5, 5); R(1).valuation() # indirect doctest
|
|
1182
|
+
0
|
|
1183
|
+
sage: R = Zp(17, 4,'floating-point')
|
|
1184
|
+
sage: a = R(2*17^2)
|
|
1185
|
+
sage: a.valuation()
|
|
1186
|
+
2
|
|
1187
|
+
sage: R = Zp(5, 4,'floating-point')
|
|
1188
|
+
sage: R(0).valuation()
|
|
1189
|
+
+Infinity
|
|
1190
|
+
sage: (~R(0)).valuation()
|
|
1191
|
+
-Infinity
|
|
1192
|
+
sage: R(1).valuation()
|
|
1193
|
+
0
|
|
1194
|
+
sage: R(2).valuation()
|
|
1195
|
+
0
|
|
1196
|
+
sage: R(5).valuation()
|
|
1197
|
+
1
|
|
1198
|
+
sage: R(10).valuation()
|
|
1199
|
+
1
|
|
1200
|
+
sage: R(25).valuation()
|
|
1201
|
+
2
|
|
1202
|
+
sage: R(50).valuation()
|
|
1203
|
+
2
|
|
1204
|
+
"""
|
|
1205
|
+
return self.ordp
|
|
1206
|
+
|
|
1207
|
+
cpdef val_unit(self, p=None):
|
|
1208
|
+
"""
|
|
1209
|
+
Return a 2-tuple, the first element set to the valuation of
|
|
1210
|
+
this element, and the second to the unit part.
|
|
1211
|
+
|
|
1212
|
+
If this element is either zero or infinity, raises an error.
|
|
1213
|
+
|
|
1214
|
+
EXAMPLES::
|
|
1215
|
+
|
|
1216
|
+
sage: R = ZpFP(5,5)
|
|
1217
|
+
sage: a = R(75); b = a - a
|
|
1218
|
+
sage: a.val_unit()
|
|
1219
|
+
(2, 3)
|
|
1220
|
+
sage: b.val_unit()
|
|
1221
|
+
Traceback (most recent call last):
|
|
1222
|
+
...
|
|
1223
|
+
ValueError: unit part of 0 and infinity not defined
|
|
1224
|
+
"""
|
|
1225
|
+
if p is not None and p != self.parent().prime():
|
|
1226
|
+
raise ValueError('Ring (%s) residue field of the wrong characteristic.' % self.parent())
|
|
1227
|
+
if huge_val(self.ordp):
|
|
1228
|
+
raise ValueError("unit part of 0 and infinity not defined")
|
|
1229
|
+
cdef Integer valuation = PY_NEW(Integer)
|
|
1230
|
+
mpz_set_si(valuation.value, self.ordp)
|
|
1231
|
+
cdef FPElement unit = self._new_c()
|
|
1232
|
+
unit.ordp = 0
|
|
1233
|
+
ccopy(unit.unit, self.unit, unit.prime_pow)
|
|
1234
|
+
return valuation, unit
|
|
1235
|
+
|
|
1236
|
+
def __hash__(self):
|
|
1237
|
+
"""
|
|
1238
|
+
Hashing.
|
|
1239
|
+
|
|
1240
|
+
EXAMPLES::
|
|
1241
|
+
|
|
1242
|
+
sage: R = ZpFP(11, 5)
|
|
1243
|
+
sage: hash(R(3)) == hash(3)
|
|
1244
|
+
True
|
|
1245
|
+
"""
|
|
1246
|
+
if very_pos_val(self.ordp):
|
|
1247
|
+
return 0
|
|
1248
|
+
if very_neg_val(self.ordp):
|
|
1249
|
+
return 314159
|
|
1250
|
+
return chash(self.unit, self.ordp, self.prime_pow.ram_prec_cap, self.prime_pow) ^ self.ordp
|
|
1251
|
+
|
|
1252
|
+
cdef class pAdicCoercion_ZZ_FP(RingHomomorphism):
|
|
1253
|
+
"""
|
|
1254
|
+
The canonical inclusion from the integer ring to a floating point ring.
|
|
1255
|
+
|
|
1256
|
+
EXAMPLES::
|
|
1257
|
+
|
|
1258
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ); f
|
|
1259
|
+
Ring morphism:
|
|
1260
|
+
From: Integer Ring
|
|
1261
|
+
To: 5-adic Ring with floating precision 20
|
|
1262
|
+
|
|
1263
|
+
TESTS::
|
|
1264
|
+
|
|
1265
|
+
sage: TestSuite(f).run()
|
|
1266
|
+
"""
|
|
1267
|
+
def __init__(self, R):
|
|
1268
|
+
"""
|
|
1269
|
+
Initialization.
|
|
1270
|
+
|
|
1271
|
+
EXAMPLES::
|
|
1272
|
+
|
|
1273
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ); type(f)
|
|
1274
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicCoercion_ZZ_FP'>
|
|
1275
|
+
"""
|
|
1276
|
+
RingHomomorphism.__init__(self, ZZ.Hom(R))
|
|
1277
|
+
self._zero = R.element_class(R, 0)
|
|
1278
|
+
self._section = pAdicConvert_FP_ZZ(R)
|
|
1279
|
+
|
|
1280
|
+
cdef dict _extra_slots(self):
|
|
1281
|
+
"""
|
|
1282
|
+
Helper for copying and pickling.
|
|
1283
|
+
|
|
1284
|
+
EXAMPLES::
|
|
1285
|
+
|
|
1286
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ)
|
|
1287
|
+
sage: g = copy(f) # indirect doctest
|
|
1288
|
+
sage: g == f
|
|
1289
|
+
True
|
|
1290
|
+
sage: g(6)
|
|
1291
|
+
1 + 5
|
|
1292
|
+
sage: g(6) == f(6)
|
|
1293
|
+
True
|
|
1294
|
+
"""
|
|
1295
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
1296
|
+
_slots['_zero'] = self._zero
|
|
1297
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
1298
|
+
return _slots
|
|
1299
|
+
|
|
1300
|
+
cdef _update_slots(self, dict _slots):
|
|
1301
|
+
"""
|
|
1302
|
+
Helper for copying and pickling.
|
|
1303
|
+
|
|
1304
|
+
EXAMPLES::
|
|
1305
|
+
|
|
1306
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ)
|
|
1307
|
+
sage: g = copy(f) # indirect doctest
|
|
1308
|
+
sage: g == f
|
|
1309
|
+
True
|
|
1310
|
+
sage: g(6)
|
|
1311
|
+
1 + 5
|
|
1312
|
+
sage: g(6) == f(6)
|
|
1313
|
+
True
|
|
1314
|
+
"""
|
|
1315
|
+
self._zero = _slots['_zero']
|
|
1316
|
+
self._section = _slots['_section']
|
|
1317
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
1318
|
+
|
|
1319
|
+
cpdef Element _call_(self, x):
|
|
1320
|
+
"""
|
|
1321
|
+
Evaluation.
|
|
1322
|
+
|
|
1323
|
+
EXAMPLES::
|
|
1324
|
+
|
|
1325
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ)
|
|
1326
|
+
sage: f(0).parent()
|
|
1327
|
+
5-adic Ring with floating precision 20
|
|
1328
|
+
sage: f(5)
|
|
1329
|
+
5
|
|
1330
|
+
"""
|
|
1331
|
+
if mpz_sgn((<Integer>x).value) == 0:
|
|
1332
|
+
return self._zero
|
|
1333
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1334
|
+
ans.ordp = cconv_mpz_t(ans.unit, (<Integer>x).value, ans.prime_pow.ram_prec_cap, False, ans.prime_pow)
|
|
1335
|
+
return ans
|
|
1336
|
+
|
|
1337
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
1338
|
+
"""
|
|
1339
|
+
This function is used when some precision cap is passed in (relative or absolute or both).
|
|
1340
|
+
|
|
1341
|
+
INPUT:
|
|
1342
|
+
|
|
1343
|
+
- ``x`` -- an Integer
|
|
1344
|
+
|
|
1345
|
+
- ``absprec``, or the first positional argument -- the maximum
|
|
1346
|
+
absolute precision (unused for floating point elements)
|
|
1347
|
+
|
|
1348
|
+
- ``relprec``, or the second positional argument -- the
|
|
1349
|
+
maximum relative precision (unused for floating point
|
|
1350
|
+
elements)
|
|
1351
|
+
|
|
1352
|
+
EXAMPLES::
|
|
1353
|
+
|
|
1354
|
+
sage: R = ZpFP(5,4)
|
|
1355
|
+
sage: type(R(10,2))
|
|
1356
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicFloatingPointElement'>
|
|
1357
|
+
sage: R(30,2)
|
|
1358
|
+
5
|
|
1359
|
+
sage: R(30,3,2)
|
|
1360
|
+
5 + 5^2
|
|
1361
|
+
sage: R(30,absprec=2)
|
|
1362
|
+
5
|
|
1363
|
+
sage: R(30,relprec=2)
|
|
1364
|
+
5 + 5^2
|
|
1365
|
+
sage: R(30,absprec=1)
|
|
1366
|
+
0
|
|
1367
|
+
sage: R(30,empty=True)
|
|
1368
|
+
0
|
|
1369
|
+
"""
|
|
1370
|
+
cdef long val, aprec, rprec
|
|
1371
|
+
if mpz_sgn((<Integer>x).value) == 0:
|
|
1372
|
+
return self._zero
|
|
1373
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, self._zero.prime_pow)
|
|
1374
|
+
val = get_ordp(x, self._zero.prime_pow)
|
|
1375
|
+
if aprec - val < rprec:
|
|
1376
|
+
rprec = aprec - val
|
|
1377
|
+
if rprec <= 0:
|
|
1378
|
+
return self._zero
|
|
1379
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1380
|
+
ans.ordp = cconv_mpz_t(ans.unit, (<Integer>x).value, rprec, False, ans.prime_pow)
|
|
1381
|
+
return ans
|
|
1382
|
+
|
|
1383
|
+
def section(self):
|
|
1384
|
+
r"""
|
|
1385
|
+
Return a map back to `\ZZ` that approximates an element of this
|
|
1386
|
+
`p`-adic ring by an integer.
|
|
1387
|
+
|
|
1388
|
+
EXAMPLES::
|
|
1389
|
+
|
|
1390
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ).section()
|
|
1391
|
+
sage: f(ZpFP(5)(-1)) - 5^20
|
|
1392
|
+
-1
|
|
1393
|
+
"""
|
|
1394
|
+
from sage.misc.constant_function import ConstantFunction
|
|
1395
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
1396
|
+
import copy
|
|
1397
|
+
self._section = copy.copy(self._section)
|
|
1398
|
+
return self._section
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
cdef class pAdicConvert_FP_ZZ(RingMap):
|
|
1402
|
+
r"""
|
|
1403
|
+
The map from a floating point ring back to `\ZZ` that returns the smallest
|
|
1404
|
+
nonnegative integer approximation to its input which is accurate up to the precision.
|
|
1405
|
+
|
|
1406
|
+
If the input is not in the closure of the image of `\ZZ`, raises a :exc:`ValueError`.
|
|
1407
|
+
|
|
1408
|
+
EXAMPLES::
|
|
1409
|
+
|
|
1410
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ).section(); f
|
|
1411
|
+
Set-theoretic ring morphism:
|
|
1412
|
+
From: 5-adic Ring with floating precision 20
|
|
1413
|
+
To: Integer Ring
|
|
1414
|
+
"""
|
|
1415
|
+
def __init__(self, R):
|
|
1416
|
+
"""
|
|
1417
|
+
Initialization.
|
|
1418
|
+
|
|
1419
|
+
EXAMPLES::
|
|
1420
|
+
|
|
1421
|
+
sage: f = ZpFP(5).coerce_map_from(ZZ).section(); type(f)
|
|
1422
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicConvert_FP_ZZ'>
|
|
1423
|
+
sage: f.category()
|
|
1424
|
+
Category of homsets of sets
|
|
1425
|
+
"""
|
|
1426
|
+
if R.absolute_degree() > 1 or R.characteristic() != 0 or R.residue_characteristic() == 0:
|
|
1427
|
+
RingMap.__init__(self, Hom(R, ZZ, SetsWithPartialMaps()))
|
|
1428
|
+
else:
|
|
1429
|
+
RingMap.__init__(self, Hom(R, ZZ, Sets()))
|
|
1430
|
+
|
|
1431
|
+
cpdef Element _call_(self, _x):
|
|
1432
|
+
"""
|
|
1433
|
+
Evaluation.
|
|
1434
|
+
|
|
1435
|
+
EXAMPLES::
|
|
1436
|
+
|
|
1437
|
+
sage: f = QpFP(5).coerce_map_from(ZZ).section()
|
|
1438
|
+
sage: f(QpFP(5)(-1)) - 5^20
|
|
1439
|
+
-1
|
|
1440
|
+
sage: f(QpFP(5)(5))
|
|
1441
|
+
5
|
|
1442
|
+
sage: f(QpFP(5)(0))
|
|
1443
|
+
0
|
|
1444
|
+
sage: f(~QpFP(5)(5))
|
|
1445
|
+
Traceback (most recent call last):
|
|
1446
|
+
...
|
|
1447
|
+
ValueError: negative valuation
|
|
1448
|
+
sage: f(~QpFP(5)(0))
|
|
1449
|
+
Traceback (most recent call last):
|
|
1450
|
+
...
|
|
1451
|
+
ValueError: Infinity cannot be converted to a rational
|
|
1452
|
+
"""
|
|
1453
|
+
cdef Integer ans = PY_NEW(Integer)
|
|
1454
|
+
cdef FPElement x = _x
|
|
1455
|
+
if very_pos_val(x.ordp):
|
|
1456
|
+
mpz_set_ui(ans.value, 0)
|
|
1457
|
+
elif very_neg_val(x.ordp):
|
|
1458
|
+
raise ValueError("Infinity cannot be converted to a rational")
|
|
1459
|
+
else:
|
|
1460
|
+
cconv_mpz_t_out(ans.value, x.unit, x.ordp, x.prime_pow.ram_prec_cap, x.prime_pow)
|
|
1461
|
+
return ans
|
|
1462
|
+
|
|
1463
|
+
cdef class pAdicCoercion_QQ_FP(RingHomomorphism):
|
|
1464
|
+
"""
|
|
1465
|
+
The canonical inclusion from the rationals to a floating point field.
|
|
1466
|
+
|
|
1467
|
+
EXAMPLES::
|
|
1468
|
+
|
|
1469
|
+
sage: f = QpFP(5).coerce_map_from(QQ); f
|
|
1470
|
+
Ring morphism:
|
|
1471
|
+
From: Rational Field
|
|
1472
|
+
To: 5-adic Field with floating precision 20
|
|
1473
|
+
|
|
1474
|
+
TESTS::
|
|
1475
|
+
|
|
1476
|
+
sage: TestSuite(f).run()
|
|
1477
|
+
"""
|
|
1478
|
+
def __init__(self, R):
|
|
1479
|
+
"""
|
|
1480
|
+
Initialization.
|
|
1481
|
+
|
|
1482
|
+
EXAMPLES::
|
|
1483
|
+
|
|
1484
|
+
sage: f = QpFP(5).coerce_map_from(QQ); type(f)
|
|
1485
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicCoercion_QQ_FP'>
|
|
1486
|
+
"""
|
|
1487
|
+
RingHomomorphism.__init__(self, QQ.Hom(R))
|
|
1488
|
+
self._zero = R.element_class(R, 0)
|
|
1489
|
+
self._section = pAdicConvert_FP_QQ(R)
|
|
1490
|
+
|
|
1491
|
+
cdef dict _extra_slots(self):
|
|
1492
|
+
"""
|
|
1493
|
+
Helper for copying and pickling.
|
|
1494
|
+
|
|
1495
|
+
EXAMPLES::
|
|
1496
|
+
|
|
1497
|
+
sage: f = QpFP(5).coerce_map_from(QQ)
|
|
1498
|
+
sage: g = copy(f) # indirect doctest
|
|
1499
|
+
sage: g
|
|
1500
|
+
Ring morphism:
|
|
1501
|
+
From: Rational Field
|
|
1502
|
+
To: 5-adic Field with floating precision 20
|
|
1503
|
+
sage: g == f
|
|
1504
|
+
True
|
|
1505
|
+
sage: g is f
|
|
1506
|
+
False
|
|
1507
|
+
sage: g(6)
|
|
1508
|
+
1 + 5
|
|
1509
|
+
sage: g(6) == f(6)
|
|
1510
|
+
True
|
|
1511
|
+
"""
|
|
1512
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
1513
|
+
_slots['_zero'] = self._zero
|
|
1514
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
1515
|
+
return _slots
|
|
1516
|
+
|
|
1517
|
+
cdef _update_slots(self, dict _slots):
|
|
1518
|
+
"""
|
|
1519
|
+
Helper for copying and pickling.
|
|
1520
|
+
|
|
1521
|
+
EXAMPLES::
|
|
1522
|
+
|
|
1523
|
+
sage: f = QpFP(5).coerce_map_from(QQ)
|
|
1524
|
+
sage: g = copy(f) # indirect doctest
|
|
1525
|
+
sage: g
|
|
1526
|
+
Ring morphism:
|
|
1527
|
+
From: Rational Field
|
|
1528
|
+
To: 5-adic Field with floating precision 20
|
|
1529
|
+
sage: g == f
|
|
1530
|
+
True
|
|
1531
|
+
sage: g is f
|
|
1532
|
+
False
|
|
1533
|
+
sage: g(6)
|
|
1534
|
+
1 + 5
|
|
1535
|
+
sage: g(6) == f(6)
|
|
1536
|
+
True
|
|
1537
|
+
"""
|
|
1538
|
+
self._zero = _slots['_zero']
|
|
1539
|
+
self._section = _slots['_section']
|
|
1540
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
1541
|
+
|
|
1542
|
+
cpdef Element _call_(self, x):
|
|
1543
|
+
"""
|
|
1544
|
+
Evaluation.
|
|
1545
|
+
|
|
1546
|
+
EXAMPLES::
|
|
1547
|
+
|
|
1548
|
+
sage: f = QpFP(5).coerce_map_from(QQ)
|
|
1549
|
+
sage: f(0).parent()
|
|
1550
|
+
5-adic Field with floating precision 20
|
|
1551
|
+
sage: f(1/5)
|
|
1552
|
+
5^-1
|
|
1553
|
+
sage: f(1/4)
|
|
1554
|
+
4 + 3*5 + 3*5^2 + 3*5^3 + 3*5^4 + 3*5^5 + 3*5^6 + 3*5^7 + 3*5^8 + 3*5^9 + 3*5^10 + 3*5^11 + 3*5^12 + 3*5^13 + 3*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 3*5^18 + 3*5^19
|
|
1555
|
+
sage: f(1/4, 5)
|
|
1556
|
+
4 + 3*5 + 3*5^2 + 3*5^3 + 3*5^4
|
|
1557
|
+
"""
|
|
1558
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1559
|
+
return self._zero
|
|
1560
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1561
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.prime_pow.ram_prec_cap, False, self._zero.prime_pow)
|
|
1562
|
+
return ans
|
|
1563
|
+
|
|
1564
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
1565
|
+
"""
|
|
1566
|
+
This function is used when some precision cap is passed in
|
|
1567
|
+
(relative or absolute or both).
|
|
1568
|
+
|
|
1569
|
+
See the documentation for
|
|
1570
|
+
:meth:`pAdicCappedRelativeElement.__init__` for more details.
|
|
1571
|
+
|
|
1572
|
+
EXAMPLES::
|
|
1573
|
+
|
|
1574
|
+
sage: R = QpFP(5,4)
|
|
1575
|
+
sage: type(R(10/3,2))
|
|
1576
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicFloatingPointElement'>
|
|
1577
|
+
sage: R(10/3,2)
|
|
1578
|
+
4*5
|
|
1579
|
+
sage: R(10/3,3,1)
|
|
1580
|
+
4*5
|
|
1581
|
+
sage: R(10/3,absprec=2)
|
|
1582
|
+
4*5
|
|
1583
|
+
sage: R(10/3,relprec=2)
|
|
1584
|
+
4*5 + 5^2
|
|
1585
|
+
sage: R(10/3,absprec=1)
|
|
1586
|
+
0
|
|
1587
|
+
sage: R(3/100,absprec=-1)
|
|
1588
|
+
2*5^-2
|
|
1589
|
+
"""
|
|
1590
|
+
cdef long val, aprec, rprec
|
|
1591
|
+
cdef FPElement ans
|
|
1592
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, self._zero.prime_pow)
|
|
1593
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1594
|
+
return self._zero
|
|
1595
|
+
val = get_ordp(x, self._zero.prime_pow)
|
|
1596
|
+
if aprec <= val:
|
|
1597
|
+
return self._zero
|
|
1598
|
+
ans = self._zero._new_c()
|
|
1599
|
+
rprec = min(rprec, aprec - val)
|
|
1600
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, rprec, False, self._zero.prime_pow)
|
|
1601
|
+
return ans
|
|
1602
|
+
|
|
1603
|
+
def section(self):
|
|
1604
|
+
"""
|
|
1605
|
+
Return a map back to the rationals that approximates an element by
|
|
1606
|
+
a rational number.
|
|
1607
|
+
|
|
1608
|
+
EXAMPLES::
|
|
1609
|
+
|
|
1610
|
+
sage: f = QpFP(5).coerce_map_from(QQ).section()
|
|
1611
|
+
sage: f(QpFP(5)(1/4))
|
|
1612
|
+
1/4
|
|
1613
|
+
sage: f(QpFP(5)(1/5))
|
|
1614
|
+
1/5
|
|
1615
|
+
"""
|
|
1616
|
+
from sage.misc.constant_function import ConstantFunction
|
|
1617
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
1618
|
+
import copy
|
|
1619
|
+
self._section = copy.copy(self._section)
|
|
1620
|
+
return self._section
|
|
1621
|
+
|
|
1622
|
+
cdef class pAdicConvert_FP_QQ(RingMap):
|
|
1623
|
+
"""
|
|
1624
|
+
The map from the floating point ring back to the rationals that returns a
|
|
1625
|
+
rational approximation of its input.
|
|
1626
|
+
|
|
1627
|
+
EXAMPLES::
|
|
1628
|
+
|
|
1629
|
+
sage: f = QpFP(5).coerce_map_from(QQ).section(); f
|
|
1630
|
+
Set-theoretic ring morphism:
|
|
1631
|
+
From: 5-adic Field with floating precision 20
|
|
1632
|
+
To: Rational Field
|
|
1633
|
+
"""
|
|
1634
|
+
def __init__(self, R):
|
|
1635
|
+
"""
|
|
1636
|
+
Initialization.
|
|
1637
|
+
|
|
1638
|
+
EXAMPLES::
|
|
1639
|
+
|
|
1640
|
+
sage: f = QpFP(5).coerce_map_from(QQ).section(); type(f)
|
|
1641
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicConvert_FP_QQ'>
|
|
1642
|
+
sage: f.category()
|
|
1643
|
+
Category of homsets of sets with partial maps
|
|
1644
|
+
"""
|
|
1645
|
+
RingMap.__init__(self, Hom(R, QQ, SetsWithPartialMaps()))
|
|
1646
|
+
|
|
1647
|
+
cpdef Element _call_(self, _x):
|
|
1648
|
+
"""
|
|
1649
|
+
Evaluation.
|
|
1650
|
+
|
|
1651
|
+
EXAMPLES::
|
|
1652
|
+
|
|
1653
|
+
sage: f = QpFP(5).coerce_map_from(QQ).section()
|
|
1654
|
+
sage: f(QpFP(5)(-1))
|
|
1655
|
+
-1
|
|
1656
|
+
sage: f(QpFP(5)(0))
|
|
1657
|
+
0
|
|
1658
|
+
sage: f(QpFP(5)(1/5))
|
|
1659
|
+
1/5
|
|
1660
|
+
"""
|
|
1661
|
+
cdef Rational ans = Rational.__new__(Rational)
|
|
1662
|
+
cdef FPElement x = _x
|
|
1663
|
+
if very_pos_val(x.ordp):
|
|
1664
|
+
mpq_set_ui(ans.value, 0, 1)
|
|
1665
|
+
elif very_neg_val(x.ordp):
|
|
1666
|
+
raise ValueError("Infinity cannot be converted to a rational")
|
|
1667
|
+
else:
|
|
1668
|
+
cconv_mpq_t_out(ans.value, x.unit, x.ordp, x.prime_pow.ram_prec_cap, x.prime_pow)
|
|
1669
|
+
return ans
|
|
1670
|
+
|
|
1671
|
+
cdef class pAdicConvert_QQ_FP(Morphism):
|
|
1672
|
+
r"""
|
|
1673
|
+
The inclusion map from `\QQ` to a floating point ring.
|
|
1674
|
+
|
|
1675
|
+
EXAMPLES::
|
|
1676
|
+
|
|
1677
|
+
sage: f = ZpFP(5).convert_map_from(QQ); f
|
|
1678
|
+
Generic morphism:
|
|
1679
|
+
From: Rational Field
|
|
1680
|
+
To: 5-adic Ring with floating precision 20
|
|
1681
|
+
"""
|
|
1682
|
+
def __init__(self, R):
|
|
1683
|
+
"""
|
|
1684
|
+
Initialization.
|
|
1685
|
+
|
|
1686
|
+
EXAMPLES::
|
|
1687
|
+
|
|
1688
|
+
sage: f = ZpFP(5).convert_map_from(QQ); type(f)
|
|
1689
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicConvert_QQ_FP'>
|
|
1690
|
+
"""
|
|
1691
|
+
Morphism.__init__(self, Hom(QQ, R, SetsWithPartialMaps()))
|
|
1692
|
+
self._zero = R.element_class(R, 0)
|
|
1693
|
+
|
|
1694
|
+
cdef dict _extra_slots(self):
|
|
1695
|
+
"""
|
|
1696
|
+
Helper for copying and pickling.
|
|
1697
|
+
|
|
1698
|
+
EXAMPLES::
|
|
1699
|
+
|
|
1700
|
+
sage: f = ZpFP(5).convert_map_from(QQ)
|
|
1701
|
+
sage: g = copy(f) # indirect doctest
|
|
1702
|
+
sage: g == f # todo: comparison not implemented
|
|
1703
|
+
True
|
|
1704
|
+
sage: g(1/6)
|
|
1705
|
+
1 + 4*5 + 4*5^3 + 4*5^5 + 4*5^7 + 4*5^9 + 4*5^11 + 4*5^13 + 4*5^15 + 4*5^17 + 4*5^19
|
|
1706
|
+
sage: g(1/6) == f(1/6)
|
|
1707
|
+
True
|
|
1708
|
+
"""
|
|
1709
|
+
_slots = Morphism._extra_slots(self)
|
|
1710
|
+
_slots['_zero'] = self._zero
|
|
1711
|
+
return _slots
|
|
1712
|
+
|
|
1713
|
+
cdef _update_slots(self, dict _slots):
|
|
1714
|
+
"""
|
|
1715
|
+
Helper for copying and pickling.
|
|
1716
|
+
|
|
1717
|
+
EXAMPLES::
|
|
1718
|
+
|
|
1719
|
+
sage: f = ZpFP(5).convert_map_from(QQ)
|
|
1720
|
+
sage: g = copy(f) # indirect doctest
|
|
1721
|
+
sage: g == f # todo: comparison not implemented
|
|
1722
|
+
True
|
|
1723
|
+
sage: g(1/6)
|
|
1724
|
+
1 + 4*5 + 4*5^3 + 4*5^5 + 4*5^7 + 4*5^9 + 4*5^11 + 4*5^13 + 4*5^15 + 4*5^17 + 4*5^19
|
|
1725
|
+
sage: g(1/6) == f(1/6)
|
|
1726
|
+
True
|
|
1727
|
+
"""
|
|
1728
|
+
self._zero = _slots['_zero']
|
|
1729
|
+
Morphism._update_slots(self, _slots)
|
|
1730
|
+
|
|
1731
|
+
cpdef Element _call_(self, x):
|
|
1732
|
+
"""
|
|
1733
|
+
Evaluation.
|
|
1734
|
+
|
|
1735
|
+
EXAMPLES::
|
|
1736
|
+
|
|
1737
|
+
sage: f = ZpFP(5,4).convert_map_from(QQ)
|
|
1738
|
+
sage: f(1/7)
|
|
1739
|
+
3 + 3*5 + 2*5^3
|
|
1740
|
+
sage: f(0/1)
|
|
1741
|
+
0
|
|
1742
|
+
"""
|
|
1743
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1744
|
+
return self._zero
|
|
1745
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1746
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.prime_pow.ram_prec_cap, False, ans.prime_pow)
|
|
1747
|
+
if ans.ordp < 0:
|
|
1748
|
+
raise ValueError("p divides the denominator")
|
|
1749
|
+
return ans
|
|
1750
|
+
|
|
1751
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
1752
|
+
"""
|
|
1753
|
+
This function is used when some precision cap is passed in (relative or absolute or both).
|
|
1754
|
+
|
|
1755
|
+
INPUT:
|
|
1756
|
+
|
|
1757
|
+
- ``x`` -- a Rational
|
|
1758
|
+
|
|
1759
|
+
- ``absprec``, or the first positional argument -- the maximum
|
|
1760
|
+
absolute precision (unused for floating point elements)
|
|
1761
|
+
|
|
1762
|
+
- ``relprec``, or the second positional argument -- the
|
|
1763
|
+
maximum relative precision (unused for floating point
|
|
1764
|
+
elements)
|
|
1765
|
+
|
|
1766
|
+
EXAMPLES::
|
|
1767
|
+
|
|
1768
|
+
sage: R = ZpFP(5,4)
|
|
1769
|
+
sage: type(R(1/7,2))
|
|
1770
|
+
<class 'sage.rings.padics.padic_floating_point_element.pAdicFloatingPointElement'>
|
|
1771
|
+
sage: R(1/7,2)
|
|
1772
|
+
3 + 3*5
|
|
1773
|
+
sage: R(1/7,3,2)
|
|
1774
|
+
3 + 3*5
|
|
1775
|
+
sage: R(1/7,absprec=2)
|
|
1776
|
+
3 + 3*5
|
|
1777
|
+
sage: R(5/7,relprec=2)
|
|
1778
|
+
3*5 + 3*5^2
|
|
1779
|
+
sage: R(1/7,absprec=1)
|
|
1780
|
+
3
|
|
1781
|
+
sage: R(1/7,empty=True)
|
|
1782
|
+
0
|
|
1783
|
+
"""
|
|
1784
|
+
cdef long val, aprec, rprec
|
|
1785
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1786
|
+
return self._zero
|
|
1787
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, self._zero.prime_pow)
|
|
1788
|
+
val = get_ordp(x, self._zero.prime_pow)
|
|
1789
|
+
rprec = min(rprec, aprec - val)
|
|
1790
|
+
if rprec <= 0:
|
|
1791
|
+
return self._zero
|
|
1792
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1793
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, rprec, False, ans.prime_pow)
|
|
1794
|
+
if ans.ordp < 0:
|
|
1795
|
+
raise ValueError("p divides the denominator")
|
|
1796
|
+
return ans
|
|
1797
|
+
|
|
1798
|
+
cdef class pAdicCoercion_FP_frac_field(RingHomomorphism):
|
|
1799
|
+
r"""
|
|
1800
|
+
The canonical inclusion of `\ZZ_q` into its fraction field.
|
|
1801
|
+
|
|
1802
|
+
EXAMPLES::
|
|
1803
|
+
|
|
1804
|
+
sage: # needs sage.libs.flint
|
|
1805
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
1806
|
+
sage: K = R.fraction_field()
|
|
1807
|
+
sage: f = K.coerce_map_from(R); f
|
|
1808
|
+
Ring morphism:
|
|
1809
|
+
From: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1810
|
+
To: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
1811
|
+
|
|
1812
|
+
TESTS::
|
|
1813
|
+
|
|
1814
|
+
sage: TestSuite(f).run() # needs sage.libs.flint
|
|
1815
|
+
"""
|
|
1816
|
+
def __init__(self, R, K):
|
|
1817
|
+
r"""
|
|
1818
|
+
Initialization.
|
|
1819
|
+
|
|
1820
|
+
EXAMPLES::
|
|
1821
|
+
|
|
1822
|
+
sage: # needs sage.libs.flint
|
|
1823
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
1824
|
+
sage: K = R.fraction_field()
|
|
1825
|
+
sage: f = K.coerce_map_from(R); type(f)
|
|
1826
|
+
<class 'sage.rings.padics.qadic_flint_FP.pAdicCoercion_FP_frac_field'>
|
|
1827
|
+
"""
|
|
1828
|
+
RingHomomorphism.__init__(self, R.Hom(K))
|
|
1829
|
+
self._zero = K(0)
|
|
1830
|
+
self._section = pAdicConvert_FP_frac_field(K, R)
|
|
1831
|
+
|
|
1832
|
+
cpdef Element _call_(self, _x):
|
|
1833
|
+
r"""
|
|
1834
|
+
Evaluation.
|
|
1835
|
+
|
|
1836
|
+
EXAMPLES::
|
|
1837
|
+
|
|
1838
|
+
sage: # needs sage.libs.flint
|
|
1839
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
1840
|
+
sage: K = R.fraction_field()
|
|
1841
|
+
sage: f = K.coerce_map_from(R)
|
|
1842
|
+
sage: f(a)
|
|
1843
|
+
a
|
|
1844
|
+
sage: f(R(0))
|
|
1845
|
+
0
|
|
1846
|
+
"""
|
|
1847
|
+
cdef FPElement x = _x
|
|
1848
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1849
|
+
ans.ordp = x.ordp
|
|
1850
|
+
cshift_notrunc(ans.unit, x.unit, 0, ans.prime_pow.ram_prec_cap, x.prime_pow, False)
|
|
1851
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1852
|
+
# The base ring is wrong, so we fix it.
|
|
1853
|
+
K = ans.unit.base_ring()
|
|
1854
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
1855
|
+
return ans
|
|
1856
|
+
|
|
1857
|
+
cpdef Element _call_with_args(self, _x, args=(), kwds={}):
|
|
1858
|
+
r"""
|
|
1859
|
+
This function is used when some precision cap is passed in
|
|
1860
|
+
(relative or absolute or both).
|
|
1861
|
+
|
|
1862
|
+
See the documentation for
|
|
1863
|
+
:meth:`pAdicCappedAbsoluteElement.__init__` for more details.
|
|
1864
|
+
|
|
1865
|
+
EXAMPLES::
|
|
1866
|
+
|
|
1867
|
+
sage: # needs sage.libs.flint
|
|
1868
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
1869
|
+
sage: K = R.fraction_field()
|
|
1870
|
+
sage: f = K.coerce_map_from(R)
|
|
1871
|
+
sage: f(a, 3)
|
|
1872
|
+
a
|
|
1873
|
+
sage: b = 9*a + 27
|
|
1874
|
+
sage: f(b, 3)
|
|
1875
|
+
a*3^2
|
|
1876
|
+
sage: f(b, 4, 1)
|
|
1877
|
+
a*3^2
|
|
1878
|
+
sage: f(b, 4, 3)
|
|
1879
|
+
a*3^2 + 3^3
|
|
1880
|
+
sage: f(b, absprec=4)
|
|
1881
|
+
a*3^2 + 3^3
|
|
1882
|
+
sage: f(b, relprec=3)
|
|
1883
|
+
a*3^2 + 3^3
|
|
1884
|
+
sage: f(b, absprec=1)
|
|
1885
|
+
0
|
|
1886
|
+
sage: f(R(0))
|
|
1887
|
+
0
|
|
1888
|
+
"""
|
|
1889
|
+
cdef long aprec, rprec
|
|
1890
|
+
cdef FPElement x = _x
|
|
1891
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1892
|
+
cdef bint reduce = False
|
|
1893
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, ans.prime_pow)
|
|
1894
|
+
if aprec <= x.ordp:
|
|
1895
|
+
ans._set_exact_zero()
|
|
1896
|
+
else:
|
|
1897
|
+
if rprec < ans.prime_pow.ram_prec_cap:
|
|
1898
|
+
reduce = True
|
|
1899
|
+
else:
|
|
1900
|
+
rprec = ans.prime_pow.ram_prec_cap
|
|
1901
|
+
if aprec < rprec + x.ordp:
|
|
1902
|
+
rprec = aprec - x.ordp
|
|
1903
|
+
reduce = True
|
|
1904
|
+
ans.ordp = x.ordp
|
|
1905
|
+
cshift_notrunc(ans.unit, x.unit, 0, rprec, x.prime_pow, reduce)
|
|
1906
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1907
|
+
# The base ring is wrong, so we fix it.
|
|
1908
|
+
K = ans.unit.base_ring()
|
|
1909
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
1910
|
+
return ans
|
|
1911
|
+
|
|
1912
|
+
def section(self):
|
|
1913
|
+
r"""
|
|
1914
|
+
Return a map back to the ring that converts elements of
|
|
1915
|
+
nonnegative valuation.
|
|
1916
|
+
|
|
1917
|
+
EXAMPLES::
|
|
1918
|
+
|
|
1919
|
+
sage: # needs sage.libs.flint
|
|
1920
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
1921
|
+
sage: K = R.fraction_field()
|
|
1922
|
+
sage: f = K.coerce_map_from(R)
|
|
1923
|
+
sage: f(K.gen())
|
|
1924
|
+
a
|
|
1925
|
+
"""
|
|
1926
|
+
return self._section
|
|
1927
|
+
|
|
1928
|
+
cdef dict _extra_slots(self):
|
|
1929
|
+
r"""
|
|
1930
|
+
Helper for copying and pickling.
|
|
1931
|
+
|
|
1932
|
+
TESTS::
|
|
1933
|
+
|
|
1934
|
+
sage: # needs sage.libs.flint
|
|
1935
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
1936
|
+
sage: K = R.fraction_field()
|
|
1937
|
+
sage: f = K.coerce_map_from(R)
|
|
1938
|
+
sage: g = copy(f) # indirect doctest
|
|
1939
|
+
sage: g
|
|
1940
|
+
Ring morphism:
|
|
1941
|
+
From: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1942
|
+
To: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
1943
|
+
sage: g == f
|
|
1944
|
+
True
|
|
1945
|
+
sage: g is f
|
|
1946
|
+
False
|
|
1947
|
+
sage: g(a)
|
|
1948
|
+
a
|
|
1949
|
+
sage: g(a) == f(a)
|
|
1950
|
+
True
|
|
1951
|
+
"""
|
|
1952
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
1953
|
+
_slots['_zero'] = self._zero
|
|
1954
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
1955
|
+
return _slots
|
|
1956
|
+
|
|
1957
|
+
cdef _update_slots(self, dict _slots):
|
|
1958
|
+
r"""
|
|
1959
|
+
Helper for copying and pickling.
|
|
1960
|
+
|
|
1961
|
+
TESTS::
|
|
1962
|
+
|
|
1963
|
+
sage: # needs sage.libs.flint
|
|
1964
|
+
sage: R.<a> = ZqFP(9, implementation='FLINT')
|
|
1965
|
+
sage: K = R.fraction_field()
|
|
1966
|
+
sage: f = K.coerce_map_from(R)
|
|
1967
|
+
sage: g = copy(f) # indirect doctest
|
|
1968
|
+
sage: g
|
|
1969
|
+
Ring morphism:
|
|
1970
|
+
From: 3-adic Unramified Extension Ring in a defined by x^2 + 2*x + 2
|
|
1971
|
+
To: 3-adic Unramified Extension Field in a defined by x^2 + 2*x + 2
|
|
1972
|
+
sage: g == f
|
|
1973
|
+
True
|
|
1974
|
+
sage: g is f
|
|
1975
|
+
False
|
|
1976
|
+
sage: g(a)
|
|
1977
|
+
a
|
|
1978
|
+
sage: g(a) == f(a)
|
|
1979
|
+
True
|
|
1980
|
+
"""
|
|
1981
|
+
self._zero = _slots['_zero']
|
|
1982
|
+
self._section = _slots['_section']
|
|
1983
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
1984
|
+
|
|
1985
|
+
cdef class pAdicConvert_FP_frac_field(Morphism):
|
|
1986
|
+
r"""
|
|
1987
|
+
The section of the inclusion from `\ZZ_q` to its fraction field.
|
|
1988
|
+
|
|
1989
|
+
EXAMPLES::
|
|
1990
|
+
|
|
1991
|
+
sage: # needs sage.libs.flint
|
|
1992
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
1993
|
+
sage: K = R.fraction_field()
|
|
1994
|
+
sage: f = R.convert_map_from(K); f
|
|
1995
|
+
Generic morphism:
|
|
1996
|
+
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
1997
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1998
|
+
"""
|
|
1999
|
+
def __init__(self, K, R):
|
|
2000
|
+
r"""
|
|
2001
|
+
Initialization.
|
|
2002
|
+
|
|
2003
|
+
EXAMPLES::
|
|
2004
|
+
|
|
2005
|
+
sage: # needs sage.libs.flint
|
|
2006
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
2007
|
+
sage: K = R.fraction_field()
|
|
2008
|
+
sage: f = R.convert_map_from(K); type(f)
|
|
2009
|
+
<class 'sage.rings.padics.qadic_flint_FP.pAdicConvert_FP_frac_field'>
|
|
2010
|
+
"""
|
|
2011
|
+
Morphism.__init__(self, Hom(K, R, SetsWithPartialMaps()))
|
|
2012
|
+
self._zero = R(0)
|
|
2013
|
+
|
|
2014
|
+
cpdef Element _call_(self, _x):
|
|
2015
|
+
r"""
|
|
2016
|
+
Evaluation.
|
|
2017
|
+
|
|
2018
|
+
EXAMPLES::
|
|
2019
|
+
|
|
2020
|
+
sage: # needs sage.libs.flint
|
|
2021
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
2022
|
+
sage: K = R.fraction_field()
|
|
2023
|
+
sage: f = R.convert_map_from(K)
|
|
2024
|
+
sage: f(K.gen())
|
|
2025
|
+
a
|
|
2026
|
+
"""
|
|
2027
|
+
cdef FPElement x = _x
|
|
2028
|
+
if x.ordp < 0:
|
|
2029
|
+
raise ValueError("negative valuation")
|
|
2030
|
+
cdef FPElement ans = self._zero._new_c()
|
|
2031
|
+
ans.ordp = x.ordp
|
|
2032
|
+
cshift_notrunc(ans.unit, x.unit, 0, ans.prime_pow.ram_prec_cap, ans.prime_pow, False)
|
|
2033
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2034
|
+
# The base ring is wrong, so we fix it.
|
|
2035
|
+
K = ans.unit.base_ring()
|
|
2036
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
2037
|
+
return ans
|
|
2038
|
+
|
|
2039
|
+
cpdef Element _call_with_args(self, _x, args=(), kwds={}):
|
|
2040
|
+
r"""
|
|
2041
|
+
This function is used when some precision cap is passed in
|
|
2042
|
+
(relative or absolute or both).
|
|
2043
|
+
|
|
2044
|
+
See the documentation for
|
|
2045
|
+
:meth:`pAdicCappedAbsoluteElement.__init__` for more details.
|
|
2046
|
+
|
|
2047
|
+
EXAMPLES::
|
|
2048
|
+
|
|
2049
|
+
sage: # needs sage.libs.flint
|
|
2050
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
2051
|
+
sage: K = R.fraction_field()
|
|
2052
|
+
sage: f = R.convert_map_from(K); a = K(a)
|
|
2053
|
+
sage: f(a, 3)
|
|
2054
|
+
a
|
|
2055
|
+
sage: b = 9*a + 27
|
|
2056
|
+
sage: f(b, 3)
|
|
2057
|
+
a*3^2
|
|
2058
|
+
sage: f(b, 4, 1)
|
|
2059
|
+
a*3^2
|
|
2060
|
+
sage: f(b, 4, 3)
|
|
2061
|
+
a*3^2 + 3^3
|
|
2062
|
+
sage: f(b, absprec=4)
|
|
2063
|
+
a*3^2 + 3^3
|
|
2064
|
+
sage: f(b, relprec=3)
|
|
2065
|
+
a*3^2 + 3^3
|
|
2066
|
+
sage: f(b, absprec=1)
|
|
2067
|
+
0
|
|
2068
|
+
sage: f(K(0))
|
|
2069
|
+
0
|
|
2070
|
+
"""
|
|
2071
|
+
cdef long aprec, rprec
|
|
2072
|
+
cdef FPElement x = _x
|
|
2073
|
+
if x.ordp < 0:
|
|
2074
|
+
raise ValueError("negative valuation")
|
|
2075
|
+
cdef FPElement ans = self._zero._new_c()
|
|
2076
|
+
cdef bint reduce = False
|
|
2077
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, ans.prime_pow)
|
|
2078
|
+
if aprec <= x.ordp:
|
|
2079
|
+
ans._set_exact_zero()
|
|
2080
|
+
else:
|
|
2081
|
+
if rprec < ans.prime_pow.ram_prec_cap:
|
|
2082
|
+
reduce = True
|
|
2083
|
+
else:
|
|
2084
|
+
rprec = ans.prime_pow.ram_prec_cap
|
|
2085
|
+
if aprec < rprec + x.ordp:
|
|
2086
|
+
rprec = aprec - x.ordp
|
|
2087
|
+
reduce = True
|
|
2088
|
+
ans.ordp = x.ordp
|
|
2089
|
+
cshift_notrunc(ans.unit, x.unit, 0, rprec, x.prime_pow, reduce)
|
|
2090
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2091
|
+
# The base ring is wrong, so we fix it.
|
|
2092
|
+
K = ans.unit.base_ring()
|
|
2093
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
2094
|
+
return ans
|
|
2095
|
+
|
|
2096
|
+
cdef dict _extra_slots(self):
|
|
2097
|
+
r"""
|
|
2098
|
+
Helper for copying and pickling.
|
|
2099
|
+
|
|
2100
|
+
TESTS::
|
|
2101
|
+
|
|
2102
|
+
sage: # needs sage.libs.flint
|
|
2103
|
+
sage: R.<a> = ZqFP(27, implementation='FLINT')
|
|
2104
|
+
sage: K = R.fraction_field()
|
|
2105
|
+
sage: f = R.convert_map_from(K)
|
|
2106
|
+
sage: a = K(a)
|
|
2107
|
+
sage: g = copy(f) # indirect doctest
|
|
2108
|
+
sage: g
|
|
2109
|
+
Generic morphism:
|
|
2110
|
+
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
2111
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
2112
|
+
sage: g == f
|
|
2113
|
+
True
|
|
2114
|
+
sage: g is f
|
|
2115
|
+
False
|
|
2116
|
+
sage: g(a)
|
|
2117
|
+
a
|
|
2118
|
+
sage: g(a) == f(a)
|
|
2119
|
+
True
|
|
2120
|
+
"""
|
|
2121
|
+
_slots = Morphism._extra_slots(self)
|
|
2122
|
+
_slots['_zero'] = self._zero
|
|
2123
|
+
return _slots
|
|
2124
|
+
|
|
2125
|
+
cdef _update_slots(self, dict _slots):
|
|
2126
|
+
r"""
|
|
2127
|
+
Helper for copying and pickling.
|
|
2128
|
+
|
|
2129
|
+
TESTS::
|
|
2130
|
+
|
|
2131
|
+
sage: # needs sage.libs.flint
|
|
2132
|
+
sage: R.<a> = ZqFP(9, implementation='FLINT')
|
|
2133
|
+
sage: K = R.fraction_field()
|
|
2134
|
+
sage: f = R.convert_map_from(K)
|
|
2135
|
+
sage: a = K(a)
|
|
2136
|
+
sage: g = copy(f) # indirect doctest
|
|
2137
|
+
sage: g
|
|
2138
|
+
Generic morphism:
|
|
2139
|
+
From: 3-adic Unramified Extension Field in a defined by x^2 + 2*x + 2
|
|
2140
|
+
To: 3-adic Unramified Extension Ring in a defined by x^2 + 2*x + 2
|
|
2141
|
+
sage: g == f
|
|
2142
|
+
True
|
|
2143
|
+
sage: g is f
|
|
2144
|
+
False
|
|
2145
|
+
sage: g(a)
|
|
2146
|
+
a
|
|
2147
|
+
sage: g(a) == f(a)
|
|
2148
|
+
True
|
|
2149
|
+
"""
|
|
2150
|
+
self._zero = _slots['_zero']
|
|
2151
|
+
Morphism._update_slots(self, _slots)
|
|
2152
|
+
|
|
2153
|
+
|
|
2154
|
+
def unpickle_fpe_v2(cls, parent, unit, ordp):
|
|
2155
|
+
"""
|
|
2156
|
+
Unpickles a floating point element.
|
|
2157
|
+
|
|
2158
|
+
EXAMPLES::
|
|
2159
|
+
|
|
2160
|
+
sage: from sage.rings.padics.padic_floating_point_element import pAdicFloatingPointElement, unpickle_fpe_v2
|
|
2161
|
+
sage: R = ZpFP(5)
|
|
2162
|
+
sage: a = unpickle_fpe_v2(pAdicFloatingPointElement, R, 17, 2); a
|
|
2163
|
+
2*5^2 + 3*5^3
|
|
2164
|
+
sage: a.parent() is R
|
|
2165
|
+
True
|
|
2166
|
+
"""
|
|
2167
|
+
cdef FPElement ans = cls.__new__(cls)
|
|
2168
|
+
ans._parent = parent
|
|
2169
|
+
ans.prime_pow = <PowComputer_?>parent.prime_pow
|
|
2170
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2171
|
+
polyt = type(ans.prime_pow.modulus)
|
|
2172
|
+
ans.unit = <celement>polyt.__new__(polyt)
|
|
2173
|
+
cconstruct(ans.unit, ans.prime_pow)
|
|
2174
|
+
cunpickle(ans.unit, unit, ans.prime_pow)
|
|
2175
|
+
ans.ordp = ordp
|
|
2176
|
+
return ans
|