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,2563 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
"""
|
|
3
|
+
Capped relative template for complete discrete valuation rings and their fraction fields
|
|
4
|
+
|
|
5
|
+
In order to use this template you need to write a linkage file and gluing file.
|
|
6
|
+
For an example see ``mpz_linkage.pxi`` (linkage file) and ``padic_capped_relative_element.pyx`` (gluing file).
|
|
7
|
+
|
|
8
|
+
The linkage file implements a common API that is then used in the class :class:`CRElement` defined here.
|
|
9
|
+
See the documentation of ``mpz_linkage.pxi`` for the functions needed.
|
|
10
|
+
|
|
11
|
+
The gluing file does the following:
|
|
12
|
+
|
|
13
|
+
- ``ctypedef``'s ``celement`` to be the appropriate type (e.g. ``mpz_t``)
|
|
14
|
+
- includes the linkage file
|
|
15
|
+
- includes this template
|
|
16
|
+
- defines a concrete class inheriting from ``CRElement``, and implements
|
|
17
|
+
any desired extra methods
|
|
18
|
+
|
|
19
|
+
AUTHORS:
|
|
20
|
+
|
|
21
|
+
- David Roe (2012-3-1) -- initial version
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
#*****************************************************************************
|
|
25
|
+
# Copyright (C) 2007-2012 David Roe <roed.math@gmail.com>
|
|
26
|
+
# William Stein <wstein@gmail.com>
|
|
27
|
+
#
|
|
28
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
29
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
30
|
+
# the License, or (at your option) any later version.
|
|
31
|
+
#
|
|
32
|
+
# http://www.gnu.org/licenses/
|
|
33
|
+
#*****************************************************************************
|
|
34
|
+
|
|
35
|
+
# This file implements common functionality among template elements
|
|
36
|
+
include "padic_template_element.pxi"
|
|
37
|
+
|
|
38
|
+
from sage.structure.element cimport Element
|
|
39
|
+
from sage.rings.padics.common_conversion cimport comb_prec, _process_args_and_kwds
|
|
40
|
+
from sage.rings.integer_ring import ZZ
|
|
41
|
+
from sage.rings.rational_field import QQ
|
|
42
|
+
from sage.categories.sets_cat import Sets
|
|
43
|
+
from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
|
|
44
|
+
from sage.categories.homset import Hom
|
|
45
|
+
|
|
46
|
+
cdef inline bint exactzero(long ordp) noexcept:
|
|
47
|
+
"""
|
|
48
|
+
Whether a given valuation represents an exact zero.
|
|
49
|
+
"""
|
|
50
|
+
return ordp >= maxordp
|
|
51
|
+
|
|
52
|
+
cdef inline int check_ordp_mpz(mpz_t ordp) except -1:
|
|
53
|
+
"""
|
|
54
|
+
Check for overflow after addition or subtraction of valuations.
|
|
55
|
+
|
|
56
|
+
There is another variant, :meth:`check_ordp`, for long input.
|
|
57
|
+
|
|
58
|
+
If overflow is detected, raises an :exc:`OverflowError`.
|
|
59
|
+
"""
|
|
60
|
+
if mpz_fits_slong_p(ordp) == 0 or mpz_cmp_si(ordp, maxordp) > 0 or mpz_cmp_si(ordp, minusmaxordp) < 0:
|
|
61
|
+
raise OverflowError("valuation overflow")
|
|
62
|
+
|
|
63
|
+
cdef inline int assert_nonzero(CRElement x) except -1:
|
|
64
|
+
"""
|
|
65
|
+
Check that ``x`` is distinguishable from zero.
|
|
66
|
+
|
|
67
|
+
Used in division and floor division.
|
|
68
|
+
"""
|
|
69
|
+
if exactzero(x.ordp):
|
|
70
|
+
raise ZeroDivisionError("cannot divide by zero")
|
|
71
|
+
if x.relprec == 0:
|
|
72
|
+
raise PrecisionError("cannot divide by something indistinguishable from zero")
|
|
73
|
+
|
|
74
|
+
cdef class CRElement(pAdicTemplateElement):
|
|
75
|
+
cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1:
|
|
76
|
+
"""
|
|
77
|
+
Set the value of this element from given defining data.
|
|
78
|
+
|
|
79
|
+
This function is intended for use in conversion, and should
|
|
80
|
+
not be called on an element created with :meth:`_new_c`.
|
|
81
|
+
|
|
82
|
+
INPUT:
|
|
83
|
+
|
|
84
|
+
- ``x`` -- data defining a `p`-adic element: int,
|
|
85
|
+
Integer, Rational, other `p`-adic element...
|
|
86
|
+
|
|
87
|
+
- ``val`` -- the valuation of the resulting element
|
|
88
|
+
|
|
89
|
+
- ``xprec -- an inherent precision of ``x``
|
|
90
|
+
|
|
91
|
+
- ``absprec`` -- an absolute precision cap for this element
|
|
92
|
+
|
|
93
|
+
- ``relprec`` -- a relative precision cap for this element
|
|
94
|
+
|
|
95
|
+
TESTS::
|
|
96
|
+
|
|
97
|
+
sage: R = Zp(5)
|
|
98
|
+
sage: R(15) # indirect doctest
|
|
99
|
+
3*5 + O(5^21)
|
|
100
|
+
sage: R(15, absprec=5)
|
|
101
|
+
3*5 + O(5^5)
|
|
102
|
+
sage: R(15, relprec=5)
|
|
103
|
+
3*5 + O(5^6)
|
|
104
|
+
sage: R(75, absprec = 10, relprec = 9) # indirect doctest
|
|
105
|
+
3*5^2 + O(5^10)
|
|
106
|
+
sage: R(25/9, relprec = 5) # indirect doctest
|
|
107
|
+
4*5^2 + 2*5^3 + 5^5 + 2*5^6 + O(5^7)
|
|
108
|
+
sage: R(25/9, relprec = 4, absprec = 5) # indirect doctest
|
|
109
|
+
4*5^2 + 2*5^3 + O(5^5)
|
|
110
|
+
|
|
111
|
+
sage: R = Zp(5,5)
|
|
112
|
+
sage: R(25/9) # indirect doctest
|
|
113
|
+
4*5^2 + 2*5^3 + 5^5 + 2*5^6 + O(5^7)
|
|
114
|
+
sage: R(25/9, absprec = 5)
|
|
115
|
+
4*5^2 + 2*5^3 + O(5^5)
|
|
116
|
+
sage: R(25/9, relprec = 4)
|
|
117
|
+
4*5^2 + 2*5^3 + 5^5 + O(5^6)
|
|
118
|
+
|
|
119
|
+
sage: R = Zp(5); S = Zp(5, 6)
|
|
120
|
+
sage: S(R(17)) # indirect doctest
|
|
121
|
+
2 + 3*5 + O(5^6)
|
|
122
|
+
sage: S(R(17),4) # indirect doctest
|
|
123
|
+
2 + 3*5 + O(5^4)
|
|
124
|
+
sage: T = Qp(5); a = T(1/5) - T(1/5)
|
|
125
|
+
sage: R(a)
|
|
126
|
+
O(5^19)
|
|
127
|
+
sage: S(a)
|
|
128
|
+
O(5^19)
|
|
129
|
+
sage: S(a, 17)
|
|
130
|
+
O(5^17)
|
|
131
|
+
|
|
132
|
+
sage: R = Zp(5); S = ZpCA(5)
|
|
133
|
+
sage: R(S(17, 5)) # indirect doctest
|
|
134
|
+
2 + 3*5 + O(5^5)
|
|
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
|
+
cdef long rprec = comb_prec(relprec, self.prime_pow.ram_prec_cap)
|
|
141
|
+
cdef long aprec = comb_prec(absprec, xprec)
|
|
142
|
+
if aprec <= val: # this may also hit an exact zero, if aprec == val == maxordp
|
|
143
|
+
self._set_inexact_zero(aprec)
|
|
144
|
+
elif exactzero(val):
|
|
145
|
+
self._set_exact_zero()
|
|
146
|
+
else:
|
|
147
|
+
self.relprec = min(rprec, aprec - val)
|
|
148
|
+
self.ordp = val
|
|
149
|
+
if isinstance(x, CRElement) and x.parent() is self.parent():
|
|
150
|
+
cshift_notrunc(self.unit, (<CRElement>x).unit, 0, self.relprec, self.prime_pow, True)
|
|
151
|
+
else:
|
|
152
|
+
cconv(self.unit, x, self.relprec, val, self.prime_pow)
|
|
153
|
+
|
|
154
|
+
cdef int _set_exact_zero(self) except -1:
|
|
155
|
+
"""
|
|
156
|
+
Set ``self`` as an exact zero.
|
|
157
|
+
|
|
158
|
+
TESTS::
|
|
159
|
+
|
|
160
|
+
sage: R = Zp(5); R(0) # indirect doctest
|
|
161
|
+
0
|
|
162
|
+
"""
|
|
163
|
+
csetzero(self.unit, self.prime_pow)
|
|
164
|
+
self.ordp = maxordp
|
|
165
|
+
self.relprec = 0
|
|
166
|
+
|
|
167
|
+
cdef int _set_inexact_zero(self, long absprec) except -1:
|
|
168
|
+
"""
|
|
169
|
+
Set ``self`` as an inexact zero with precision ``absprec``.
|
|
170
|
+
|
|
171
|
+
TESTS::
|
|
172
|
+
|
|
173
|
+
sage: R = Zp(5); R(0, 5) # indirect doctest
|
|
174
|
+
O(5^5)
|
|
175
|
+
"""
|
|
176
|
+
csetzero(self.unit, self.prime_pow)
|
|
177
|
+
self.ordp = absprec
|
|
178
|
+
self.relprec = 0
|
|
179
|
+
|
|
180
|
+
cdef CRElement _new_c(self):
|
|
181
|
+
"""
|
|
182
|
+
Create a new element with the same basic info.
|
|
183
|
+
|
|
184
|
+
TESTS::
|
|
185
|
+
|
|
186
|
+
sage: R = Zp(5)
|
|
187
|
+
sage: R(6,5) * R(7,8) # indirect doctest
|
|
188
|
+
2 + 3*5 + 5^2 + O(5^5)
|
|
189
|
+
|
|
190
|
+
sage: # needs sage.libs.ntl
|
|
191
|
+
sage: R.<a> = ZqCR(25)
|
|
192
|
+
sage: S.<x> = ZZ[]
|
|
193
|
+
sage: W.<w> = R.ext(x^2 - 5)
|
|
194
|
+
sage: w * (w+1) # indirect doctest
|
|
195
|
+
w + w^2 + O(w^41)
|
|
196
|
+
"""
|
|
197
|
+
cdef type t = type(self)
|
|
198
|
+
cdef type polyt
|
|
199
|
+
cdef CRElement ans = t.__new__(t)
|
|
200
|
+
ans._parent = self._parent
|
|
201
|
+
ans.prime_pow = self.prime_pow
|
|
202
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
203
|
+
polyt = type(self.prime_pow.modulus)
|
|
204
|
+
ans.unit = <celement>polyt.__new__(polyt)
|
|
205
|
+
cconstruct(ans.unit, ans.prime_pow)
|
|
206
|
+
return ans
|
|
207
|
+
|
|
208
|
+
cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec):
|
|
209
|
+
"""
|
|
210
|
+
Create a new element with a given value and absolute precision.
|
|
211
|
+
|
|
212
|
+
Used by code that doesn't know the precision type.
|
|
213
|
+
"""
|
|
214
|
+
cdef CRElement ans = self._new_c()
|
|
215
|
+
ans.relprec = absprec
|
|
216
|
+
ans.ordp = 0
|
|
217
|
+
ccopy(ans.unit, value, ans.prime_pow)
|
|
218
|
+
ans._normalize()
|
|
219
|
+
return ans
|
|
220
|
+
|
|
221
|
+
cdef int _get_unit(self, celement value) except -1:
|
|
222
|
+
"""
|
|
223
|
+
Set ``value`` to the unit of this `p`-adic element.
|
|
224
|
+
"""
|
|
225
|
+
ccopy(value, self.unit, self.prime_pow)
|
|
226
|
+
|
|
227
|
+
cdef int check_preccap(self) except -1:
|
|
228
|
+
"""
|
|
229
|
+
Check that this element doesn't have precision higher than
|
|
230
|
+
allowed by the precision cap.
|
|
231
|
+
|
|
232
|
+
TESTS::
|
|
233
|
+
|
|
234
|
+
sage: Zp(5)(1).lift_to_precision(30)
|
|
235
|
+
Traceback (most recent call last):
|
|
236
|
+
...
|
|
237
|
+
PrecisionError: precision higher than allowed by the precision cap
|
|
238
|
+
"""
|
|
239
|
+
if self.relprec > self.prime_pow.ram_prec_cap:
|
|
240
|
+
raise PrecisionError("precision higher than allowed by the precision cap")
|
|
241
|
+
|
|
242
|
+
def __copy__(self):
|
|
243
|
+
"""
|
|
244
|
+
Return a copy of this element.
|
|
245
|
+
|
|
246
|
+
EXAMPLES::
|
|
247
|
+
|
|
248
|
+
sage: a = Zp(5,6)(17); b = copy(a)
|
|
249
|
+
sage: a == b
|
|
250
|
+
True
|
|
251
|
+
sage: a is b
|
|
252
|
+
False
|
|
253
|
+
"""
|
|
254
|
+
cdef CRElement ans = self._new_c()
|
|
255
|
+
ans.relprec = self.relprec
|
|
256
|
+
ans.ordp = self.ordp
|
|
257
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
258
|
+
return ans
|
|
259
|
+
|
|
260
|
+
cdef int _normalize(self) except -1:
|
|
261
|
+
"""
|
|
262
|
+
Normalize this element, so that ``self.ordp`` is correct.
|
|
263
|
+
|
|
264
|
+
TESTS::
|
|
265
|
+
|
|
266
|
+
sage: R = Zp(5)
|
|
267
|
+
sage: R(6) + R(4) # indirect doctest
|
|
268
|
+
2*5 + O(5^20)
|
|
269
|
+
"""
|
|
270
|
+
cdef long diff
|
|
271
|
+
cdef bint is_zero
|
|
272
|
+
if not exactzero(self.ordp):
|
|
273
|
+
is_zero = creduce(self.unit, self.unit, self.relprec, self.prime_pow)
|
|
274
|
+
if is_zero:
|
|
275
|
+
self._set_inexact_zero(self.ordp + self.relprec)
|
|
276
|
+
else:
|
|
277
|
+
diff = cremove(self.unit, self.unit, self.relprec, self.prime_pow, True)
|
|
278
|
+
# diff is less than self.relprec since the reduction didn't yield zero
|
|
279
|
+
self.ordp += diff
|
|
280
|
+
check_ordp(self.ordp)
|
|
281
|
+
self.relprec -= diff
|
|
282
|
+
|
|
283
|
+
def __dealloc__(self):
|
|
284
|
+
"""
|
|
285
|
+
Deallocate the underlying data structure.
|
|
286
|
+
|
|
287
|
+
TESTS::
|
|
288
|
+
|
|
289
|
+
sage: R = Zp(5)
|
|
290
|
+
sage: a = R(17)
|
|
291
|
+
sage: del(a)
|
|
292
|
+
"""
|
|
293
|
+
cdestruct(self.unit, self.prime_pow)
|
|
294
|
+
|
|
295
|
+
def __reduce__(self):
|
|
296
|
+
"""
|
|
297
|
+
Return a tuple of a function and data that can be used to unpickle this
|
|
298
|
+
element.
|
|
299
|
+
|
|
300
|
+
TESTS::
|
|
301
|
+
|
|
302
|
+
sage: a = ZpCR(5)(-3)
|
|
303
|
+
sage: type(a)
|
|
304
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'>
|
|
305
|
+
sage: loads(dumps(a)) == a # indirect doctest
|
|
306
|
+
True
|
|
307
|
+
"""
|
|
308
|
+
return unpickle_cre_v2, (self.__class__, self.parent(), cpickle(self.unit, self.prime_pow), self.ordp, self.relprec)
|
|
309
|
+
|
|
310
|
+
cpdef _neg_(self):
|
|
311
|
+
"""
|
|
312
|
+
Return the additive inverse of this element.
|
|
313
|
+
|
|
314
|
+
EXAMPLES::
|
|
315
|
+
|
|
316
|
+
sage: R = Zp(5, 20, 'capped-rel', 'val-unit')
|
|
317
|
+
sage: R(5) + (-R(5)) # indirect doctest
|
|
318
|
+
O(5^21)
|
|
319
|
+
sage: -R(1)
|
|
320
|
+
95367431640624 + O(5^20)
|
|
321
|
+
sage: -R(5)
|
|
322
|
+
5 * 95367431640624 + O(5^21)
|
|
323
|
+
sage: -R(0)
|
|
324
|
+
0
|
|
325
|
+
"""
|
|
326
|
+
cdef CRElement ans = self._new_c()
|
|
327
|
+
ans.relprec = self.relprec
|
|
328
|
+
ans.ordp = self.ordp
|
|
329
|
+
if ans.relprec != 0:
|
|
330
|
+
cneg(ans.unit, self.unit, ans.relprec, ans.prime_pow)
|
|
331
|
+
creduce(ans.unit, ans.unit, ans.relprec, ans.prime_pow)
|
|
332
|
+
return ans
|
|
333
|
+
|
|
334
|
+
cpdef _add_(self, _right):
|
|
335
|
+
"""
|
|
336
|
+
Return the sum of this element and ``_right``.
|
|
337
|
+
|
|
338
|
+
EXAMPLES::
|
|
339
|
+
|
|
340
|
+
sage: R = Zp(19, 5, 'capped-rel','series')
|
|
341
|
+
sage: a = R(-1); a
|
|
342
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
343
|
+
sage: b=R(-5/2); b
|
|
344
|
+
7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
345
|
+
sage: a+b # indirect doctest
|
|
346
|
+
6 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
347
|
+
"""
|
|
348
|
+
cdef CRElement ans
|
|
349
|
+
cdef CRElement right = _right
|
|
350
|
+
cdef long tmpL
|
|
351
|
+
if self.ordp == right.ordp:
|
|
352
|
+
ans = self._new_c()
|
|
353
|
+
# The relative precision of the sum is the minimum of the relative precisions in this case,
|
|
354
|
+
# possibly decreasing if we got cancellation
|
|
355
|
+
ans.ordp = self.ordp
|
|
356
|
+
ans.relprec = min(self.relprec, right.relprec)
|
|
357
|
+
if ans.relprec != 0:
|
|
358
|
+
cadd(ans.unit, self.unit, right.unit, ans.relprec, ans.prime_pow)
|
|
359
|
+
ans._normalize()
|
|
360
|
+
else:
|
|
361
|
+
if self.ordp > right.ordp:
|
|
362
|
+
# Addition is commutative, swap so self.ordp < right.ordp
|
|
363
|
+
ans = right
|
|
364
|
+
right = self
|
|
365
|
+
self = ans
|
|
366
|
+
tmpL = right.ordp - self.ordp
|
|
367
|
+
if tmpL > self.relprec:
|
|
368
|
+
return self
|
|
369
|
+
ans = self._new_c()
|
|
370
|
+
ans.ordp = self.ordp
|
|
371
|
+
ans.relprec = min(self.relprec, tmpL + right.relprec)
|
|
372
|
+
if ans.relprec != 0:
|
|
373
|
+
cshift_notrunc(ans.unit, right.unit, tmpL, ans.relprec, ans.prime_pow, False)
|
|
374
|
+
cadd(ans.unit, ans.unit, self.unit, ans.relprec, ans.prime_pow)
|
|
375
|
+
creduce(ans.unit, ans.unit, ans.relprec, ans.prime_pow)
|
|
376
|
+
return ans
|
|
377
|
+
|
|
378
|
+
cpdef _sub_(self, _right):
|
|
379
|
+
"""
|
|
380
|
+
Return the difference of this element and ``_right``.
|
|
381
|
+
|
|
382
|
+
EXAMPLES::
|
|
383
|
+
|
|
384
|
+
sage: R = Zp(13, 4)
|
|
385
|
+
sage: R(10) - R(10) # indirect doctest
|
|
386
|
+
O(13^4)
|
|
387
|
+
sage: R(10) - R(11)
|
|
388
|
+
12 + 12*13 + 12*13^2 + 12*13^3 + O(13^4)
|
|
389
|
+
"""
|
|
390
|
+
cdef CRElement ans
|
|
391
|
+
cdef CRElement right = _right
|
|
392
|
+
cdef long tmpL
|
|
393
|
+
if self.ordp == right.ordp:
|
|
394
|
+
ans = self._new_c()
|
|
395
|
+
# The relative precision of the difference is the minimum of the relative precisions in this case,
|
|
396
|
+
# possibly decreasing if we got cancellation
|
|
397
|
+
ans.ordp = self.ordp
|
|
398
|
+
ans.relprec = min(self.relprec, right.relprec)
|
|
399
|
+
if ans.relprec != 0:
|
|
400
|
+
csub(ans.unit, self.unit, right.unit, ans.relprec, ans.prime_pow)
|
|
401
|
+
ans._normalize()
|
|
402
|
+
elif self.ordp < right.ordp:
|
|
403
|
+
tmpL = right.ordp - self.ordp
|
|
404
|
+
if tmpL > self.relprec:
|
|
405
|
+
return self
|
|
406
|
+
ans = self._new_c()
|
|
407
|
+
ans.ordp = self.ordp
|
|
408
|
+
ans.relprec = min(self.relprec, tmpL + right.relprec)
|
|
409
|
+
if ans.relprec != 0:
|
|
410
|
+
cshift_notrunc(ans.unit, right.unit, tmpL, ans.relprec, ans.prime_pow, False)
|
|
411
|
+
csub(ans.unit, self.unit, ans.unit, ans.relprec, ans.prime_pow)
|
|
412
|
+
creduce(ans.unit, ans.unit, ans.relprec, ans.prime_pow)
|
|
413
|
+
else:
|
|
414
|
+
tmpL = self.ordp - right.ordp
|
|
415
|
+
if tmpL > right.relprec:
|
|
416
|
+
return right._neg_()
|
|
417
|
+
ans = self._new_c()
|
|
418
|
+
ans.ordp = right.ordp
|
|
419
|
+
ans.relprec = min(right.relprec, tmpL + self.relprec)
|
|
420
|
+
if ans.relprec != 0:
|
|
421
|
+
cshift_notrunc(ans.unit, self.unit, tmpL, ans.relprec, ans.prime_pow, False)
|
|
422
|
+
csub(ans.unit, ans.unit, right.unit, ans.relprec, ans.prime_pow)
|
|
423
|
+
creduce(ans.unit, ans.unit, ans.relprec, ans.prime_pow)
|
|
424
|
+
return ans
|
|
425
|
+
|
|
426
|
+
def __invert__(self):
|
|
427
|
+
r"""
|
|
428
|
+
Return the multiplicative inverse of this element.
|
|
429
|
+
|
|
430
|
+
.. NOTE::
|
|
431
|
+
|
|
432
|
+
The result of inversion always lives in the fraction
|
|
433
|
+
field, even if the element to be inverted is a unit.
|
|
434
|
+
|
|
435
|
+
EXAMPLES::
|
|
436
|
+
|
|
437
|
+
sage: R = Qp(7,4,'capped-rel','series'); a = R(3); a
|
|
438
|
+
3 + O(7^4)
|
|
439
|
+
sage: ~a # indirect doctest
|
|
440
|
+
5 + 4*7 + 4*7^2 + 4*7^3 + O(7^4)
|
|
441
|
+
"""
|
|
442
|
+
assert_nonzero(self)
|
|
443
|
+
cdef CRElement ans = self._new_c()
|
|
444
|
+
if ans.prime_pow.in_field == 0:
|
|
445
|
+
ans._parent = self._parent.fraction_field()
|
|
446
|
+
ans.prime_pow = ans._parent.prime_pow
|
|
447
|
+
ans.ordp = -self.ordp
|
|
448
|
+
ans.relprec = self.relprec
|
|
449
|
+
cinvert(ans.unit, self.unit, ans.relprec, ans.prime_pow)
|
|
450
|
+
return ans
|
|
451
|
+
|
|
452
|
+
cpdef _mul_(self, _right):
|
|
453
|
+
r"""
|
|
454
|
+
Return the product of this element and ``_right``.
|
|
455
|
+
|
|
456
|
+
EXAMPLES::
|
|
457
|
+
|
|
458
|
+
sage: R = Zp(5)
|
|
459
|
+
sage: a = R(2385,11); a
|
|
460
|
+
2*5 + 4*5^3 + 3*5^4 + O(5^11)
|
|
461
|
+
sage: b = R(2387625, 16); b
|
|
462
|
+
5^3 + 4*5^5 + 2*5^6 + 5^8 + 5^9 + O(5^16)
|
|
463
|
+
sage: a * b # indirect doctest
|
|
464
|
+
2*5^4 + 2*5^6 + 4*5^7 + 2*5^8 + 3*5^10 + 5^11 + 3*5^12 + 4*5^13 + O(5^14)
|
|
465
|
+
"""
|
|
466
|
+
cdef CRElement ans
|
|
467
|
+
cdef CRElement right = _right
|
|
468
|
+
if exactzero(self.ordp):
|
|
469
|
+
return self
|
|
470
|
+
if exactzero(right.ordp):
|
|
471
|
+
return right
|
|
472
|
+
ans = self._new_c()
|
|
473
|
+
ans.relprec = min(self.relprec, right.relprec)
|
|
474
|
+
if ans.relprec == 0:
|
|
475
|
+
ans._set_inexact_zero(self.ordp + right.ordp)
|
|
476
|
+
else:
|
|
477
|
+
ans.ordp = self.ordp + right.ordp
|
|
478
|
+
cmul(ans.unit, self.unit, right.unit, ans.relprec, ans.prime_pow)
|
|
479
|
+
creduce(ans.unit, ans.unit, ans.relprec, ans.prime_pow)
|
|
480
|
+
check_ordp(ans.ordp)
|
|
481
|
+
return ans
|
|
482
|
+
|
|
483
|
+
cpdef _div_(self, _right):
|
|
484
|
+
"""
|
|
485
|
+
Return the quotient of this element and ``right``.
|
|
486
|
+
|
|
487
|
+
.. NOTE::
|
|
488
|
+
|
|
489
|
+
The result of division always lives in the fraction field,
|
|
490
|
+
even if the element to be inverted is a unit.
|
|
491
|
+
|
|
492
|
+
EXAMPLES::
|
|
493
|
+
|
|
494
|
+
sage: R = Zp(5,6)
|
|
495
|
+
sage: R(17) / R(21) # indirect doctest
|
|
496
|
+
2 + 4*5^2 + 3*5^3 + 4*5^4 + O(5^6)
|
|
497
|
+
sage: a = R(50) / R(5); a
|
|
498
|
+
2*5 + O(5^7)
|
|
499
|
+
sage: R(5) / R(50)
|
|
500
|
+
3*5^-1 + 2 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + O(5^5)
|
|
501
|
+
sage: ~a
|
|
502
|
+
3*5^-1 + 2 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + O(5^5)
|
|
503
|
+
sage: 1 / a
|
|
504
|
+
3*5^-1 + 2 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + O(5^5)
|
|
505
|
+
"""
|
|
506
|
+
cdef CRElement ans
|
|
507
|
+
cdef CRElement right = _right
|
|
508
|
+
assert_nonzero(right)
|
|
509
|
+
ans = self._new_c()
|
|
510
|
+
if ans.prime_pow.in_field == 0:
|
|
511
|
+
ans._parent = self._parent.fraction_field()
|
|
512
|
+
ans.prime_pow = ans._parent.prime_pow
|
|
513
|
+
if exactzero(self.ordp):
|
|
514
|
+
ans._set_exact_zero()
|
|
515
|
+
return ans
|
|
516
|
+
ans.relprec = min(self.relprec, right.relprec)
|
|
517
|
+
if ans.relprec == 0:
|
|
518
|
+
ans._set_inexact_zero(self.ordp - right.ordp)
|
|
519
|
+
else:
|
|
520
|
+
ans.ordp = self.ordp - right.ordp
|
|
521
|
+
cdivunit(ans.unit, self.unit, right.unit, ans.relprec, ans.prime_pow)
|
|
522
|
+
creduce(ans.unit, ans.unit, ans.relprec, ans.prime_pow)
|
|
523
|
+
check_ordp(ans.ordp)
|
|
524
|
+
return ans
|
|
525
|
+
|
|
526
|
+
def __pow__(CRElement self, _right, dummy):
|
|
527
|
+
r"""
|
|
528
|
+
Exponentiation.
|
|
529
|
+
|
|
530
|
+
When ``right`` is divisible by `p` then one can get more
|
|
531
|
+
precision than expected.
|
|
532
|
+
|
|
533
|
+
Lemma 2.1 [Pau2006]_:
|
|
534
|
+
|
|
535
|
+
Let `\alpha` be in `\mathcal{O}_K`. Let
|
|
536
|
+
|
|
537
|
+
.. MATH::
|
|
538
|
+
|
|
539
|
+
p = -\pi_K^{e_K} \epsilon
|
|
540
|
+
|
|
541
|
+
be the factorization of `p` where `\epsilon` is a unit. Then
|
|
542
|
+
the `p`-th power of `1 + \alpha \pi_K^{\lambda}` satisfies
|
|
543
|
+
|
|
544
|
+
.. MATH::
|
|
545
|
+
|
|
546
|
+
(1 + \alpha \pi^{\lambda})^p \equiv \left{ \begin{array}{lll}
|
|
547
|
+
1 + \alpha^p \pi_K^{p \lambda} &
|
|
548
|
+
\mod \mathfrak{p}_K^{p \lambda + 1} &
|
|
549
|
+
\mbox{if $1 \le \lambda < \frac{e_K}{p-1}$} \\
|
|
550
|
+
1 + (\alpha^p - \epsilon \alpha) \pi_K^{p \lambda} &
|
|
551
|
+
\mod \mathfrak{p}_K^{p \lambda + 1} &
|
|
552
|
+
\mbox{if $\lambda = \frac{e_K}{p-1}$} \\
|
|
553
|
+
1 - \epsilon \alpha \pi_K^{\lambda + e} &
|
|
554
|
+
\mod \mathfrak{p}_K^{\lambda + e + 1} &
|
|
555
|
+
\mbox{if $\lambda > \frac{e_K}{p-1}$}
|
|
556
|
+
\end{array} \right.
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
So if ``right`` is divisible by `p^k` we can multiply the
|
|
560
|
+
relative precision by `p` until we exceed `e/(p-1)`, then add
|
|
561
|
+
`e` until we have done a total of `k` things: the precision of
|
|
562
|
+
the result can therefore be greater than the precision of
|
|
563
|
+
``self``.
|
|
564
|
+
|
|
565
|
+
For `\alpha` in `\ZZ_p` we can simplify the result a bit. In
|
|
566
|
+
this case, the `p`-th power of `1 + \alpha p^{\lambda}`
|
|
567
|
+
satisfies
|
|
568
|
+
|
|
569
|
+
.. MATH::
|
|
570
|
+
|
|
571
|
+
(1 + \alpha p^{\lambda})^p \equiv 1 + \alpha p^{\lambda + 1} mod p^{\lambda + 2}
|
|
572
|
+
|
|
573
|
+
unless `\lambda = 1` and `p = 2`, in which case
|
|
574
|
+
|
|
575
|
+
.. MATH::
|
|
576
|
+
|
|
577
|
+
(1 + 2 \alpha)^2 \equiv 1 + 4(\alpha^2 + \alpha) mod 8
|
|
578
|
+
|
|
579
|
+
So for `p \ne 2`, if right is divisible by `p^k` then we add
|
|
580
|
+
`k` to the relative precision of the answer.
|
|
581
|
+
|
|
582
|
+
For `p = 2`, if we start with something of relative precision
|
|
583
|
+
1 (ie `2^m + O(2^{m+1})`), `\alpha^2 + \alpha \equiv 0 \mod
|
|
584
|
+
2`, so the precision of the result is `k + 2`:
|
|
585
|
+
|
|
586
|
+
.. MATH::
|
|
587
|
+
|
|
588
|
+
(2^m + O(2^{m+1}))^{2^k} = 2^{m 2^k} + O(2^{m 2^k + k + 2})
|
|
589
|
+
|
|
590
|
+
For `p`-adic exponents, we define `\alpha^\beta` as
|
|
591
|
+
`\exp(\beta \log(\alpha))`. The precision of the result is
|
|
592
|
+
determined using the power series expansions for the
|
|
593
|
+
exponential and logarithm maps, together with the notes above.
|
|
594
|
+
|
|
595
|
+
.. NOTE::
|
|
596
|
+
|
|
597
|
+
For `p`-adic exponents we always need that `a` is a unit.
|
|
598
|
+
For unramified extensions `a^b` will converge as long as
|
|
599
|
+
`b` is integral (though it may converge for non-integral
|
|
600
|
+
`b` as well depending on the value of `a`). However, in
|
|
601
|
+
highly ramified extensions some bases may be sufficiently
|
|
602
|
+
close to `1` that `exp(b log(a))` does not converge even
|
|
603
|
+
though `b` is integral.
|
|
604
|
+
|
|
605
|
+
.. WARNING::
|
|
606
|
+
|
|
607
|
+
If `\alpha` is a unit, but not congruent to `1` modulo
|
|
608
|
+
`\pi_K`, the result will not be the limit over integers
|
|
609
|
+
`b` converging to `\beta` since this limit does not exist.
|
|
610
|
+
Rather, the logarithm kills torsion in `\ZZ_p^\times`, and
|
|
611
|
+
`\alpha^\beta` will equal `(\alpha')^\beta`, where
|
|
612
|
+
`\alpha'` is the quotient of `\alpha` by the Teichmuller
|
|
613
|
+
representative congruent to `\alpha` modulo `\pi_K`. Thus
|
|
614
|
+
the result will always be congruent to `1` modulo `\pi_K`.
|
|
615
|
+
|
|
616
|
+
REFERENCES:
|
|
617
|
+
|
|
618
|
+
- [Pau2006]_
|
|
619
|
+
|
|
620
|
+
INPUT:
|
|
621
|
+
|
|
622
|
+
- ``_right`` -- currently integers and `p`-adic exponents are
|
|
623
|
+
supported
|
|
624
|
+
|
|
625
|
+
- ``dummy`` -- not used (Python's ``__pow__`` signature
|
|
626
|
+
includes it)
|
|
627
|
+
|
|
628
|
+
EXAMPLES::
|
|
629
|
+
|
|
630
|
+
sage: R = Zp(19, 5, 'capped-rel','series')
|
|
631
|
+
sage: a = R(-1); a
|
|
632
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
633
|
+
sage: a^2 # indirect doctest
|
|
634
|
+
1 + O(19^5)
|
|
635
|
+
sage: a^3
|
|
636
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
637
|
+
sage: R(5)^30
|
|
638
|
+
11 + 14*19 + 19^2 + 7*19^3 + O(19^5)
|
|
639
|
+
sage: K = Qp(19, 5, 'capped-rel','series')
|
|
640
|
+
sage: a = K(-1); a
|
|
641
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
642
|
+
sage: a^2
|
|
643
|
+
1 + O(19^5)
|
|
644
|
+
sage: a^3
|
|
645
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
646
|
+
sage: K(5)^30
|
|
647
|
+
11 + 14*19 + 19^2 + 7*19^3 + O(19^5)
|
|
648
|
+
sage: K(5, 3)^19 # indirect doctest
|
|
649
|
+
5 + 3*19 + 11*19^3 + O(19^4)
|
|
650
|
+
|
|
651
|
+
`p`-adic exponents are also supported::
|
|
652
|
+
|
|
653
|
+
sage: a = K(8/5,4); a
|
|
654
|
+
13 + 7*19 + 11*19^2 + 7*19^3 + O(19^4)
|
|
655
|
+
sage: a^(K(19/7))
|
|
656
|
+
1 + 14*19^2 + 11*19^3 + 13*19^4 + O(19^5)
|
|
657
|
+
sage: (a // K.teichmuller(13))^(K(19/7))
|
|
658
|
+
1 + 14*19^2 + 11*19^3 + 13*19^4 + O(19^5)
|
|
659
|
+
sage: (a.log() * 19/7).exp()
|
|
660
|
+
1 + 14*19^2 + 11*19^3 + 13*19^4 + O(19^5)
|
|
661
|
+
|
|
662
|
+
TESTS:
|
|
663
|
+
|
|
664
|
+
Check that :issue:`31875` is fixed::
|
|
665
|
+
|
|
666
|
+
sage: R(1)^R(0)
|
|
667
|
+
1 + O(19^5)
|
|
668
|
+
|
|
669
|
+
sage: # needs sage.libs.ntl
|
|
670
|
+
sage: S.<a> = ZqCR(4)
|
|
671
|
+
sage: S(1)^S(0)
|
|
672
|
+
1 + O(2^20)
|
|
673
|
+
"""
|
|
674
|
+
cdef long base_level, exp_prec
|
|
675
|
+
cdef mpz_t tmp
|
|
676
|
+
cdef Integer right
|
|
677
|
+
cdef CRElement base, pright, ans
|
|
678
|
+
cdef bint exact_exp
|
|
679
|
+
if isinstance(_right, (Integer, int, Rational)):
|
|
680
|
+
if _right < 0:
|
|
681
|
+
base = ~self
|
|
682
|
+
return base.__pow__(-_right, dummy)
|
|
683
|
+
exact_exp = True
|
|
684
|
+
elif self.parent() is _right.parent():
|
|
685
|
+
# For extension elements, we need to switch to the
|
|
686
|
+
# fraction field sometimes in highly ramified extensions.
|
|
687
|
+
exact_exp = (<CRElement>_right)._is_exact_zero()
|
|
688
|
+
pright = _right
|
|
689
|
+
else:
|
|
690
|
+
self, _right = canonical_coercion(self, _right)
|
|
691
|
+
return self.__pow__(_right, dummy)
|
|
692
|
+
if exact_exp and _right == 0:
|
|
693
|
+
# return 1 to maximum precision
|
|
694
|
+
ans = self._new_c()
|
|
695
|
+
ans.ordp = 0
|
|
696
|
+
ans.relprec = self.prime_pow.ram_prec_cap
|
|
697
|
+
csetone(ans.unit, ans.prime_pow)
|
|
698
|
+
return ans
|
|
699
|
+
if exactzero(self.ordp):
|
|
700
|
+
if exact_exp:
|
|
701
|
+
# We may assume from above that right > 0
|
|
702
|
+
return self
|
|
703
|
+
else:
|
|
704
|
+
# log(0) is not defined
|
|
705
|
+
raise ValueError("0^x is not defined for p-adic x: log(0) does not converge")
|
|
706
|
+
ans = self._new_c()
|
|
707
|
+
if self.relprec == 0:
|
|
708
|
+
# If a positive integer exponent, return an inexact zero of valuation right * self.ordp. Otherwise raise an error.
|
|
709
|
+
if isinstance(_right, int):
|
|
710
|
+
_right = Integer(_right)
|
|
711
|
+
if isinstance(_right, Integer):
|
|
712
|
+
right = <Integer>_right
|
|
713
|
+
mpz_init(tmp)
|
|
714
|
+
mpz_mul_si(tmp, (<Integer>_right).value, self.ordp)
|
|
715
|
+
check_ordp_mpz(tmp)
|
|
716
|
+
ans._set_inexact_zero(mpz_get_si(tmp))
|
|
717
|
+
mpz_clear(tmp)
|
|
718
|
+
else:
|
|
719
|
+
raise PrecisionError
|
|
720
|
+
elif exact_exp:
|
|
721
|
+
# exact_pow_helper is defined in padic_template_element.pxi
|
|
722
|
+
right = exact_pow_helper(&ans.relprec, self.relprec, _right, self.prime_pow)
|
|
723
|
+
if ans.relprec > self.prime_pow.ram_prec_cap:
|
|
724
|
+
ans.relprec = self.prime_pow.ram_prec_cap
|
|
725
|
+
mpz_init(tmp)
|
|
726
|
+
mpz_mul_si(tmp, right.value, self.ordp)
|
|
727
|
+
check_ordp_mpz(tmp)
|
|
728
|
+
ans.ordp = mpz_get_si(tmp)
|
|
729
|
+
mpz_clear(tmp)
|
|
730
|
+
cpow(ans.unit, self.unit, right.value, ans.relprec, ans.prime_pow)
|
|
731
|
+
else:
|
|
732
|
+
# padic_pow_helper is defined in padic_template_element.pxi
|
|
733
|
+
ans.relprec = padic_pow_helper(ans.unit, self.unit, self.ordp, self.relprec,
|
|
734
|
+
pright.unit, pright.ordp, pright.relprec, self.prime_pow)
|
|
735
|
+
ans.ordp = 0
|
|
736
|
+
return ans
|
|
737
|
+
|
|
738
|
+
cdef pAdicTemplateElement _lshift_c(self, long shift):
|
|
739
|
+
r"""
|
|
740
|
+
Multiply by `\pi^{\mbox{shift}}`.
|
|
741
|
+
|
|
742
|
+
Negative shifts may truncate the result if the parent is not a
|
|
743
|
+
field.
|
|
744
|
+
|
|
745
|
+
TESTS::
|
|
746
|
+
|
|
747
|
+
sage: a = Zp(5)(17); a
|
|
748
|
+
2 + 3*5 + O(5^20)
|
|
749
|
+
sage: a << 2 # indirect doctest
|
|
750
|
+
2*5^2 + 3*5^3 + O(5^22)
|
|
751
|
+
sage: a << -2
|
|
752
|
+
O(5^18)
|
|
753
|
+
sage: a << 0 == a
|
|
754
|
+
True
|
|
755
|
+
sage: Zp(5)(0) << -4000
|
|
756
|
+
0
|
|
757
|
+
"""
|
|
758
|
+
if exactzero(self.ordp):
|
|
759
|
+
return self
|
|
760
|
+
if self.prime_pow.in_field == 0 and shift < 0 and -shift > self.ordp:
|
|
761
|
+
return self._rshift_c(-shift)
|
|
762
|
+
cdef CRElement ans = self._new_c()
|
|
763
|
+
ans.relprec = self.relprec
|
|
764
|
+
ans.ordp = self.ordp + shift
|
|
765
|
+
check_ordp(ans.ordp)
|
|
766
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
767
|
+
return ans
|
|
768
|
+
|
|
769
|
+
cdef pAdicTemplateElement _rshift_c(self, long shift):
|
|
770
|
+
r"""
|
|
771
|
+
Divide by ``\pi^{\mbox{shift}}``.
|
|
772
|
+
|
|
773
|
+
Positive shifts may truncate the result if the parent is not a
|
|
774
|
+
field.
|
|
775
|
+
|
|
776
|
+
TESTS::
|
|
777
|
+
|
|
778
|
+
sage: R = Zp(5); K = Qp(5)
|
|
779
|
+
sage: R(17) >> 1
|
|
780
|
+
3 + O(5^19)
|
|
781
|
+
sage: K(17) >> 1
|
|
782
|
+
2*5^-1 + 3 + O(5^19)
|
|
783
|
+
sage: R(17) >> 40
|
|
784
|
+
O(5^0)
|
|
785
|
+
sage: K(17) >> -5
|
|
786
|
+
2*5^5 + 3*5^6 + O(5^25)
|
|
787
|
+
"""
|
|
788
|
+
if exactzero(self.ordp):
|
|
789
|
+
return self
|
|
790
|
+
cdef CRElement ans = self._new_c()
|
|
791
|
+
cdef long diff
|
|
792
|
+
if self.prime_pow.in_field == 1 or shift <= self.ordp:
|
|
793
|
+
ans.relprec = self.relprec
|
|
794
|
+
ans.ordp = self.ordp - shift
|
|
795
|
+
check_ordp(ans.ordp)
|
|
796
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
797
|
+
else:
|
|
798
|
+
diff = shift - self.ordp
|
|
799
|
+
if diff >= self.relprec:
|
|
800
|
+
ans._set_inexact_zero(0)
|
|
801
|
+
else:
|
|
802
|
+
ans.relprec = self.relprec - diff
|
|
803
|
+
cshift(ans.unit, ans.prime_pow.shift_rem, self.unit, -diff, ans.relprec, ans.prime_pow, False)
|
|
804
|
+
ans.ordp = 0
|
|
805
|
+
ans._normalize()
|
|
806
|
+
return ans
|
|
807
|
+
|
|
808
|
+
def _quo_rem(self, _right):
|
|
809
|
+
"""
|
|
810
|
+
Quotient with remainder.
|
|
811
|
+
|
|
812
|
+
We choose the remainder to have the same `p`-adic expansion
|
|
813
|
+
as the numerator, but truncated at the valuation of the denominator.
|
|
814
|
+
|
|
815
|
+
EXAMPLES::
|
|
816
|
+
|
|
817
|
+
sage: R = Zp(3, 5)
|
|
818
|
+
sage: R(12).quo_rem(R(2)) # indirect doctest
|
|
819
|
+
(2*3 + O(3^6), 0)
|
|
820
|
+
sage: R(2).quo_rem(R(12))
|
|
821
|
+
(O(3^4), 2 + O(3^5))
|
|
822
|
+
sage: q, r = R(4).quo_rem(R(12)); q, r
|
|
823
|
+
(1 + 2*3 + 2*3^3 + O(3^4), 1 + O(3^5))
|
|
824
|
+
sage: 12*q + r == 4
|
|
825
|
+
True
|
|
826
|
+
|
|
827
|
+
In general, the remainder is returned with maximal precision.
|
|
828
|
+
However, it is not the case when the valuation of the divisor
|
|
829
|
+
is greater than the absolute precision on the numerator::
|
|
830
|
+
|
|
831
|
+
sage: R(1,2).quo_rem(R(81))
|
|
832
|
+
(O(3^0), 1 + O(3^2))
|
|
833
|
+
|
|
834
|
+
For fields the normal quotient always has remainder 0:
|
|
835
|
+
|
|
836
|
+
sage: K = Qp(3, 5)
|
|
837
|
+
sage: K(12).quo_rem(K(2))
|
|
838
|
+
(2*3 + O(3^6), 0)
|
|
839
|
+
sage: q, r = K(4).quo_rem(K(12)); q, r
|
|
840
|
+
(3^-1 + O(3^4), 0)
|
|
841
|
+
sage: 12*q + r == 4
|
|
842
|
+
True
|
|
843
|
+
|
|
844
|
+
You can get the same behavior for fields as for rings
|
|
845
|
+
by using integral=True::
|
|
846
|
+
|
|
847
|
+
sage: K(12).quo_rem(K(2), integral=True)
|
|
848
|
+
(2*3 + O(3^6), 0)
|
|
849
|
+
sage: K(2).quo_rem(K(12), integral=True)
|
|
850
|
+
(O(3^4), 2 + O(3^5))
|
|
851
|
+
"""
|
|
852
|
+
cdef CRElement right = _right
|
|
853
|
+
assert_nonzero(right)
|
|
854
|
+
if exactzero(self.ordp):
|
|
855
|
+
return self, self
|
|
856
|
+
cdef CRElement q = self._new_c()
|
|
857
|
+
cdef CRElement r = self._new_c()
|
|
858
|
+
cdef long diff = self.ordp - right.ordp
|
|
859
|
+
cdef long qrprec = diff + self.relprec
|
|
860
|
+
if qrprec < 0:
|
|
861
|
+
q._set_inexact_zero(0)
|
|
862
|
+
r = self
|
|
863
|
+
elif qrprec == 0:
|
|
864
|
+
q._set_inexact_zero(0)
|
|
865
|
+
r.ordp = self.ordp
|
|
866
|
+
r.relprec = self.prime_pow.ram_prec_cap
|
|
867
|
+
ccopy(r.unit, self.unit, r.prime_pow)
|
|
868
|
+
elif self.relprec == 0:
|
|
869
|
+
q._set_inexact_zero(diff)
|
|
870
|
+
r._set_exact_zero()
|
|
871
|
+
elif diff >= 0:
|
|
872
|
+
q.ordp = diff
|
|
873
|
+
q.relprec = min(self.relprec, right.relprec)
|
|
874
|
+
cdivunit(q.unit, self.unit, right.unit, q.relprec, q.prime_pow)
|
|
875
|
+
r._set_exact_zero()
|
|
876
|
+
else:
|
|
877
|
+
r.ordp = self.ordp
|
|
878
|
+
r.relprec = self.prime_pow.ram_prec_cap
|
|
879
|
+
q.ordp = 0
|
|
880
|
+
q.relprec = min(qrprec, right.relprec)
|
|
881
|
+
cshift(q.prime_pow.shift_rem, r.unit, self.unit, diff, q.relprec, q.prime_pow, False)
|
|
882
|
+
cdivunit(q.unit, q.prime_pow.shift_rem, right.unit, q.relprec, q.prime_pow)
|
|
883
|
+
q._normalize()
|
|
884
|
+
return q, r
|
|
885
|
+
|
|
886
|
+
def add_bigoh(self, absprec):
|
|
887
|
+
"""
|
|
888
|
+
Return a new element with absolute precision decreased to
|
|
889
|
+
``absprec``.
|
|
890
|
+
|
|
891
|
+
INPUT:
|
|
892
|
+
|
|
893
|
+
- ``absprec`` -- integer or infinity
|
|
894
|
+
|
|
895
|
+
OUTPUT:
|
|
896
|
+
|
|
897
|
+
an equal element with precision set to the minimum of ``self``'s
|
|
898
|
+
precision and ``absprec``
|
|
899
|
+
|
|
900
|
+
EXAMPLES::
|
|
901
|
+
|
|
902
|
+
sage: R = Zp(7,4,'capped-rel','series'); a = R(8); a.add_bigoh(1)
|
|
903
|
+
1 + O(7)
|
|
904
|
+
sage: b = R(0); b.add_bigoh(3)
|
|
905
|
+
O(7^3)
|
|
906
|
+
sage: R = Qp(7,4); a = R(8); a.add_bigoh(1)
|
|
907
|
+
1 + O(7)
|
|
908
|
+
sage: b = R(0); b.add_bigoh(3)
|
|
909
|
+
O(7^3)
|
|
910
|
+
|
|
911
|
+
The precision never increases::
|
|
912
|
+
|
|
913
|
+
sage: R(4).add_bigoh(2).add_bigoh(4)
|
|
914
|
+
4 + O(7^2)
|
|
915
|
+
|
|
916
|
+
Another example that illustrates that the precision does
|
|
917
|
+
not increase::
|
|
918
|
+
|
|
919
|
+
sage: k = Qp(3,5)
|
|
920
|
+
sage: a = k(1234123412/3^70); a
|
|
921
|
+
2*3^-70 + 3^-69 + 3^-68 + 3^-67 + O(3^-65)
|
|
922
|
+
sage: a.add_bigoh(2)
|
|
923
|
+
2*3^-70 + 3^-69 + 3^-68 + 3^-67 + O(3^-65)
|
|
924
|
+
|
|
925
|
+
sage: k = Qp(5,10)
|
|
926
|
+
sage: a = k(1/5^3 + 5^2); a
|
|
927
|
+
5^-3 + 5^2 + O(5^7)
|
|
928
|
+
sage: a.add_bigoh(2)
|
|
929
|
+
5^-3 + O(5^2)
|
|
930
|
+
sage: a.add_bigoh(-1)
|
|
931
|
+
5^-3 + O(5^-1)
|
|
932
|
+
"""
|
|
933
|
+
cdef CRElement ans
|
|
934
|
+
cdef long aprec, newprec
|
|
935
|
+
if absprec is infinity:
|
|
936
|
+
return self
|
|
937
|
+
elif isinstance(absprec, int):
|
|
938
|
+
aprec = absprec
|
|
939
|
+
else:
|
|
940
|
+
if not isinstance(absprec, Integer):
|
|
941
|
+
absprec = Integer(absprec)
|
|
942
|
+
if mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
943
|
+
if mpz_sgn((<Integer>absprec).value) == -1:
|
|
944
|
+
raise ValueError("absprec must fit into a signed long")
|
|
945
|
+
else:
|
|
946
|
+
aprec = self.prime_pow.ram_prec_cap
|
|
947
|
+
else:
|
|
948
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
949
|
+
if aprec < 0 and not self.parent().is_field():
|
|
950
|
+
return self.parent().fraction_field()(self).add_bigoh(absprec)
|
|
951
|
+
if aprec < self.ordp:
|
|
952
|
+
ans = self._new_c()
|
|
953
|
+
ans._set_inexact_zero(aprec)
|
|
954
|
+
elif aprec >= self.ordp + self.relprec:
|
|
955
|
+
ans = self
|
|
956
|
+
else:
|
|
957
|
+
ans = self._new_c()
|
|
958
|
+
ans.ordp = self.ordp
|
|
959
|
+
ans.relprec = aprec - self.ordp
|
|
960
|
+
creduce(ans.unit, self.unit, ans.relprec, ans.prime_pow)
|
|
961
|
+
return ans
|
|
962
|
+
|
|
963
|
+
cpdef bint _is_exact_zero(self) except -1:
|
|
964
|
+
"""
|
|
965
|
+
Return ``True`` if this element is exactly zero.
|
|
966
|
+
|
|
967
|
+
EXAMPLES::
|
|
968
|
+
|
|
969
|
+
sage: R = Zp(5)
|
|
970
|
+
sage: R(0)._is_exact_zero()
|
|
971
|
+
True
|
|
972
|
+
sage: R(0,5)._is_exact_zero()
|
|
973
|
+
False
|
|
974
|
+
sage: R(17)._is_exact_zero()
|
|
975
|
+
False
|
|
976
|
+
"""
|
|
977
|
+
return exactzero(self.ordp)
|
|
978
|
+
|
|
979
|
+
cpdef bint _is_inexact_zero(self) except -1:
|
|
980
|
+
"""
|
|
981
|
+
Return ``True`` if this element is indistinguishable from zero
|
|
982
|
+
but has finite precision.
|
|
983
|
+
|
|
984
|
+
EXAMPLES::
|
|
985
|
+
|
|
986
|
+
sage: R = Zp(5)
|
|
987
|
+
sage: R(0)._is_inexact_zero()
|
|
988
|
+
False
|
|
989
|
+
sage: R(0,5)._is_inexact_zero()
|
|
990
|
+
True
|
|
991
|
+
sage: R(17)._is_inexact_zero()
|
|
992
|
+
False
|
|
993
|
+
"""
|
|
994
|
+
return self.relprec == 0 and not exactzero(self.ordp)
|
|
995
|
+
|
|
996
|
+
def is_zero(self, absprec=None):
|
|
997
|
+
r"""
|
|
998
|
+
Determine whether this element is zero modulo
|
|
999
|
+
`\pi^{\mbox{absprec}}`.
|
|
1000
|
+
|
|
1001
|
+
If ``absprec`` is ``None``, returns ``True`` if this element is
|
|
1002
|
+
indistinguishable from zero.
|
|
1003
|
+
|
|
1004
|
+
INPUT:
|
|
1005
|
+
|
|
1006
|
+
- ``absprec`` -- integer, infinity, or ``None``
|
|
1007
|
+
|
|
1008
|
+
EXAMPLES::
|
|
1009
|
+
|
|
1010
|
+
sage: R = Zp(5); a = R(0); b = R(0,5); c = R(75)
|
|
1011
|
+
sage: a.is_zero(), a.is_zero(6)
|
|
1012
|
+
(True, True)
|
|
1013
|
+
sage: b.is_zero(), b.is_zero(5)
|
|
1014
|
+
(True, True)
|
|
1015
|
+
sage: c.is_zero(), c.is_zero(2), c.is_zero(3)
|
|
1016
|
+
(False, True, False)
|
|
1017
|
+
sage: b.is_zero(6)
|
|
1018
|
+
Traceback (most recent call last):
|
|
1019
|
+
...
|
|
1020
|
+
PrecisionError: not enough precision to determine if element is zero
|
|
1021
|
+
"""
|
|
1022
|
+
if absprec is None:
|
|
1023
|
+
return self.relprec == 0
|
|
1024
|
+
if exactzero(self.ordp):
|
|
1025
|
+
return True
|
|
1026
|
+
if absprec is infinity:
|
|
1027
|
+
return False
|
|
1028
|
+
if isinstance(absprec, int):
|
|
1029
|
+
if self.relprec == 0 and absprec > self.ordp:
|
|
1030
|
+
raise PrecisionError("not enough precision to determine if element is zero")
|
|
1031
|
+
return self.ordp >= absprec
|
|
1032
|
+
if not isinstance(absprec, Integer):
|
|
1033
|
+
absprec = Integer(absprec)
|
|
1034
|
+
if self.relprec == 0:
|
|
1035
|
+
if mpz_cmp_si((<Integer>absprec).value, self.ordp) > 0:
|
|
1036
|
+
raise PrecisionError("not enough precision to determine if element is zero")
|
|
1037
|
+
else:
|
|
1038
|
+
return True
|
|
1039
|
+
return mpz_cmp_si((<Integer>absprec).value, self.ordp) <= 0
|
|
1040
|
+
|
|
1041
|
+
def __bool__(self):
|
|
1042
|
+
"""
|
|
1043
|
+
Return ``True`` if ``self`` is distinguishable from zero.
|
|
1044
|
+
|
|
1045
|
+
For most applications, explicitly specifying the power of p
|
|
1046
|
+
modulo which the element is supposed to be nonzero is
|
|
1047
|
+
preferable.
|
|
1048
|
+
|
|
1049
|
+
EXAMPLES::
|
|
1050
|
+
|
|
1051
|
+
sage: R = Zp(5); a = R(0); b = R(0,5); c = R(75)
|
|
1052
|
+
sage: bool(a), bool(b), bool(c)
|
|
1053
|
+
(False, False, True)
|
|
1054
|
+
"""
|
|
1055
|
+
return self.relprec != 0
|
|
1056
|
+
|
|
1057
|
+
def is_equal_to(self, _right, absprec=None):
|
|
1058
|
+
r"""
|
|
1059
|
+
Return whether ``self`` is equal to ``right`` modulo
|
|
1060
|
+
`\pi^{\mbox{absprec}}`.
|
|
1061
|
+
|
|
1062
|
+
If ``absprec`` is ``None``, returns ``True`` if ``self`` and ``right`` are
|
|
1063
|
+
equal to the minimum of their precisions.
|
|
1064
|
+
|
|
1065
|
+
INPUT:
|
|
1066
|
+
|
|
1067
|
+
- ``right`` -- a `p`-adic element
|
|
1068
|
+
- ``absprec`` -- integer, infinity, or ``None``
|
|
1069
|
+
|
|
1070
|
+
EXAMPLES::
|
|
1071
|
+
|
|
1072
|
+
sage: R = Zp(5, 10); a = R(0); b = R(0, 3); c = R(75, 5)
|
|
1073
|
+
sage: aa = a + 625; bb = b + 625; cc = c + 625
|
|
1074
|
+
sage: a.is_equal_to(aa), a.is_equal_to(aa, 4), a.is_equal_to(aa, 5)
|
|
1075
|
+
(False, True, False)
|
|
1076
|
+
sage: a.is_equal_to(aa, 15)
|
|
1077
|
+
Traceback (most recent call last):
|
|
1078
|
+
...
|
|
1079
|
+
PrecisionError: elements not known to enough precision
|
|
1080
|
+
|
|
1081
|
+
sage: a.is_equal_to(a, 50000)
|
|
1082
|
+
True
|
|
1083
|
+
|
|
1084
|
+
sage: a.is_equal_to(b), a.is_equal_to(b, 2)
|
|
1085
|
+
(True, True)
|
|
1086
|
+
sage: a.is_equal_to(b, 5)
|
|
1087
|
+
Traceback (most recent call last):
|
|
1088
|
+
...
|
|
1089
|
+
PrecisionError: elements not known to enough precision
|
|
1090
|
+
|
|
1091
|
+
sage: b.is_equal_to(b, 5)
|
|
1092
|
+
Traceback (most recent call last):
|
|
1093
|
+
...
|
|
1094
|
+
PrecisionError: elements not known to enough precision
|
|
1095
|
+
|
|
1096
|
+
sage: b.is_equal_to(bb, 3)
|
|
1097
|
+
True
|
|
1098
|
+
sage: b.is_equal_to(bb, 4)
|
|
1099
|
+
Traceback (most recent call last):
|
|
1100
|
+
...
|
|
1101
|
+
PrecisionError: elements not known to enough precision
|
|
1102
|
+
|
|
1103
|
+
sage: c.is_equal_to(b, 2), c.is_equal_to(b, 3)
|
|
1104
|
+
(True, False)
|
|
1105
|
+
sage: c.is_equal_to(b, 4)
|
|
1106
|
+
Traceback (most recent call last):
|
|
1107
|
+
...
|
|
1108
|
+
PrecisionError: elements not known to enough precision
|
|
1109
|
+
|
|
1110
|
+
sage: c.is_equal_to(cc, 2), c.is_equal_to(cc, 4), c.is_equal_to(cc, 5)
|
|
1111
|
+
(True, True, False)
|
|
1112
|
+
|
|
1113
|
+
TESTS::
|
|
1114
|
+
|
|
1115
|
+
sage: aa.is_equal_to(a), aa.is_equal_to(a, 4), aa.is_equal_to(a, 5)
|
|
1116
|
+
(False, True, False)
|
|
1117
|
+
sage: aa.is_equal_to(a, 15)
|
|
1118
|
+
Traceback (most recent call last):
|
|
1119
|
+
...
|
|
1120
|
+
PrecisionError: elements not known to enough precision
|
|
1121
|
+
|
|
1122
|
+
sage: b.is_equal_to(a), b.is_equal_to(a, 2)
|
|
1123
|
+
(True, True)
|
|
1124
|
+
sage: b.is_equal_to(a, 5)
|
|
1125
|
+
Traceback (most recent call last):
|
|
1126
|
+
...
|
|
1127
|
+
PrecisionError: elements not known to enough precision
|
|
1128
|
+
|
|
1129
|
+
sage: bb.is_equal_to(b, 3)
|
|
1130
|
+
True
|
|
1131
|
+
sage: bb.is_equal_to(b, 4)
|
|
1132
|
+
Traceback (most recent call last):
|
|
1133
|
+
...
|
|
1134
|
+
PrecisionError: elements not known to enough precision
|
|
1135
|
+
|
|
1136
|
+
sage: b.is_equal_to(c, 2), b.is_equal_to(c, 3)
|
|
1137
|
+
(True, False)
|
|
1138
|
+
sage: b.is_equal_to(c, 4)
|
|
1139
|
+
Traceback (most recent call last):
|
|
1140
|
+
...
|
|
1141
|
+
PrecisionError: elements not known to enough precision
|
|
1142
|
+
|
|
1143
|
+
sage: cc.is_equal_to(c, 2), cc.is_equal_to(c, 4), cc.is_equal_to(c, 5)
|
|
1144
|
+
(True, True, False)
|
|
1145
|
+
"""
|
|
1146
|
+
cdef CRElement right
|
|
1147
|
+
cdef long aprec, rprec
|
|
1148
|
+
if self.parent() is _right.parent():
|
|
1149
|
+
right = _right
|
|
1150
|
+
else:
|
|
1151
|
+
right = self.parent().coerce(_right)
|
|
1152
|
+
if exactzero(self.ordp) and exactzero(right.ordp):
|
|
1153
|
+
return True
|
|
1154
|
+
elif absprec is infinity:
|
|
1155
|
+
raise PrecisionError("elements not known to enough precision")
|
|
1156
|
+
if absprec is None:
|
|
1157
|
+
aprec = min(self.ordp + self.relprec, right.ordp + right.relprec)
|
|
1158
|
+
else:
|
|
1159
|
+
if not isinstance(absprec, Integer):
|
|
1160
|
+
absprec = Integer(absprec)
|
|
1161
|
+
if mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
1162
|
+
if mpz_sgn((<Integer>absprec).value) < 0 or \
|
|
1163
|
+
exactzero(self.ordp) and exactzero(right.ordp):
|
|
1164
|
+
return True
|
|
1165
|
+
else:
|
|
1166
|
+
raise PrecisionError("elements not known to enough precision")
|
|
1167
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
1168
|
+
if aprec > self.ordp + self.relprec or aprec > right.ordp + right.relprec:
|
|
1169
|
+
raise PrecisionError("elements not known to enough precision")
|
|
1170
|
+
if self.ordp >= aprec and right.ordp >= aprec:
|
|
1171
|
+
return True
|
|
1172
|
+
elif self.ordp != right.ordp:
|
|
1173
|
+
return False
|
|
1174
|
+
rprec = aprec - self.ordp
|
|
1175
|
+
return ccmp(self.unit, right.unit, rprec, rprec < self.relprec, rprec < right.relprec, self.prime_pow) == 0
|
|
1176
|
+
|
|
1177
|
+
cdef int _cmp_units(self, pAdicGenericElement _right) except -2:
|
|
1178
|
+
"""
|
|
1179
|
+
Comparison of units, used in equality testing.
|
|
1180
|
+
|
|
1181
|
+
EXAMPLES::
|
|
1182
|
+
|
|
1183
|
+
sage: R = Zp(5)
|
|
1184
|
+
sage: a = R(17); b = R(0,3); c = R(85,7); d = R(2, 1)
|
|
1185
|
+
sage: any([a == b, a == c, b == c, b == d, c == d])
|
|
1186
|
+
False
|
|
1187
|
+
sage: all([a == a, b == b, c == c, d == d, a == d])
|
|
1188
|
+
True
|
|
1189
|
+
|
|
1190
|
+
sage: sorted([a, b, c, d])
|
|
1191
|
+
[2 + 3*5 + O(5^20), 2 + O(5), 2*5 + 3*5^2 + O(5^7), O(5^3)]
|
|
1192
|
+
"""
|
|
1193
|
+
cdef CRElement right = _right
|
|
1194
|
+
cdef long rprec = min(self.relprec, right.relprec)
|
|
1195
|
+
if rprec == 0:
|
|
1196
|
+
return 0
|
|
1197
|
+
return ccmp(self.unit, right.unit, rprec, rprec < self.relprec, rprec < right.relprec, self.prime_pow)
|
|
1198
|
+
|
|
1199
|
+
cdef pAdicTemplateElement lift_to_precision_c(self, long absprec):
|
|
1200
|
+
"""
|
|
1201
|
+
Lifts this element to another with precision at least ``absprec``.
|
|
1202
|
+
|
|
1203
|
+
TESTS::
|
|
1204
|
+
|
|
1205
|
+
sage: R = Zp(5); a = R(0); b = R(0,5); c = R(17,3)
|
|
1206
|
+
sage: a.lift_to_precision(5)
|
|
1207
|
+
0
|
|
1208
|
+
sage: b.lift_to_precision(4)
|
|
1209
|
+
O(5^5)
|
|
1210
|
+
sage: b.lift_to_precision(8)
|
|
1211
|
+
O(5^8)
|
|
1212
|
+
sage: b.lift_to_precision(40)
|
|
1213
|
+
O(5^40)
|
|
1214
|
+
sage: c.lift_to_precision(1)
|
|
1215
|
+
2 + 3*5 + O(5^3)
|
|
1216
|
+
sage: c.lift_to_precision(8)
|
|
1217
|
+
2 + 3*5 + O(5^8)
|
|
1218
|
+
sage: c.lift_to_precision(40)
|
|
1219
|
+
Traceback (most recent call last):
|
|
1220
|
+
...
|
|
1221
|
+
PrecisionError: precision higher than allowed by the precision cap
|
|
1222
|
+
"""
|
|
1223
|
+
cdef CRElement ans
|
|
1224
|
+
if absprec == maxordp:
|
|
1225
|
+
if self.relprec == 0:
|
|
1226
|
+
ans = self._new_c()
|
|
1227
|
+
ans._set_exact_zero()
|
|
1228
|
+
return ans
|
|
1229
|
+
else:
|
|
1230
|
+
absprec = self.ordp + self.prime_pow.ram_prec_cap
|
|
1231
|
+
cdef long relprec = absprec - self.ordp
|
|
1232
|
+
if relprec <= self.relprec:
|
|
1233
|
+
return self
|
|
1234
|
+
ans = self._new_c()
|
|
1235
|
+
if self.relprec == 0:
|
|
1236
|
+
ans._set_inexact_zero(absprec)
|
|
1237
|
+
else:
|
|
1238
|
+
ans.ordp = self.ordp
|
|
1239
|
+
ans.relprec = relprec
|
|
1240
|
+
ccopy(ans.unit, self.unit, ans.prime_pow)
|
|
1241
|
+
return ans
|
|
1242
|
+
|
|
1243
|
+
def _cache_key(self):
|
|
1244
|
+
r"""
|
|
1245
|
+
Return a hashable key which identifies this element for caching.
|
|
1246
|
+
|
|
1247
|
+
TESTS::
|
|
1248
|
+
|
|
1249
|
+
sage: # needs sage.libs.ntl
|
|
1250
|
+
sage: K.<a> = Qq(9)
|
|
1251
|
+
sage: (9*a)._cache_key()
|
|
1252
|
+
(..., ((0, 1),), 2, 20)
|
|
1253
|
+
|
|
1254
|
+
.. SEEALSO::
|
|
1255
|
+
|
|
1256
|
+
:meth:`sage.misc.cachefunc._cache_key`
|
|
1257
|
+
"""
|
|
1258
|
+
def tuple_recursive(l):
|
|
1259
|
+
return tuple(tuple_recursive(x) for x in l) if isinstance(l, list) else l
|
|
1260
|
+
|
|
1261
|
+
return (self.parent(), tuple_recursive(trim_zeros(list(self.expansion()))), self.valuation(), self.precision_relative())
|
|
1262
|
+
|
|
1263
|
+
def _teichmuller_set_unsafe(self):
|
|
1264
|
+
"""
|
|
1265
|
+
Set this element to the Teichmuller representative with the
|
|
1266
|
+
same residue.
|
|
1267
|
+
|
|
1268
|
+
.. WARNING::
|
|
1269
|
+
|
|
1270
|
+
This function modifies the element, which is not safe.
|
|
1271
|
+
Elements are supposed to be immutable.
|
|
1272
|
+
|
|
1273
|
+
EXAMPLES::
|
|
1274
|
+
|
|
1275
|
+
sage: R = Zp(17,5); a = R(11)
|
|
1276
|
+
sage: a
|
|
1277
|
+
11 + O(17^5)
|
|
1278
|
+
sage: a._teichmuller_set_unsafe(); a
|
|
1279
|
+
11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4 + O(17^5)
|
|
1280
|
+
sage: E = a.expansion(lift_mode='teichmuller'); E
|
|
1281
|
+
17-adic expansion of 11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4 + O(17^5) (teichmuller)
|
|
1282
|
+
sage: list(E)
|
|
1283
|
+
[11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4 + O(17^5), 0, 0, 0, 0]
|
|
1284
|
+
|
|
1285
|
+
Note that if you set an element which is congruent to 0 you
|
|
1286
|
+
get an exact 0.
|
|
1287
|
+
|
|
1288
|
+
sage: b = R(17*5); b
|
|
1289
|
+
5*17 + O(17^6)
|
|
1290
|
+
sage: b._teichmuller_set_unsafe(); b
|
|
1291
|
+
0
|
|
1292
|
+
"""
|
|
1293
|
+
if self.ordp > 0:
|
|
1294
|
+
self._set_exact_zero()
|
|
1295
|
+
elif self.ordp < 0:
|
|
1296
|
+
raise ValueError("cannot set negative valuation element to Teichmuller representative")
|
|
1297
|
+
elif self.relprec == 0:
|
|
1298
|
+
raise ValueError("not enough precision")
|
|
1299
|
+
else:
|
|
1300
|
+
cteichmuller(self.unit, self.unit, self.relprec, self.prime_pow)
|
|
1301
|
+
|
|
1302
|
+
def _polynomial_list(self, pad=False):
|
|
1303
|
+
"""
|
|
1304
|
+
Return the coefficient list for a polynomial over the base ring
|
|
1305
|
+
yielding this element.
|
|
1306
|
+
|
|
1307
|
+
INPUT:
|
|
1308
|
+
|
|
1309
|
+
- ``pad`` -- whether to pad the result with zeros of the appropriate precision
|
|
1310
|
+
|
|
1311
|
+
EXAMPLES::
|
|
1312
|
+
|
|
1313
|
+
sage: # needs sage.libs.ntl
|
|
1314
|
+
sage: R.<x> = ZZ[]
|
|
1315
|
+
sage: K.<a> = Qq(25)
|
|
1316
|
+
sage: W.<w> = K.extension(x^3 - 5)
|
|
1317
|
+
sage: (1 + w + O(w^11))._polynomial_list()
|
|
1318
|
+
[1 + O(5^4), 1 + O(5^4)]
|
|
1319
|
+
sage: (1 + w + O(w^11))._polynomial_list(pad=True)
|
|
1320
|
+
[1 + O(5^4), 1 + O(5^4), O(5^3)]
|
|
1321
|
+
sage: W(0)._polynomial_list()
|
|
1322
|
+
[]
|
|
1323
|
+
sage: W(0)._polynomial_list(pad=True)
|
|
1324
|
+
[0, 0, 0]
|
|
1325
|
+
sage: W(O(w^7))._polynomial_list()
|
|
1326
|
+
[]
|
|
1327
|
+
sage: W(O(w^7))._polynomial_list(pad=True)
|
|
1328
|
+
[O(5^3), O(5^2), O(5^2)]
|
|
1329
|
+
"""
|
|
1330
|
+
R = self.base_ring()
|
|
1331
|
+
if exactzero(self.ordp):
|
|
1332
|
+
L = []
|
|
1333
|
+
else:
|
|
1334
|
+
L = ccoefficients(self.unit, self.ordp, self.relprec, self.prime_pow)
|
|
1335
|
+
if pad:
|
|
1336
|
+
n = self.parent().relative_degree()
|
|
1337
|
+
L.extend([R.zero()] * (n - len(L)))
|
|
1338
|
+
if exactzero(self.ordp):
|
|
1339
|
+
return L
|
|
1340
|
+
e = self.parent().relative_e()
|
|
1341
|
+
prec = self.precision_absolute()
|
|
1342
|
+
if e == 1:
|
|
1343
|
+
return [R(c, prec) for c in L]
|
|
1344
|
+
else:
|
|
1345
|
+
return [R(c, (prec - i - 1) // e + 1) for i, c in enumerate(L)]
|
|
1346
|
+
|
|
1347
|
+
def polynomial(self, var='x'):
|
|
1348
|
+
"""
|
|
1349
|
+
Return a polynomial over the base ring that yields this element
|
|
1350
|
+
when evaluated at the generator of the parent.
|
|
1351
|
+
|
|
1352
|
+
INPUT:
|
|
1353
|
+
|
|
1354
|
+
- ``var`` -- string, the variable name for the polynomial
|
|
1355
|
+
|
|
1356
|
+
EXAMPLES::
|
|
1357
|
+
|
|
1358
|
+
sage: # needs sage.libs.ntl
|
|
1359
|
+
sage: K.<a> = Qq(5^3)
|
|
1360
|
+
sage: a.polynomial()
|
|
1361
|
+
(1 + O(5^20))*x + O(5^20)
|
|
1362
|
+
sage: a.polynomial(var='y')
|
|
1363
|
+
(1 + O(5^20))*y + O(5^20)
|
|
1364
|
+
sage: (5*a^2 + K(25, 4)).polynomial()
|
|
1365
|
+
(5 + O(5^4))*x^2 + O(5^4)*x + 5^2 + O(5^4)
|
|
1366
|
+
"""
|
|
1367
|
+
R = self.base_ring()
|
|
1368
|
+
S = R[var]
|
|
1369
|
+
return self.base_ring()[var](self._polynomial_list())
|
|
1370
|
+
|
|
1371
|
+
def precision_absolute(self):
|
|
1372
|
+
"""
|
|
1373
|
+
Return the absolute precision of this element.
|
|
1374
|
+
|
|
1375
|
+
This is the power of the maximal ideal modulo which this
|
|
1376
|
+
element is defined.
|
|
1377
|
+
|
|
1378
|
+
EXAMPLES::
|
|
1379
|
+
|
|
1380
|
+
sage: R = Zp(7,3,'capped-rel'); a = R(7); a.precision_absolute()
|
|
1381
|
+
4
|
|
1382
|
+
sage: R = Qp(7,3); a = R(7); a.precision_absolute()
|
|
1383
|
+
4
|
|
1384
|
+
sage: R(7^-3).precision_absolute()
|
|
1385
|
+
0
|
|
1386
|
+
|
|
1387
|
+
sage: R(0).precision_absolute()
|
|
1388
|
+
+Infinity
|
|
1389
|
+
sage: R(0,7).precision_absolute()
|
|
1390
|
+
7
|
|
1391
|
+
"""
|
|
1392
|
+
if exactzero(self.ordp):
|
|
1393
|
+
return infinity
|
|
1394
|
+
cdef Integer ans = Integer.__new__(Integer)
|
|
1395
|
+
mpz_set_si(ans.value, self.ordp + self.relprec)
|
|
1396
|
+
return ans
|
|
1397
|
+
|
|
1398
|
+
def precision_relative(self):
|
|
1399
|
+
"""
|
|
1400
|
+
Return the relative precision of this element.
|
|
1401
|
+
|
|
1402
|
+
This is the power of the maximal ideal modulo which the unit
|
|
1403
|
+
part of ``self`` is defined.
|
|
1404
|
+
|
|
1405
|
+
EXAMPLES::
|
|
1406
|
+
|
|
1407
|
+
sage: R = Zp(7,3,'capped-rel'); a = R(7); a.precision_relative()
|
|
1408
|
+
3
|
|
1409
|
+
sage: R = Qp(7,3); a = R(7); a.precision_relative()
|
|
1410
|
+
3
|
|
1411
|
+
sage: a = R(7^-2, -1); a.precision_relative()
|
|
1412
|
+
1
|
|
1413
|
+
sage: a
|
|
1414
|
+
7^-2 + O(7^-1)
|
|
1415
|
+
|
|
1416
|
+
sage: R(0).precision_relative()
|
|
1417
|
+
0
|
|
1418
|
+
sage: R(0,7).precision_relative()
|
|
1419
|
+
0
|
|
1420
|
+
"""
|
|
1421
|
+
cdef Integer ans = Integer.__new__(Integer)
|
|
1422
|
+
mpz_set_si(ans.value, self.relprec)
|
|
1423
|
+
return ans
|
|
1424
|
+
|
|
1425
|
+
cpdef pAdicTemplateElement unit_part(self):
|
|
1426
|
+
r"""
|
|
1427
|
+
Return `u`, where this element is `\pi^v u`.
|
|
1428
|
+
|
|
1429
|
+
EXAMPLES::
|
|
1430
|
+
|
|
1431
|
+
sage: R = Zp(17,4,'capped-rel')
|
|
1432
|
+
sage: a = R(18*17)
|
|
1433
|
+
sage: a.unit_part()
|
|
1434
|
+
1 + 17 + O(17^4)
|
|
1435
|
+
sage: type(a)
|
|
1436
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'>
|
|
1437
|
+
sage: R = Qp(17,4,'capped-rel')
|
|
1438
|
+
sage: a = R(18*17)
|
|
1439
|
+
sage: a.unit_part()
|
|
1440
|
+
1 + 17 + O(17^4)
|
|
1441
|
+
sage: type(a)
|
|
1442
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'>
|
|
1443
|
+
sage: a = R(2*17^2); a
|
|
1444
|
+
2*17^2 + O(17^6)
|
|
1445
|
+
sage: a.unit_part()
|
|
1446
|
+
2 + O(17^4)
|
|
1447
|
+
sage: b=1/a; b
|
|
1448
|
+
9*17^-2 + 8*17^-1 + 8 + 8*17 + O(17^2)
|
|
1449
|
+
sage: b.unit_part()
|
|
1450
|
+
9 + 8*17 + 8*17^2 + 8*17^3 + O(17^4)
|
|
1451
|
+
sage: Zp(5)(75).unit_part()
|
|
1452
|
+
3 + O(5^20)
|
|
1453
|
+
|
|
1454
|
+
sage: R(0).unit_part()
|
|
1455
|
+
Traceback (most recent call last):
|
|
1456
|
+
...
|
|
1457
|
+
ValueError: unit part of 0 not defined
|
|
1458
|
+
sage: R(0,7).unit_part()
|
|
1459
|
+
O(17^0)
|
|
1460
|
+
"""
|
|
1461
|
+
if exactzero(self.ordp):
|
|
1462
|
+
raise ValueError("unit part of 0 not defined")
|
|
1463
|
+
cdef CRElement ans = (<CRElement>self)._new_c()
|
|
1464
|
+
ans.ordp = 0
|
|
1465
|
+
ans.relprec = (<CRElement>self).relprec
|
|
1466
|
+
ccopy(ans.unit, (<CRElement>self).unit, ans.prime_pow)
|
|
1467
|
+
return ans
|
|
1468
|
+
|
|
1469
|
+
cdef long valuation_c(self) noexcept:
|
|
1470
|
+
"""
|
|
1471
|
+
Return the valuation of this element.
|
|
1472
|
+
|
|
1473
|
+
If ``self`` is an exact zero, returns ``maxordp``, which is defined as
|
|
1474
|
+
``(1L << (sizeof(long) * 8 - 2))-1``.
|
|
1475
|
+
|
|
1476
|
+
EXAMPLES::
|
|
1477
|
+
|
|
1478
|
+
sage: R = Qp(5); a = R(1)
|
|
1479
|
+
sage: a.valuation() # indirect doctest
|
|
1480
|
+
0
|
|
1481
|
+
sage: b = (a << 4); b.valuation()
|
|
1482
|
+
4
|
|
1483
|
+
sage: b = (a << 1073741822); b.valuation()
|
|
1484
|
+
1073741822
|
|
1485
|
+
"""
|
|
1486
|
+
return self.ordp
|
|
1487
|
+
|
|
1488
|
+
cpdef val_unit(self, p=None):
|
|
1489
|
+
"""
|
|
1490
|
+
Return a pair ``(self.valuation(), self.unit_part())``.
|
|
1491
|
+
|
|
1492
|
+
INPUT:
|
|
1493
|
+
|
|
1494
|
+
- ``p`` -- a prime (default: ``None``); if specified, will make sure
|
|
1495
|
+
that ``p == self.parent().prime()``
|
|
1496
|
+
|
|
1497
|
+
.. NOTE::
|
|
1498
|
+
|
|
1499
|
+
The optional argument ``p`` is used for consistency with the
|
|
1500
|
+
valuation methods on integers and rationals.
|
|
1501
|
+
|
|
1502
|
+
EXAMPLES::
|
|
1503
|
+
|
|
1504
|
+
sage: R = Zp(5); a = R(75, 20); a
|
|
1505
|
+
3*5^2 + O(5^20)
|
|
1506
|
+
sage: a.val_unit()
|
|
1507
|
+
(2, 3 + O(5^18))
|
|
1508
|
+
sage: R(0).val_unit()
|
|
1509
|
+
Traceback (most recent call last):
|
|
1510
|
+
...
|
|
1511
|
+
ValueError: unit part of 0 not defined
|
|
1512
|
+
sage: R(0, 10).val_unit()
|
|
1513
|
+
(10, O(5^0))
|
|
1514
|
+
"""
|
|
1515
|
+
# Since we keep this element normalized there's not much to do here.
|
|
1516
|
+
if p is not None and p != self.parent().prime():
|
|
1517
|
+
raise ValueError('ring (%s) residue field of the wrong characteristic' % self.parent())
|
|
1518
|
+
if exactzero((<CRElement>self).ordp):
|
|
1519
|
+
raise ValueError("unit part of 0 not defined")
|
|
1520
|
+
cdef Integer val = Integer.__new__(Integer)
|
|
1521
|
+
mpz_set_si(val.value, (<CRElement>self).ordp)
|
|
1522
|
+
cdef CRElement unit = (<CRElement>self)._new_c()
|
|
1523
|
+
unit.ordp = 0
|
|
1524
|
+
unit.relprec = (<CRElement>self).relprec
|
|
1525
|
+
ccopy(unit.unit, (<CRElement>self).unit, unit.prime_pow)
|
|
1526
|
+
return val, unit
|
|
1527
|
+
|
|
1528
|
+
def __hash__(self):
|
|
1529
|
+
"""
|
|
1530
|
+
Hashing.
|
|
1531
|
+
|
|
1532
|
+
.. WARNING::
|
|
1533
|
+
|
|
1534
|
+
Hashing of `p`-adic elements will likely be deprecated soon. See :issue:`11895`.
|
|
1535
|
+
|
|
1536
|
+
EXAMPLES::
|
|
1537
|
+
|
|
1538
|
+
sage: R = Zp(5)
|
|
1539
|
+
sage: hash(R(17)) # indirect doctest
|
|
1540
|
+
17
|
|
1541
|
+
|
|
1542
|
+
sage: hash(R(-1))
|
|
1543
|
+
1977844648 # 32-bit
|
|
1544
|
+
95367431640624 # 64-bit
|
|
1545
|
+
"""
|
|
1546
|
+
if exactzero(self.ordp):
|
|
1547
|
+
return 0
|
|
1548
|
+
return chash(self.unit, self.ordp, self.relprec, self.prime_pow) ^ self.ordp
|
|
1549
|
+
|
|
1550
|
+
cdef class pAdicCoercion_ZZ_CR(RingHomomorphism):
|
|
1551
|
+
"""
|
|
1552
|
+
The canonical inclusion from the integer ring to a capped relative ring.
|
|
1553
|
+
|
|
1554
|
+
EXAMPLES::
|
|
1555
|
+
|
|
1556
|
+
sage: f = Zp(5).coerce_map_from(ZZ); f
|
|
1557
|
+
Ring morphism:
|
|
1558
|
+
From: Integer Ring
|
|
1559
|
+
To: 5-adic Ring with capped relative precision 20
|
|
1560
|
+
|
|
1561
|
+
TESTS::
|
|
1562
|
+
|
|
1563
|
+
sage: TestSuite(f).run()
|
|
1564
|
+
"""
|
|
1565
|
+
def __init__(self, R):
|
|
1566
|
+
"""
|
|
1567
|
+
Initialization.
|
|
1568
|
+
|
|
1569
|
+
EXAMPLES::
|
|
1570
|
+
|
|
1571
|
+
sage: f = Zp(5).coerce_map_from(ZZ); type(f)
|
|
1572
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCoercion_ZZ_CR'>
|
|
1573
|
+
"""
|
|
1574
|
+
RingHomomorphism.__init__(self, ZZ.Hom(R))
|
|
1575
|
+
self._zero = R.element_class(R, 0)
|
|
1576
|
+
self._section = pAdicConvert_CR_ZZ(R)
|
|
1577
|
+
|
|
1578
|
+
cdef dict _extra_slots(self):
|
|
1579
|
+
"""
|
|
1580
|
+
Helper for copying and pickling.
|
|
1581
|
+
|
|
1582
|
+
EXAMPLES::
|
|
1583
|
+
|
|
1584
|
+
sage: f = Zp(5).coerce_map_from(ZZ)
|
|
1585
|
+
sage: g = copy(f) # indirect doctest
|
|
1586
|
+
sage: g
|
|
1587
|
+
Ring morphism:
|
|
1588
|
+
From: Integer Ring
|
|
1589
|
+
To: 5-adic Ring with capped relative precision 20
|
|
1590
|
+
sage: g == f
|
|
1591
|
+
True
|
|
1592
|
+
sage: g is f
|
|
1593
|
+
False
|
|
1594
|
+
sage: g(5)
|
|
1595
|
+
5 + O(5^21)
|
|
1596
|
+
sage: g(5) == f(5)
|
|
1597
|
+
True
|
|
1598
|
+
"""
|
|
1599
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
1600
|
+
_slots['_zero'] = self._zero
|
|
1601
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
1602
|
+
return _slots
|
|
1603
|
+
|
|
1604
|
+
cdef _update_slots(self, dict _slots):
|
|
1605
|
+
"""
|
|
1606
|
+
Helper for copying and pickling.
|
|
1607
|
+
|
|
1608
|
+
EXAMPLES::
|
|
1609
|
+
|
|
1610
|
+
sage: f = Zp(5).coerce_map_from(ZZ)
|
|
1611
|
+
sage: g = copy(f) # indirect doctest
|
|
1612
|
+
sage: g
|
|
1613
|
+
Ring morphism:
|
|
1614
|
+
From: Integer Ring
|
|
1615
|
+
To: 5-adic Ring with capped relative precision 20
|
|
1616
|
+
sage: g == f
|
|
1617
|
+
True
|
|
1618
|
+
sage: g is f
|
|
1619
|
+
False
|
|
1620
|
+
sage: g(5)
|
|
1621
|
+
5 + O(5^21)
|
|
1622
|
+
sage: g(5) == f(5)
|
|
1623
|
+
True
|
|
1624
|
+
"""
|
|
1625
|
+
self._zero = _slots['_zero']
|
|
1626
|
+
self._section = _slots['_section']
|
|
1627
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
1628
|
+
|
|
1629
|
+
cpdef Element _call_(self, x):
|
|
1630
|
+
"""
|
|
1631
|
+
Evaluation.
|
|
1632
|
+
|
|
1633
|
+
EXAMPLES::
|
|
1634
|
+
|
|
1635
|
+
sage: f = Zp(5).coerce_map_from(ZZ)
|
|
1636
|
+
sage: f(0).parent()
|
|
1637
|
+
5-adic Ring with capped relative precision 20
|
|
1638
|
+
sage: f(5)
|
|
1639
|
+
5 + O(5^21)
|
|
1640
|
+
"""
|
|
1641
|
+
if mpz_sgn((<Integer>x).value) == 0:
|
|
1642
|
+
return self._zero
|
|
1643
|
+
cdef CRElement ans = self._zero._new_c()
|
|
1644
|
+
ans.relprec = ans.prime_pow.ram_prec_cap
|
|
1645
|
+
ans.ordp = cconv_mpz_t(ans.unit, (<Integer>x).value, ans.relprec, False, ans.prime_pow)
|
|
1646
|
+
return ans
|
|
1647
|
+
|
|
1648
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
1649
|
+
"""
|
|
1650
|
+
This function is used when some precision cap is passed in
|
|
1651
|
+
(relative or absolute or both), or an empty element is
|
|
1652
|
+
desired.
|
|
1653
|
+
|
|
1654
|
+
See the documentation for
|
|
1655
|
+
:meth:`pAdicCappedRelativeElement.__init__` for more details.
|
|
1656
|
+
|
|
1657
|
+
EXAMPLES::
|
|
1658
|
+
|
|
1659
|
+
sage: R = Zp(5,4)
|
|
1660
|
+
sage: type(R(10,2))
|
|
1661
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'>
|
|
1662
|
+
sage: R(10,2) # indirect doctest
|
|
1663
|
+
2*5 + O(5^2)
|
|
1664
|
+
sage: R(10,3,1)
|
|
1665
|
+
2*5 + O(5^2)
|
|
1666
|
+
sage: R(10,absprec=2)
|
|
1667
|
+
2*5 + O(5^2)
|
|
1668
|
+
sage: R(10,relprec=2)
|
|
1669
|
+
2*5 + O(5^3)
|
|
1670
|
+
sage: R(10,absprec=1)
|
|
1671
|
+
O(5)
|
|
1672
|
+
sage: R(10,empty=True)
|
|
1673
|
+
O(5^0)
|
|
1674
|
+
"""
|
|
1675
|
+
cdef long val, aprec, rprec
|
|
1676
|
+
cdef CRElement ans
|
|
1677
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, self._zero.prime_pow)
|
|
1678
|
+
if mpz_sgn((<Integer>x).value) == 0:
|
|
1679
|
+
if exactzero(aprec):
|
|
1680
|
+
return self._zero
|
|
1681
|
+
ans = self._zero._new_c()
|
|
1682
|
+
ans._set_inexact_zero(aprec)
|
|
1683
|
+
else:
|
|
1684
|
+
val = get_ordp(x, self._zero.prime_pow)
|
|
1685
|
+
ans = self._zero._new_c()
|
|
1686
|
+
if aprec <= val:
|
|
1687
|
+
ans._set_inexact_zero(aprec)
|
|
1688
|
+
else:
|
|
1689
|
+
ans.relprec = min(rprec, aprec - val)
|
|
1690
|
+
ans.ordp = cconv_mpz_t(ans.unit, (<Integer>x).value, ans.relprec, False, self._zero.prime_pow)
|
|
1691
|
+
return ans
|
|
1692
|
+
|
|
1693
|
+
def section(self):
|
|
1694
|
+
"""
|
|
1695
|
+
Return a map back to the ring of integers that approximates an element
|
|
1696
|
+
by an integer.
|
|
1697
|
+
|
|
1698
|
+
EXAMPLES::
|
|
1699
|
+
|
|
1700
|
+
sage: f = Zp(5).coerce_map_from(ZZ).section()
|
|
1701
|
+
sage: f(Zp(5)(-1)) - 5^20
|
|
1702
|
+
-1
|
|
1703
|
+
"""
|
|
1704
|
+
from sage.misc.constant_function import ConstantFunction
|
|
1705
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
1706
|
+
import copy
|
|
1707
|
+
self._section = copy.copy(self._section)
|
|
1708
|
+
return self._section
|
|
1709
|
+
|
|
1710
|
+
cdef class pAdicConvert_CR_ZZ(RingMap):
|
|
1711
|
+
"""
|
|
1712
|
+
The map from a capped relative ring back to the ring of integers that
|
|
1713
|
+
returns the smallest nonnegative integer approximation to its input
|
|
1714
|
+
which is accurate up to the precision.
|
|
1715
|
+
|
|
1716
|
+
Raises a :exc:`ValueError`, if the input is not in the closure of the image of
|
|
1717
|
+
the integers.
|
|
1718
|
+
|
|
1719
|
+
EXAMPLES::
|
|
1720
|
+
|
|
1721
|
+
sage: f = Zp(5).coerce_map_from(ZZ).section(); f
|
|
1722
|
+
Set-theoretic ring morphism:
|
|
1723
|
+
From: 5-adic Ring with capped relative precision 20
|
|
1724
|
+
To: Integer Ring
|
|
1725
|
+
"""
|
|
1726
|
+
def __init__(self, R):
|
|
1727
|
+
"""
|
|
1728
|
+
Initialization.
|
|
1729
|
+
|
|
1730
|
+
EXAMPLES::
|
|
1731
|
+
|
|
1732
|
+
sage: f = Qp(5).coerce_map_from(ZZ).section(); type(f)
|
|
1733
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicConvert_CR_ZZ'>
|
|
1734
|
+
sage: f.category()
|
|
1735
|
+
Category of homsets of sets with partial maps
|
|
1736
|
+
sage: Zp(5).coerce_map_from(ZZ).section().category()
|
|
1737
|
+
Category of homsets of sets
|
|
1738
|
+
"""
|
|
1739
|
+
if R.is_field() or R.absolute_degree() > 1 or R.characteristic() != 0 or R.residue_characteristic() == 0:
|
|
1740
|
+
RingMap.__init__(self, Hom(R, ZZ, SetsWithPartialMaps()))
|
|
1741
|
+
else:
|
|
1742
|
+
RingMap.__init__(self, Hom(R, ZZ, Sets()))
|
|
1743
|
+
|
|
1744
|
+
cpdef Element _call_(self, _x):
|
|
1745
|
+
"""
|
|
1746
|
+
Evaluation.
|
|
1747
|
+
|
|
1748
|
+
EXAMPLES::
|
|
1749
|
+
|
|
1750
|
+
sage: f = Qp(5).coerce_map_from(ZZ).section()
|
|
1751
|
+
sage: f(Qp(5)(-1)) - 5^20
|
|
1752
|
+
-1
|
|
1753
|
+
sage: f(Qp(5)(0))
|
|
1754
|
+
0
|
|
1755
|
+
sage: f(Qp(5)(1/5))
|
|
1756
|
+
Traceback (most recent call last):
|
|
1757
|
+
...
|
|
1758
|
+
ValueError: negative valuation
|
|
1759
|
+
"""
|
|
1760
|
+
cdef Integer ans = Integer.__new__(Integer)
|
|
1761
|
+
cdef CRElement x = _x
|
|
1762
|
+
if x.relprec != 0:
|
|
1763
|
+
cconv_mpz_t_out(ans.value, x.unit, x.ordp, x.relprec, x.prime_pow)
|
|
1764
|
+
return ans
|
|
1765
|
+
|
|
1766
|
+
cdef class pAdicCoercion_QQ_CR(RingHomomorphism):
|
|
1767
|
+
"""
|
|
1768
|
+
The canonical inclusion from the rationals to a capped relative field.
|
|
1769
|
+
|
|
1770
|
+
EXAMPLES::
|
|
1771
|
+
|
|
1772
|
+
sage: f = Qp(5).coerce_map_from(QQ); f
|
|
1773
|
+
Ring morphism:
|
|
1774
|
+
From: Rational Field
|
|
1775
|
+
To: 5-adic Field with capped relative precision 20
|
|
1776
|
+
|
|
1777
|
+
TESTS::
|
|
1778
|
+
|
|
1779
|
+
sage: TestSuite(f).run()
|
|
1780
|
+
"""
|
|
1781
|
+
def __init__(self, R):
|
|
1782
|
+
"""
|
|
1783
|
+
Initialization.
|
|
1784
|
+
|
|
1785
|
+
EXAMPLES::
|
|
1786
|
+
|
|
1787
|
+
sage: f = Qp(5).coerce_map_from(QQ); type(f)
|
|
1788
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCoercion_QQ_CR'>
|
|
1789
|
+
"""
|
|
1790
|
+
RingHomomorphism.__init__(self, QQ.Hom(R))
|
|
1791
|
+
self._zero = R.element_class(R, 0)
|
|
1792
|
+
self._section = pAdicConvert_CR_QQ(R)
|
|
1793
|
+
|
|
1794
|
+
cdef dict _extra_slots(self):
|
|
1795
|
+
"""
|
|
1796
|
+
Helper for copying and pickling.
|
|
1797
|
+
|
|
1798
|
+
EXAMPLES::
|
|
1799
|
+
|
|
1800
|
+
sage: f = Qp(5).coerce_map_from(QQ)
|
|
1801
|
+
sage: g = copy(f) # indirect doctest
|
|
1802
|
+
sage: g
|
|
1803
|
+
Ring morphism:
|
|
1804
|
+
From: Rational Field
|
|
1805
|
+
To: 5-adic Field with capped relative precision 20
|
|
1806
|
+
sage: g == f
|
|
1807
|
+
True
|
|
1808
|
+
sage: g is f
|
|
1809
|
+
False
|
|
1810
|
+
sage: g(6)
|
|
1811
|
+
1 + 5 + O(5^20)
|
|
1812
|
+
sage: g(6) == f(6)
|
|
1813
|
+
True
|
|
1814
|
+
"""
|
|
1815
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
1816
|
+
_slots['_zero'] = self._zero
|
|
1817
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
1818
|
+
return _slots
|
|
1819
|
+
|
|
1820
|
+
cdef _update_slots(self, dict _slots):
|
|
1821
|
+
"""
|
|
1822
|
+
Helper for copying and pickling.
|
|
1823
|
+
|
|
1824
|
+
EXAMPLES::
|
|
1825
|
+
|
|
1826
|
+
sage: f = Qp(5).coerce_map_from(QQ)
|
|
1827
|
+
sage: g = copy(f) # indirect doctest
|
|
1828
|
+
sage: g
|
|
1829
|
+
Ring morphism:
|
|
1830
|
+
From: Rational Field
|
|
1831
|
+
To: 5-adic Field with capped relative precision 20
|
|
1832
|
+
sage: g == f
|
|
1833
|
+
True
|
|
1834
|
+
sage: g is f
|
|
1835
|
+
False
|
|
1836
|
+
sage: g(6)
|
|
1837
|
+
1 + 5 + O(5^20)
|
|
1838
|
+
sage: g(6) == f(6)
|
|
1839
|
+
True
|
|
1840
|
+
"""
|
|
1841
|
+
self._zero = _slots['_zero']
|
|
1842
|
+
self._section = _slots['_section']
|
|
1843
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
1844
|
+
|
|
1845
|
+
cpdef Element _call_(self, x):
|
|
1846
|
+
"""
|
|
1847
|
+
Evaluation.
|
|
1848
|
+
|
|
1849
|
+
EXAMPLES::
|
|
1850
|
+
|
|
1851
|
+
sage: f = Qp(5).coerce_map_from(QQ)
|
|
1852
|
+
sage: f(0).parent()
|
|
1853
|
+
5-adic Field with capped relative precision 20
|
|
1854
|
+
sage: f(1/5)
|
|
1855
|
+
5^-1 + O(5^19)
|
|
1856
|
+
sage: f(1/4)
|
|
1857
|
+
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 + O(5^20)
|
|
1858
|
+
"""
|
|
1859
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1860
|
+
return self._zero
|
|
1861
|
+
cdef CRElement ans = self._zero._new_c()
|
|
1862
|
+
ans.relprec = ans.prime_pow.ram_prec_cap
|
|
1863
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.relprec, False, self._zero.prime_pow)
|
|
1864
|
+
return ans
|
|
1865
|
+
|
|
1866
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
1867
|
+
"""
|
|
1868
|
+
This function is used when some precision cap is passed in
|
|
1869
|
+
(relative or absolute or both), or an empty element is
|
|
1870
|
+
desired.
|
|
1871
|
+
|
|
1872
|
+
See the documentation for
|
|
1873
|
+
:meth:`pAdicCappedRelativeElement.__init__` for more details.
|
|
1874
|
+
|
|
1875
|
+
EXAMPLES::
|
|
1876
|
+
|
|
1877
|
+
sage: R = Qp(5,4)
|
|
1878
|
+
sage: type(R(10/3,2))
|
|
1879
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'>
|
|
1880
|
+
sage: R(10/3,2) # indirect doctest
|
|
1881
|
+
4*5 + O(5^2)
|
|
1882
|
+
sage: R(10/3,3,1)
|
|
1883
|
+
4*5 + O(5^2)
|
|
1884
|
+
sage: R(10/3,absprec=2)
|
|
1885
|
+
4*5 + O(5^2)
|
|
1886
|
+
sage: R(10/3,relprec=2)
|
|
1887
|
+
4*5 + 5^2 + O(5^3)
|
|
1888
|
+
sage: R(10/3,absprec=1)
|
|
1889
|
+
O(5)
|
|
1890
|
+
sage: R(10/3,empty=True)
|
|
1891
|
+
O(5^0)
|
|
1892
|
+
sage: R(3/100,absprec=-1)
|
|
1893
|
+
2*5^-2 + O(5^-1)
|
|
1894
|
+
"""
|
|
1895
|
+
cdef long val, aprec, rprec
|
|
1896
|
+
cdef CRElement ans
|
|
1897
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, self._zero.prime_pow)
|
|
1898
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1899
|
+
if exactzero(aprec):
|
|
1900
|
+
return self._zero
|
|
1901
|
+
ans = self._zero._new_c()
|
|
1902
|
+
ans._set_inexact_zero(aprec)
|
|
1903
|
+
else:
|
|
1904
|
+
val = get_ordp(x, self._zero.prime_pow)
|
|
1905
|
+
ans = self._zero._new_c()
|
|
1906
|
+
if aprec <= val:
|
|
1907
|
+
ans._set_inexact_zero(aprec)
|
|
1908
|
+
else:
|
|
1909
|
+
ans.relprec = min(rprec, aprec - val)
|
|
1910
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.relprec, False, self._zero.prime_pow)
|
|
1911
|
+
return ans
|
|
1912
|
+
|
|
1913
|
+
def section(self):
|
|
1914
|
+
"""
|
|
1915
|
+
Return a map back to the rationals that approximates an element by
|
|
1916
|
+
a rational number.
|
|
1917
|
+
|
|
1918
|
+
EXAMPLES::
|
|
1919
|
+
|
|
1920
|
+
sage: f = Qp(5).coerce_map_from(QQ).section()
|
|
1921
|
+
sage: f(Qp(5)(1/4))
|
|
1922
|
+
1/4
|
|
1923
|
+
sage: f(Qp(5)(1/5))
|
|
1924
|
+
1/5
|
|
1925
|
+
"""
|
|
1926
|
+
from sage.misc.constant_function import ConstantFunction
|
|
1927
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
1928
|
+
import copy
|
|
1929
|
+
self._section = copy.copy(self._section)
|
|
1930
|
+
return self._section
|
|
1931
|
+
|
|
1932
|
+
cdef class pAdicConvert_CR_QQ(RingMap):
|
|
1933
|
+
"""
|
|
1934
|
+
The map from the capped relative ring back to the rationals that returns a
|
|
1935
|
+
rational approximation of its input.
|
|
1936
|
+
|
|
1937
|
+
EXAMPLES::
|
|
1938
|
+
|
|
1939
|
+
sage: f = Qp(5).coerce_map_from(QQ).section(); f
|
|
1940
|
+
Set-theoretic ring morphism:
|
|
1941
|
+
From: 5-adic Field with capped relative precision 20
|
|
1942
|
+
To: Rational Field
|
|
1943
|
+
"""
|
|
1944
|
+
def __init__(self, R):
|
|
1945
|
+
"""
|
|
1946
|
+
Initialization.
|
|
1947
|
+
|
|
1948
|
+
EXAMPLES::
|
|
1949
|
+
|
|
1950
|
+
sage: f = Qp(5).coerce_map_from(QQ).section(); type(f)
|
|
1951
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicConvert_CR_QQ'>
|
|
1952
|
+
sage: f.category()
|
|
1953
|
+
Category of homsets of sets
|
|
1954
|
+
"""
|
|
1955
|
+
if R.absolute_degree() > 1 or R.characteristic() != 0 or R.residue_characteristic() == 0:
|
|
1956
|
+
RingMap.__init__(self, Hom(R, QQ, SetsWithPartialMaps()))
|
|
1957
|
+
else:
|
|
1958
|
+
RingMap.__init__(self, Hom(R, QQ, Sets()))
|
|
1959
|
+
|
|
1960
|
+
cpdef Element _call_(self, _x):
|
|
1961
|
+
"""
|
|
1962
|
+
Evaluation.
|
|
1963
|
+
|
|
1964
|
+
EXAMPLES::
|
|
1965
|
+
|
|
1966
|
+
sage: f = Qp(5).coerce_map_from(QQ).section()
|
|
1967
|
+
sage: f(Qp(5)(-1))
|
|
1968
|
+
-1
|
|
1969
|
+
sage: f(Qp(5)(0))
|
|
1970
|
+
0
|
|
1971
|
+
sage: f(Qp(5)(1/5))
|
|
1972
|
+
1/5
|
|
1973
|
+
"""
|
|
1974
|
+
cdef Rational ans = Rational.__new__(Rational)
|
|
1975
|
+
cdef CRElement x = _x
|
|
1976
|
+
if x.relprec == 0:
|
|
1977
|
+
mpq_set_ui(ans.value, 0, 1)
|
|
1978
|
+
else:
|
|
1979
|
+
cconv_mpq_t_out(ans.value, x.unit, x.ordp, x.relprec, x.prime_pow)
|
|
1980
|
+
return ans
|
|
1981
|
+
|
|
1982
|
+
cdef class pAdicConvert_QQ_CR(Morphism):
|
|
1983
|
+
"""
|
|
1984
|
+
The inclusion map from the rationals to a capped relative ring that is
|
|
1985
|
+
defined on all elements with nonnegative `p`-adic valuation.
|
|
1986
|
+
|
|
1987
|
+
EXAMPLES::
|
|
1988
|
+
|
|
1989
|
+
sage: f = Zp(5).convert_map_from(QQ); f
|
|
1990
|
+
Generic morphism:
|
|
1991
|
+
From: Rational Field
|
|
1992
|
+
To: 5-adic Ring with capped relative precision 20
|
|
1993
|
+
"""
|
|
1994
|
+
def __init__(self, R):
|
|
1995
|
+
"""
|
|
1996
|
+
Initialization.
|
|
1997
|
+
|
|
1998
|
+
EXAMPLES::
|
|
1999
|
+
|
|
2000
|
+
sage: f = Zp(5).convert_map_from(QQ); type(f)
|
|
2001
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicConvert_QQ_CR'>
|
|
2002
|
+
"""
|
|
2003
|
+
Morphism.__init__(self, Hom(QQ, R, SetsWithPartialMaps()))
|
|
2004
|
+
self._zero = R.element_class(R, 0)
|
|
2005
|
+
self._section = pAdicConvert_CR_QQ(R)
|
|
2006
|
+
|
|
2007
|
+
cdef dict _extra_slots(self):
|
|
2008
|
+
"""
|
|
2009
|
+
Helper for copying and pickling.
|
|
2010
|
+
|
|
2011
|
+
EXAMPLES::
|
|
2012
|
+
|
|
2013
|
+
sage: f = Zp(5).convert_map_from(QQ)
|
|
2014
|
+
sage: g = copy(f) # indirect doctest
|
|
2015
|
+
sage: g == f
|
|
2016
|
+
True
|
|
2017
|
+
sage: g(1/6)
|
|
2018
|
+
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 + O(5^20)
|
|
2019
|
+
sage: g(1/6) == f(1/6)
|
|
2020
|
+
True
|
|
2021
|
+
"""
|
|
2022
|
+
_slots = Morphism._extra_slots(self)
|
|
2023
|
+
_slots['_zero'] = self._zero
|
|
2024
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
2025
|
+
return _slots
|
|
2026
|
+
|
|
2027
|
+
cdef _update_slots(self, dict _slots):
|
|
2028
|
+
"""
|
|
2029
|
+
Helper for copying and pickling.
|
|
2030
|
+
|
|
2031
|
+
EXAMPLES::
|
|
2032
|
+
|
|
2033
|
+
sage: f = Zp(5).convert_map_from(QQ)
|
|
2034
|
+
sage: g = copy(f) # indirect doctest
|
|
2035
|
+
sage: g == f
|
|
2036
|
+
True
|
|
2037
|
+
sage: g(1/6)
|
|
2038
|
+
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 + O(5^20)
|
|
2039
|
+
sage: g(1/6) == f(1/6)
|
|
2040
|
+
True
|
|
2041
|
+
"""
|
|
2042
|
+
self._zero = _slots['_zero']
|
|
2043
|
+
self._section = _slots['_section']
|
|
2044
|
+
Morphism._update_slots(self, _slots)
|
|
2045
|
+
|
|
2046
|
+
cpdef Element _call_(self, x):
|
|
2047
|
+
"""
|
|
2048
|
+
Evaluation.
|
|
2049
|
+
|
|
2050
|
+
EXAMPLES::
|
|
2051
|
+
|
|
2052
|
+
sage: f = Zp(5,4).convert_map_from(QQ)
|
|
2053
|
+
sage: f(1/7)
|
|
2054
|
+
3 + 3*5 + 2*5^3 + O(5^4)
|
|
2055
|
+
sage: f(0)
|
|
2056
|
+
0
|
|
2057
|
+
"""
|
|
2058
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
2059
|
+
return self._zero
|
|
2060
|
+
cdef CRElement ans = self._zero._new_c()
|
|
2061
|
+
ans.relprec = ans.prime_pow.ram_prec_cap
|
|
2062
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.relprec, False, self._zero.prime_pow)
|
|
2063
|
+
if ans.ordp < 0:
|
|
2064
|
+
raise ValueError("p divides the denominator")
|
|
2065
|
+
return ans
|
|
2066
|
+
|
|
2067
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
2068
|
+
"""
|
|
2069
|
+
This function is used when some precision cap is passed in
|
|
2070
|
+
(relative or absolute or both), or an empty element is
|
|
2071
|
+
desired.
|
|
2072
|
+
|
|
2073
|
+
See the documentation for
|
|
2074
|
+
:meth:`pAdicCappedRelativeElement.__init__` for more details.
|
|
2075
|
+
|
|
2076
|
+
EXAMPLES::
|
|
2077
|
+
|
|
2078
|
+
sage: R = Zp(5,4)
|
|
2079
|
+
sage: type(R(10/3,2))
|
|
2080
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'>
|
|
2081
|
+
sage: R(10/3,2) # indirect doctest
|
|
2082
|
+
4*5 + O(5^2)
|
|
2083
|
+
sage: R(10/3,3,1)
|
|
2084
|
+
4*5 + O(5^2)
|
|
2085
|
+
sage: R(10/3,absprec=2)
|
|
2086
|
+
4*5 + O(5^2)
|
|
2087
|
+
sage: R(10/3,relprec=2)
|
|
2088
|
+
4*5 + 5^2 + O(5^3)
|
|
2089
|
+
sage: R(10/3,absprec=1)
|
|
2090
|
+
O(5)
|
|
2091
|
+
sage: R(10/3,empty=True)
|
|
2092
|
+
O(5^0)
|
|
2093
|
+
sage: R(3/100,relprec=3)
|
|
2094
|
+
Traceback (most recent call last):
|
|
2095
|
+
...
|
|
2096
|
+
ValueError: p divides the denominator
|
|
2097
|
+
"""
|
|
2098
|
+
cdef long val, aprec, rprec
|
|
2099
|
+
cdef CRElement ans
|
|
2100
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, self._zero.prime_pow)
|
|
2101
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
2102
|
+
if exactzero(aprec):
|
|
2103
|
+
return self._zero
|
|
2104
|
+
ans = self._zero._new_c()
|
|
2105
|
+
ans._set_inexact_zero(aprec)
|
|
2106
|
+
else:
|
|
2107
|
+
val = get_ordp(x, self._zero.prime_pow)
|
|
2108
|
+
ans = self._zero._new_c()
|
|
2109
|
+
if aprec <= val:
|
|
2110
|
+
ans._set_inexact_zero(aprec)
|
|
2111
|
+
else:
|
|
2112
|
+
ans.relprec = min(rprec, aprec - val)
|
|
2113
|
+
ans.ordp = cconv_mpq_t(ans.unit, (<Rational>x).value, ans.relprec, False, self._zero.prime_pow)
|
|
2114
|
+
if ans.ordp < 0:
|
|
2115
|
+
raise ValueError("p divides the denominator")
|
|
2116
|
+
return ans
|
|
2117
|
+
|
|
2118
|
+
def section(self):
|
|
2119
|
+
"""
|
|
2120
|
+
Return the map back to the rationals that returns the smallest
|
|
2121
|
+
nonnegative integer approximation to its input which is accurate up to
|
|
2122
|
+
the precision.
|
|
2123
|
+
|
|
2124
|
+
EXAMPLES::
|
|
2125
|
+
|
|
2126
|
+
sage: f = Zp(5,4).convert_map_from(QQ).section()
|
|
2127
|
+
sage: f(Zp(5,4)(-1))
|
|
2128
|
+
-1
|
|
2129
|
+
"""
|
|
2130
|
+
from sage.misc.constant_function import ConstantFunction
|
|
2131
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
2132
|
+
import copy
|
|
2133
|
+
self._section = copy.copy(self._section)
|
|
2134
|
+
return self._section
|
|
2135
|
+
|
|
2136
|
+
cdef class pAdicCoercion_CR_frac_field(RingHomomorphism):
|
|
2137
|
+
r"""
|
|
2138
|
+
The canonical inclusion of `\ZZ_q` into its fraction field.
|
|
2139
|
+
|
|
2140
|
+
EXAMPLES::
|
|
2141
|
+
|
|
2142
|
+
sage: # needs sage.libs.flint
|
|
2143
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2144
|
+
sage: K = R.fraction_field()
|
|
2145
|
+
sage: f = K.coerce_map_from(R); f
|
|
2146
|
+
Ring morphism:
|
|
2147
|
+
From: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
2148
|
+
To: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
2149
|
+
|
|
2150
|
+
TESTS::
|
|
2151
|
+
|
|
2152
|
+
sage: TestSuite(f).run() # needs sage.libs.flint
|
|
2153
|
+
"""
|
|
2154
|
+
def __init__(self, R, K):
|
|
2155
|
+
"""
|
|
2156
|
+
Initialization.
|
|
2157
|
+
|
|
2158
|
+
EXAMPLES::
|
|
2159
|
+
|
|
2160
|
+
sage: # needs sage.libs.flint
|
|
2161
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2162
|
+
sage: K = R.fraction_field()
|
|
2163
|
+
sage: f = K.coerce_map_from(R); type(f)
|
|
2164
|
+
<class 'sage.rings.padics.qadic_flint_CR.pAdicCoercion_CR_frac_field'>
|
|
2165
|
+
"""
|
|
2166
|
+
RingHomomorphism.__init__(self, R.Hom(K))
|
|
2167
|
+
self._zero = K(0)
|
|
2168
|
+
self._section = pAdicConvert_CR_frac_field(K, R)
|
|
2169
|
+
|
|
2170
|
+
cpdef Element _call_(self, _x):
|
|
2171
|
+
"""
|
|
2172
|
+
Evaluation.
|
|
2173
|
+
|
|
2174
|
+
EXAMPLES::
|
|
2175
|
+
|
|
2176
|
+
sage: # needs sage.libs.flint
|
|
2177
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2178
|
+
sage: K = R.fraction_field()
|
|
2179
|
+
sage: f = K.coerce_map_from(R)
|
|
2180
|
+
sage: f(a)
|
|
2181
|
+
a + O(3^20)
|
|
2182
|
+
sage: f(R(0))
|
|
2183
|
+
0
|
|
2184
|
+
"""
|
|
2185
|
+
cdef CRElement x = _x
|
|
2186
|
+
cdef CRElement ans = self._zero._new_c()
|
|
2187
|
+
ans.ordp = x.ordp
|
|
2188
|
+
ans.relprec = x.relprec
|
|
2189
|
+
cshift_notrunc(ans.unit, x.unit, 0, ans.relprec, x.prime_pow, False)
|
|
2190
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2191
|
+
# The base ring is wrong, so we fix it.
|
|
2192
|
+
K = ans.unit.base_ring()
|
|
2193
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
2194
|
+
return ans
|
|
2195
|
+
|
|
2196
|
+
cpdef Element _call_with_args(self, _x, args=(), kwds={}):
|
|
2197
|
+
"""
|
|
2198
|
+
This function is used when some precision cap is passed in
|
|
2199
|
+
(relative or absolute or both).
|
|
2200
|
+
|
|
2201
|
+
See the documentation for
|
|
2202
|
+
:meth:`pAdicCappedAbsoluteElement.__init__` for more details.
|
|
2203
|
+
|
|
2204
|
+
EXAMPLES::
|
|
2205
|
+
|
|
2206
|
+
sage: # needs sage.libs.flint
|
|
2207
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2208
|
+
sage: K = R.fraction_field()
|
|
2209
|
+
sage: f = K.coerce_map_from(R)
|
|
2210
|
+
sage: f(a, 3)
|
|
2211
|
+
a + O(3^3)
|
|
2212
|
+
sage: b = 9*a
|
|
2213
|
+
sage: f(b, 3) # indirect doctest
|
|
2214
|
+
a*3^2 + O(3^3)
|
|
2215
|
+
sage: f(b, 4, 1)
|
|
2216
|
+
a*3^2 + O(3^3)
|
|
2217
|
+
sage: f(b, 4, 3)
|
|
2218
|
+
a*3^2 + O(3^4)
|
|
2219
|
+
sage: f(b, absprec=4)
|
|
2220
|
+
a*3^2 + O(3^4)
|
|
2221
|
+
sage: f(b, relprec=3)
|
|
2222
|
+
a*3^2 + O(3^5)
|
|
2223
|
+
sage: f(b, absprec=1)
|
|
2224
|
+
O(3)
|
|
2225
|
+
sage: f(R(0))
|
|
2226
|
+
0
|
|
2227
|
+
"""
|
|
2228
|
+
cdef long aprec, rprec
|
|
2229
|
+
cdef CRElement x = _x
|
|
2230
|
+
cdef CRElement ans = self._zero._new_c()
|
|
2231
|
+
cdef bint reduce = False
|
|
2232
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, ans.prime_pow)
|
|
2233
|
+
if aprec <= x.ordp:
|
|
2234
|
+
csetzero(ans.unit, x.prime_pow)
|
|
2235
|
+
ans.relprec = 0
|
|
2236
|
+
ans.ordp = aprec
|
|
2237
|
+
else:
|
|
2238
|
+
if rprec < x.relprec:
|
|
2239
|
+
reduce = True
|
|
2240
|
+
else:
|
|
2241
|
+
rprec = x.relprec
|
|
2242
|
+
if aprec < rprec + x.ordp:
|
|
2243
|
+
rprec = aprec - x.ordp
|
|
2244
|
+
reduce = True
|
|
2245
|
+
ans.ordp = x.ordp
|
|
2246
|
+
ans.relprec = rprec
|
|
2247
|
+
cshift_notrunc(ans.unit, x.unit, 0, rprec, x.prime_pow, reduce)
|
|
2248
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2249
|
+
# The base ring is wrong, so we fix it.
|
|
2250
|
+
K = ans.unit.base_ring()
|
|
2251
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
2252
|
+
return ans
|
|
2253
|
+
|
|
2254
|
+
def section(self):
|
|
2255
|
+
"""
|
|
2256
|
+
Return a map back to the ring that converts elements of
|
|
2257
|
+
nonnegative valuation.
|
|
2258
|
+
|
|
2259
|
+
EXAMPLES::
|
|
2260
|
+
|
|
2261
|
+
sage: # needs sage.libs.flint
|
|
2262
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2263
|
+
sage: K = R.fraction_field()
|
|
2264
|
+
sage: f = K.coerce_map_from(R)
|
|
2265
|
+
sage: f(K.gen())
|
|
2266
|
+
a + O(3^20)
|
|
2267
|
+
sage: f.section()
|
|
2268
|
+
Generic morphism:
|
|
2269
|
+
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
2270
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
2271
|
+
"""
|
|
2272
|
+
from sage.misc.constant_function import ConstantFunction
|
|
2273
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
2274
|
+
import copy
|
|
2275
|
+
self._section = copy.copy(self._section)
|
|
2276
|
+
return self._section
|
|
2277
|
+
|
|
2278
|
+
cdef dict _extra_slots(self):
|
|
2279
|
+
"""
|
|
2280
|
+
Helper for copying and pickling.
|
|
2281
|
+
|
|
2282
|
+
TESTS::
|
|
2283
|
+
|
|
2284
|
+
sage: # needs sage.libs.flint
|
|
2285
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2286
|
+
sage: K = R.fraction_field()
|
|
2287
|
+
sage: f = K.coerce_map_from(R)
|
|
2288
|
+
sage: g = copy(f) # indirect doctest
|
|
2289
|
+
sage: g
|
|
2290
|
+
Ring morphism:
|
|
2291
|
+
From: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
2292
|
+
To: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
2293
|
+
sage: g == f
|
|
2294
|
+
True
|
|
2295
|
+
sage: g is f
|
|
2296
|
+
False
|
|
2297
|
+
sage: g(a)
|
|
2298
|
+
a + O(3^20)
|
|
2299
|
+
sage: g(a) == f(a)
|
|
2300
|
+
True
|
|
2301
|
+
"""
|
|
2302
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
2303
|
+
_slots['_zero'] = self._zero
|
|
2304
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
2305
|
+
return _slots
|
|
2306
|
+
|
|
2307
|
+
cdef _update_slots(self, dict _slots):
|
|
2308
|
+
"""
|
|
2309
|
+
Helper for copying and pickling.
|
|
2310
|
+
|
|
2311
|
+
TESTS::
|
|
2312
|
+
|
|
2313
|
+
sage: # needs sage.libs.flint
|
|
2314
|
+
sage: R.<a> = ZqCR(9, implementation='FLINT')
|
|
2315
|
+
sage: K = R.fraction_field()
|
|
2316
|
+
sage: f = K.coerce_map_from(R)
|
|
2317
|
+
sage: g = copy(f) # indirect doctest
|
|
2318
|
+
sage: g
|
|
2319
|
+
Ring morphism:
|
|
2320
|
+
From: 3-adic Unramified Extension Ring in a defined by x^2 + 2*x + 2
|
|
2321
|
+
To: 3-adic Unramified Extension Field in a defined by x^2 + 2*x + 2
|
|
2322
|
+
sage: g == f
|
|
2323
|
+
True
|
|
2324
|
+
sage: g is f
|
|
2325
|
+
False
|
|
2326
|
+
sage: g(a)
|
|
2327
|
+
a + O(3^20)
|
|
2328
|
+
sage: g(a) == f(a)
|
|
2329
|
+
True
|
|
2330
|
+
"""
|
|
2331
|
+
self._zero = _slots['_zero']
|
|
2332
|
+
self._section = _slots['_section']
|
|
2333
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
2334
|
+
|
|
2335
|
+
def is_injective(self):
|
|
2336
|
+
r"""
|
|
2337
|
+
Return whether this map is injective.
|
|
2338
|
+
|
|
2339
|
+
EXAMPLES::
|
|
2340
|
+
|
|
2341
|
+
sage: # needs sage.libs.flint
|
|
2342
|
+
sage: R.<a> = ZqCR(9, implementation='FLINT')
|
|
2343
|
+
sage: K = R.fraction_field()
|
|
2344
|
+
sage: f = K.coerce_map_from(R)
|
|
2345
|
+
sage: f.is_injective()
|
|
2346
|
+
True
|
|
2347
|
+
"""
|
|
2348
|
+
return True
|
|
2349
|
+
|
|
2350
|
+
def is_surjective(self):
|
|
2351
|
+
r"""
|
|
2352
|
+
Return whether this map is surjective.
|
|
2353
|
+
|
|
2354
|
+
EXAMPLES::
|
|
2355
|
+
|
|
2356
|
+
sage: # needs sage.libs.flint
|
|
2357
|
+
sage: R.<a> = ZqCR(9, implementation='FLINT')
|
|
2358
|
+
sage: K = R.fraction_field()
|
|
2359
|
+
sage: f = K.coerce_map_from(R)
|
|
2360
|
+
sage: f.is_surjective()
|
|
2361
|
+
False
|
|
2362
|
+
"""
|
|
2363
|
+
return False
|
|
2364
|
+
|
|
2365
|
+
|
|
2366
|
+
cdef class pAdicConvert_CR_frac_field(Morphism):
|
|
2367
|
+
r"""
|
|
2368
|
+
The section of the inclusion from `\ZZ_q` to its fraction field.
|
|
2369
|
+
|
|
2370
|
+
EXAMPLES::
|
|
2371
|
+
|
|
2372
|
+
sage: # needs sage.libs.flint
|
|
2373
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2374
|
+
sage: K = R.fraction_field()
|
|
2375
|
+
sage: f = R.convert_map_from(K); f
|
|
2376
|
+
Generic morphism:
|
|
2377
|
+
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
2378
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
2379
|
+
"""
|
|
2380
|
+
def __init__(self, K, R):
|
|
2381
|
+
"""
|
|
2382
|
+
Initialization.
|
|
2383
|
+
|
|
2384
|
+
EXAMPLES::
|
|
2385
|
+
|
|
2386
|
+
sage: # needs sage.libs.flint
|
|
2387
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2388
|
+
sage: K = R.fraction_field()
|
|
2389
|
+
sage: f = R.convert_map_from(K); type(f)
|
|
2390
|
+
<class 'sage.rings.padics.qadic_flint_CR.pAdicConvert_CR_frac_field'>
|
|
2391
|
+
"""
|
|
2392
|
+
Morphism.__init__(self, Hom(K, R, SetsWithPartialMaps()))
|
|
2393
|
+
self._zero = R(0)
|
|
2394
|
+
|
|
2395
|
+
cpdef Element _call_(self, _x):
|
|
2396
|
+
"""
|
|
2397
|
+
Evaluation.
|
|
2398
|
+
|
|
2399
|
+
EXAMPLES::
|
|
2400
|
+
|
|
2401
|
+
sage: # needs sage.libs.flint
|
|
2402
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2403
|
+
sage: K = R.fraction_field()
|
|
2404
|
+
sage: f = R.convert_map_from(K)
|
|
2405
|
+
sage: f(K.gen())
|
|
2406
|
+
a + O(3^20)
|
|
2407
|
+
"""
|
|
2408
|
+
cdef CRElement x = _x
|
|
2409
|
+
if x.ordp < 0:
|
|
2410
|
+
raise ValueError("negative valuation")
|
|
2411
|
+
cdef CRElement ans = self._zero._new_c()
|
|
2412
|
+
ans.relprec = x.relprec
|
|
2413
|
+
ans.ordp = x.ordp
|
|
2414
|
+
cshift_notrunc(ans.unit, x.unit, 0, ans.relprec, ans.prime_pow, False)
|
|
2415
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2416
|
+
# The base ring is wrong, so we fix it.
|
|
2417
|
+
K = ans.unit.base_ring()
|
|
2418
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
2419
|
+
return ans
|
|
2420
|
+
|
|
2421
|
+
cpdef Element _call_with_args(self, _x, args=(), kwds={}):
|
|
2422
|
+
"""
|
|
2423
|
+
This function is used when some precision cap is passed in
|
|
2424
|
+
(relative or absolute or both).
|
|
2425
|
+
|
|
2426
|
+
See the documentation for
|
|
2427
|
+
:meth:`pAdicCappedAbsoluteElement.__init__` for more details.
|
|
2428
|
+
|
|
2429
|
+
EXAMPLES::
|
|
2430
|
+
|
|
2431
|
+
sage: # needs sage.libs.flint
|
|
2432
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2433
|
+
sage: K = R.fraction_field()
|
|
2434
|
+
sage: f = R.convert_map_from(K); a = K(a)
|
|
2435
|
+
sage: f(a, 3)
|
|
2436
|
+
a + O(3^3)
|
|
2437
|
+
sage: b = 9*a
|
|
2438
|
+
sage: f(b, 3) # indirect doctest
|
|
2439
|
+
a*3^2 + O(3^3)
|
|
2440
|
+
sage: f(b, 4, 1)
|
|
2441
|
+
a*3^2 + O(3^3)
|
|
2442
|
+
sage: f(b, 4, 3)
|
|
2443
|
+
a*3^2 + O(3^4)
|
|
2444
|
+
sage: f(b, absprec=4)
|
|
2445
|
+
a*3^2 + O(3^4)
|
|
2446
|
+
sage: f(b, relprec=3)
|
|
2447
|
+
a*3^2 + O(3^5)
|
|
2448
|
+
sage: f(b, absprec=1)
|
|
2449
|
+
O(3)
|
|
2450
|
+
sage: f(K(0))
|
|
2451
|
+
0
|
|
2452
|
+
"""
|
|
2453
|
+
cdef long aprec, rprec
|
|
2454
|
+
cdef CRElement x = _x
|
|
2455
|
+
if x.ordp < 0:
|
|
2456
|
+
raise ValueError("negative valuation")
|
|
2457
|
+
cdef CRElement ans = self._zero._new_c()
|
|
2458
|
+
cdef bint reduce = False
|
|
2459
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, ans.prime_pow)
|
|
2460
|
+
if aprec <= x.ordp:
|
|
2461
|
+
csetzero(ans.unit, x.prime_pow)
|
|
2462
|
+
ans.relprec = 0
|
|
2463
|
+
ans.ordp = aprec
|
|
2464
|
+
else:
|
|
2465
|
+
if rprec < x.relprec:
|
|
2466
|
+
reduce = True
|
|
2467
|
+
else:
|
|
2468
|
+
rprec = x.relprec
|
|
2469
|
+
if aprec < rprec + x.ordp:
|
|
2470
|
+
rprec = aprec - x.ordp
|
|
2471
|
+
reduce = True
|
|
2472
|
+
ans.ordp = x.ordp
|
|
2473
|
+
ans.relprec = rprec
|
|
2474
|
+
cshift_notrunc(ans.unit, x.unit, 0, rprec, x.prime_pow, reduce)
|
|
2475
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2476
|
+
# The base ring is wrong, so we fix it.
|
|
2477
|
+
K = ans.unit.base_ring()
|
|
2478
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
2479
|
+
return ans
|
|
2480
|
+
|
|
2481
|
+
cdef dict _extra_slots(self):
|
|
2482
|
+
"""
|
|
2483
|
+
Helper for copying and pickling.
|
|
2484
|
+
|
|
2485
|
+
TESTS::
|
|
2486
|
+
|
|
2487
|
+
sage: # needs sage.libs.flint
|
|
2488
|
+
sage: R.<a> = ZqCR(27, implementation='FLINT')
|
|
2489
|
+
sage: K = R.fraction_field()
|
|
2490
|
+
sage: f = R.convert_map_from(K)
|
|
2491
|
+
sage: a = K(a)
|
|
2492
|
+
sage: g = copy(f) # indirect doctest
|
|
2493
|
+
sage: g
|
|
2494
|
+
Generic morphism:
|
|
2495
|
+
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
2496
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
2497
|
+
sage: g == f
|
|
2498
|
+
True
|
|
2499
|
+
sage: g is f
|
|
2500
|
+
False
|
|
2501
|
+
sage: g(a)
|
|
2502
|
+
a + O(3^20)
|
|
2503
|
+
sage: g(a) == f(a)
|
|
2504
|
+
True
|
|
2505
|
+
"""
|
|
2506
|
+
_slots = Morphism._extra_slots(self)
|
|
2507
|
+
_slots['_zero'] = self._zero
|
|
2508
|
+
return _slots
|
|
2509
|
+
|
|
2510
|
+
cdef _update_slots(self, dict _slots):
|
|
2511
|
+
"""
|
|
2512
|
+
Helper for copying and pickling.
|
|
2513
|
+
|
|
2514
|
+
TESTS::
|
|
2515
|
+
|
|
2516
|
+
sage: # needs sage.libs.flint
|
|
2517
|
+
sage: R.<a> = ZqCR(9, implementation='FLINT')
|
|
2518
|
+
sage: K = R.fraction_field()
|
|
2519
|
+
sage: f = R.convert_map_from(K)
|
|
2520
|
+
sage: a = K(a)
|
|
2521
|
+
sage: g = copy(f) # indirect doctest
|
|
2522
|
+
sage: g
|
|
2523
|
+
Generic morphism:
|
|
2524
|
+
From: 3-adic Unramified Extension Field in a defined by x^2 + 2*x + 2
|
|
2525
|
+
To: 3-adic Unramified Extension Ring in a defined by x^2 + 2*x + 2
|
|
2526
|
+
sage: g == f
|
|
2527
|
+
True
|
|
2528
|
+
sage: g is f
|
|
2529
|
+
False
|
|
2530
|
+
sage: g(a)
|
|
2531
|
+
a + O(3^20)
|
|
2532
|
+
sage: g(a) == f(a)
|
|
2533
|
+
True
|
|
2534
|
+
"""
|
|
2535
|
+
self._zero = _slots['_zero']
|
|
2536
|
+
Morphism._update_slots(self, _slots)
|
|
2537
|
+
|
|
2538
|
+
|
|
2539
|
+
def unpickle_cre_v2(cls, parent, unit, ordp, relprec):
|
|
2540
|
+
"""
|
|
2541
|
+
Unpickles a capped relative element.
|
|
2542
|
+
|
|
2543
|
+
EXAMPLES::
|
|
2544
|
+
|
|
2545
|
+
sage: from sage.rings.padics.padic_capped_relative_element import unpickle_cre_v2
|
|
2546
|
+
sage: R = Zp(5); a = R(85,6)
|
|
2547
|
+
sage: b = unpickle_cre_v2(a.__class__, R, 17, 1, 5)
|
|
2548
|
+
sage: a == b
|
|
2549
|
+
True
|
|
2550
|
+
sage: a.precision_relative() == b.precision_relative()
|
|
2551
|
+
True
|
|
2552
|
+
"""
|
|
2553
|
+
cdef CRElement ans = cls.__new__(cls)
|
|
2554
|
+
ans._parent = parent
|
|
2555
|
+
ans.prime_pow = <PowComputer_?>parent.prime_pow
|
|
2556
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
2557
|
+
polyt = type(ans.prime_pow.modulus)
|
|
2558
|
+
ans.unit = <celement>polyt.__new__(polyt)
|
|
2559
|
+
cconstruct(ans.unit, ans.prime_pow)
|
|
2560
|
+
cunpickle(ans.unit, unit, ans.prime_pow)
|
|
2561
|
+
ans.ordp = ordp
|
|
2562
|
+
ans.relprec = relprec
|
|
2563
|
+
return ans
|