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,1575 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
"""
|
|
3
|
+
Fixed modulus template for complete discrete valuation rings
|
|
4
|
+
|
|
5
|
+
In order to use this template you need to write a linkage file and
|
|
6
|
+
gluing file. For an example see ``mpz_linkage.pxi`` (linkage file) and
|
|
7
|
+
``padic_fixed_modulus_element.pyx`` (gluing file).
|
|
8
|
+
|
|
9
|
+
The linkage file implements a common API that is then used in the
|
|
10
|
+
class :class:`FMElement` defined here. See ``sage/libs/linkages/padics/API.pxi``
|
|
11
|
+
for the functions needed.
|
|
12
|
+
|
|
13
|
+
The gluing file does the following:
|
|
14
|
+
|
|
15
|
+
- ``ctypedef``'s ``celement`` to be the appropriate type (e.g. ``mpz_t``)
|
|
16
|
+
- includes the linkage file
|
|
17
|
+
- includes this template
|
|
18
|
+
- defines a concrete class inheriting from :class:`FMElement`, and implements
|
|
19
|
+
any desired extra methods
|
|
20
|
+
|
|
21
|
+
AUTHORS:
|
|
22
|
+
|
|
23
|
+
- David Roe (2012-03-01) -- initial version
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
#*****************************************************************************
|
|
27
|
+
# Copyright (C) 2007-2012 David Roe <roed.math@gmail.com>
|
|
28
|
+
# William Stein <wstein@gmail.com>
|
|
29
|
+
#
|
|
30
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
31
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
32
|
+
# the License, or (at your option) any later version.
|
|
33
|
+
#
|
|
34
|
+
# http://www.gnu.org/licenses/
|
|
35
|
+
#*****************************************************************************
|
|
36
|
+
|
|
37
|
+
include "padic_template_element.pxi"
|
|
38
|
+
from cpython.long cimport *
|
|
39
|
+
|
|
40
|
+
from sage.structure.element cimport Element
|
|
41
|
+
from sage.rings.padics.common_conversion cimport comb_prec, _process_args_and_kwds
|
|
42
|
+
from sage.rings.integer_ring import ZZ
|
|
43
|
+
from sage.rings.rational_field import QQ
|
|
44
|
+
from sage.categories.sets_cat import Sets
|
|
45
|
+
from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
|
|
46
|
+
from sage.categories.homset import Hom
|
|
47
|
+
|
|
48
|
+
cdef class FMElement(pAdicTemplateElement):
|
|
49
|
+
cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1:
|
|
50
|
+
"""
|
|
51
|
+
Set the value of this element from given defining data.
|
|
52
|
+
|
|
53
|
+
This function is intended for use in conversion, and should
|
|
54
|
+
not be called on an element created with :meth:`_new_c`.
|
|
55
|
+
|
|
56
|
+
INPUT:
|
|
57
|
+
|
|
58
|
+
- ``x`` -- data defining a `p`-adic element: int, long,
|
|
59
|
+
Integer, Rational, other `p`-adic element...
|
|
60
|
+
|
|
61
|
+
- ``val`` -- the valuation of the resulting element (unused;
|
|
62
|
+
for compatibility with other `p`-adic precision modes)
|
|
63
|
+
|
|
64
|
+
- ``xprec -- an inherent precision of ``x`` (unused; for
|
|
65
|
+
compatibility with other `p`-adic precision modes)
|
|
66
|
+
|
|
67
|
+
- ``absprec`` -- an absolute precision cap for this element
|
|
68
|
+
(unused; for compatibility with other `p`-adic precision
|
|
69
|
+
modes)
|
|
70
|
+
|
|
71
|
+
- ``relprec`` -- a relative precision cap for this element
|
|
72
|
+
(unused; for compatibility with other `p`-adic precision
|
|
73
|
+
modes)
|
|
74
|
+
|
|
75
|
+
TESTS::
|
|
76
|
+
|
|
77
|
+
sage: R = ZpFM(5)
|
|
78
|
+
sage: a = R(17,5); a # indirect doctest
|
|
79
|
+
2 + 3*5
|
|
80
|
+
sage: R = ZpFM(5,5)
|
|
81
|
+
sage: a = R(25/9); a # indirect doctest
|
|
82
|
+
4*5^2 + 2*5^3
|
|
83
|
+
"""
|
|
84
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
85
|
+
polyt = type(self.prime_pow.modulus)
|
|
86
|
+
self.value = <celement>polyt.__new__(polyt)
|
|
87
|
+
cconstruct(self.value, self.prime_pow)
|
|
88
|
+
if isinstance(x, FMElement) and x.parent() is self.parent():
|
|
89
|
+
cshift_notrunc(self.value, (<FMElement>x).value, 0, 0, self.prime_pow, False)
|
|
90
|
+
else:
|
|
91
|
+
cconv(self.value, x, self.prime_pow.ram_prec_cap, 0, self.prime_pow)
|
|
92
|
+
|
|
93
|
+
cdef FMElement _new_c(self):
|
|
94
|
+
"""
|
|
95
|
+
Create a new element with the same basic info.
|
|
96
|
+
|
|
97
|
+
TESTS::
|
|
98
|
+
|
|
99
|
+
sage: R = ZpFM(5); R(6) * R(7) # indirect doctest
|
|
100
|
+
2 + 3*5 + 5^2
|
|
101
|
+
"""
|
|
102
|
+
cdef type t = type(self)
|
|
103
|
+
cdef FMElement ans = t.__new__(t)
|
|
104
|
+
ans._parent = self._parent
|
|
105
|
+
ans.prime_pow = self.prime_pow
|
|
106
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
107
|
+
polyt = type(self.prime_pow.modulus)
|
|
108
|
+
ans.value = <celement>polyt.__new__(polyt)
|
|
109
|
+
cconstruct(ans.value, ans.prime_pow)
|
|
110
|
+
return ans
|
|
111
|
+
|
|
112
|
+
cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec):
|
|
113
|
+
"""
|
|
114
|
+
Create a new element with a given value and absolute precision.
|
|
115
|
+
|
|
116
|
+
Used by code that doesn't know the precision type.
|
|
117
|
+
"""
|
|
118
|
+
cdef FMElement ans = self._new_c()
|
|
119
|
+
creduce(ans.value, value, ans.prime_pow.prec_cap, ans.prime_pow)
|
|
120
|
+
return ans
|
|
121
|
+
|
|
122
|
+
cdef int _get_unit(self, celement value) except -1:
|
|
123
|
+
"""
|
|
124
|
+
Set ``value`` to the unit of this `p`-adic element.
|
|
125
|
+
"""
|
|
126
|
+
cremove(value, self.value, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
127
|
+
|
|
128
|
+
cdef int check_preccap(self) except -1:
|
|
129
|
+
"""
|
|
130
|
+
Check that the precision of this element does not exceed the
|
|
131
|
+
precision cap. Does nothing for fixed mod elements.
|
|
132
|
+
|
|
133
|
+
TESTS::
|
|
134
|
+
|
|
135
|
+
sage: ZpFM(5)(1).lift_to_precision(30) # indirect doctest
|
|
136
|
+
1
|
|
137
|
+
"""
|
|
138
|
+
pass
|
|
139
|
+
|
|
140
|
+
def __copy__(self):
|
|
141
|
+
"""
|
|
142
|
+
Return a copy of this element.
|
|
143
|
+
|
|
144
|
+
EXAMPLES::
|
|
145
|
+
|
|
146
|
+
sage: a = ZpFM(5,6)(17); b = copy(a)
|
|
147
|
+
sage: a == b
|
|
148
|
+
True
|
|
149
|
+
sage: a is b
|
|
150
|
+
False
|
|
151
|
+
"""
|
|
152
|
+
cdef FMElement ans = self._new_c()
|
|
153
|
+
ccopy(ans.value, self.value, ans.prime_pow)
|
|
154
|
+
return ans
|
|
155
|
+
|
|
156
|
+
def __dealloc__(self):
|
|
157
|
+
"""
|
|
158
|
+
Deallocate the underlying data structure.
|
|
159
|
+
|
|
160
|
+
TESTS::
|
|
161
|
+
|
|
162
|
+
sage: R = ZpFM(5)
|
|
163
|
+
sage: a = R(17)
|
|
164
|
+
sage: del(a)
|
|
165
|
+
"""
|
|
166
|
+
cdestruct(self.value, self.prime_pow)
|
|
167
|
+
|
|
168
|
+
def __reduce__(self):
|
|
169
|
+
"""
|
|
170
|
+
Return a tuple of a function and data that can be used to unpickle this
|
|
171
|
+
element.
|
|
172
|
+
|
|
173
|
+
EXAMPLES::
|
|
174
|
+
|
|
175
|
+
sage: a = ZpFM(5)(-3)
|
|
176
|
+
sage: type(a)
|
|
177
|
+
<class 'sage.rings.padics.padic_fixed_mod_element.pAdicFixedModElement'>
|
|
178
|
+
sage: loads(dumps(a)) == a
|
|
179
|
+
True
|
|
180
|
+
"""
|
|
181
|
+
return unpickle_fme_v2, (self.__class__, self.parent(), cpickle(self.value, self.prime_pow))
|
|
182
|
+
|
|
183
|
+
cpdef _neg_(self):
|
|
184
|
+
r"""
|
|
185
|
+
Return the additive inverse of this element.
|
|
186
|
+
|
|
187
|
+
EXAMPLES::
|
|
188
|
+
|
|
189
|
+
sage: R = Zp(7, 4, 'fixed-mod', 'series')
|
|
190
|
+
sage: -R(7) # indirect doctest
|
|
191
|
+
6*7 + 6*7^2 + 6*7^3
|
|
192
|
+
"""
|
|
193
|
+
cdef FMElement ans = self._new_c()
|
|
194
|
+
cneg(ans.value, self.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
195
|
+
creduce_small(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
196
|
+
return ans
|
|
197
|
+
|
|
198
|
+
cpdef _add_(self, _right):
|
|
199
|
+
r"""
|
|
200
|
+
Return the sum of this element and ``_right``.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: R = Zp(7, 4, 'fixed-mod', 'series')
|
|
205
|
+
sage: x = R(1721); x
|
|
206
|
+
6 + 5*7^3
|
|
207
|
+
sage: y = R(1373); y
|
|
208
|
+
1 + 4*7^3
|
|
209
|
+
sage: x + y # indirect doctest
|
|
210
|
+
7 + 2*7^3
|
|
211
|
+
"""
|
|
212
|
+
cdef FMElement right = _right
|
|
213
|
+
cdef FMElement ans = self._new_c()
|
|
214
|
+
cadd(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
215
|
+
creduce_small(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
216
|
+
return ans
|
|
217
|
+
|
|
218
|
+
cpdef _sub_(self, _right):
|
|
219
|
+
r"""
|
|
220
|
+
Return the difference of this element and ``_right``.
|
|
221
|
+
|
|
222
|
+
EXAMPLES::
|
|
223
|
+
|
|
224
|
+
sage: R = Zp(7, 4, 'fixed-mod', 'series')
|
|
225
|
+
sage: x = R(1721); x
|
|
226
|
+
6 + 5*7^3
|
|
227
|
+
sage: y = R(1373); y
|
|
228
|
+
1 + 4*7^3
|
|
229
|
+
sage: x - y # indirect doctest
|
|
230
|
+
5 + 7^3
|
|
231
|
+
"""
|
|
232
|
+
cdef FMElement right = _right
|
|
233
|
+
cdef FMElement ans = self._new_c()
|
|
234
|
+
csub(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
235
|
+
creduce_small(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
236
|
+
return ans
|
|
237
|
+
|
|
238
|
+
def __invert__(self):
|
|
239
|
+
r"""
|
|
240
|
+
Return multiplicative inverse of this element. The valuation
|
|
241
|
+
of ``self`` must be zero.
|
|
242
|
+
|
|
243
|
+
EXAMPLES::
|
|
244
|
+
|
|
245
|
+
sage: R = Zp(7, 4, 'fixed-mod', 'series')
|
|
246
|
+
sage: ~R(2)
|
|
247
|
+
4 + 3*7 + 3*7^2 + 3*7^3
|
|
248
|
+
sage: ~R(0)
|
|
249
|
+
Traceback (most recent call last):
|
|
250
|
+
...
|
|
251
|
+
ValueError: cannot invert non-unit
|
|
252
|
+
sage: ~R(7)
|
|
253
|
+
Traceback (most recent call last):
|
|
254
|
+
...
|
|
255
|
+
ValueError: cannot invert non-unit
|
|
256
|
+
"""
|
|
257
|
+
if not cisunit(self.value, self.prime_pow):
|
|
258
|
+
raise ValueError("cannot invert non-unit")
|
|
259
|
+
cdef FMElement ans = self._new_c()
|
|
260
|
+
cinvert(ans.value, self.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
261
|
+
return ans
|
|
262
|
+
|
|
263
|
+
cpdef _mul_(self, _right):
|
|
264
|
+
r"""
|
|
265
|
+
Return the product of this element and ``_right``.
|
|
266
|
+
|
|
267
|
+
EXAMPLES::
|
|
268
|
+
|
|
269
|
+
sage: R = Zp(7, 4, 'fixed-mod', 'series')
|
|
270
|
+
sage: R(3) * R(2) # indirect doctest
|
|
271
|
+
6
|
|
272
|
+
sage: R(1/2) * R(2)
|
|
273
|
+
1
|
|
274
|
+
"""
|
|
275
|
+
cdef FMElement right = _right
|
|
276
|
+
cdef FMElement ans = self._new_c()
|
|
277
|
+
cmul(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
278
|
+
creduce(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
279
|
+
return ans
|
|
280
|
+
|
|
281
|
+
cpdef _div_(self, _right):
|
|
282
|
+
r"""
|
|
283
|
+
Return the quotient of this element and ``right``. ``right`` must have
|
|
284
|
+
valuation zero.
|
|
285
|
+
|
|
286
|
+
EXAMPLES::
|
|
287
|
+
|
|
288
|
+
sage: R = Zp(7, 4, 'fixed-mod', 'series')
|
|
289
|
+
sage: R(3) / R(2) # indirect doctest
|
|
290
|
+
5 + 3*7 + 3*7^2 + 3*7^3
|
|
291
|
+
sage: R(5) / R(0)
|
|
292
|
+
Traceback (most recent call last):
|
|
293
|
+
...
|
|
294
|
+
ValueError: cannot invert non-unit
|
|
295
|
+
sage: R(7) / R(49)
|
|
296
|
+
Traceback (most recent call last):
|
|
297
|
+
...
|
|
298
|
+
ValueError: cannot invert non-unit
|
|
299
|
+
"""
|
|
300
|
+
cdef FMElement right = _right
|
|
301
|
+
cdef FMElement ans = self._new_c()
|
|
302
|
+
if not cisunit(right.value, self.prime_pow):
|
|
303
|
+
raise ValueError("cannot invert non-unit")
|
|
304
|
+
cdivunit(ans.value, self.value, right.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
305
|
+
creduce(ans.value, ans.value, ans.prime_pow.ram_prec_cap, ans.prime_pow)
|
|
306
|
+
return ans
|
|
307
|
+
|
|
308
|
+
def _quo_rem(self, _right):
|
|
309
|
+
"""
|
|
310
|
+
Quotient with remainder.
|
|
311
|
+
|
|
312
|
+
EXAMPLES::
|
|
313
|
+
|
|
314
|
+
sage: R = ZpFM(3, 5)
|
|
315
|
+
sage: R(12).quo_rem(R(2)) # indirect doctest
|
|
316
|
+
(2*3, 0)
|
|
317
|
+
sage: R(2).quo_rem(R(12))
|
|
318
|
+
(0, 2)
|
|
319
|
+
sage: q, r = R(4).quo_rem(R(12)); q, r
|
|
320
|
+
(1 + 2*3 + 2*3^3, 1)
|
|
321
|
+
sage: 12*q + r == 4
|
|
322
|
+
True
|
|
323
|
+
"""
|
|
324
|
+
cdef FMElement right = _right
|
|
325
|
+
if ciszero(right.value, right.prime_pow):
|
|
326
|
+
raise ZeroDivisionError
|
|
327
|
+
cdef FMElement q = self._new_c()
|
|
328
|
+
cdef FMElement r = self._new_c()
|
|
329
|
+
cdef long sval, rval, diff, pcap = self.prime_pow.ram_prec_cap
|
|
330
|
+
sval = self.valuation_c()
|
|
331
|
+
rval = right.valuation_c()
|
|
332
|
+
diff = sval - rval
|
|
333
|
+
if ciszero(self.value, self.prime_pow):
|
|
334
|
+
csetzero(q.value, q.prime_pow)
|
|
335
|
+
csetzero(r.value, r.prime_pow)
|
|
336
|
+
elif diff >= 0:
|
|
337
|
+
# shift right and self by the same power of the uniformizer
|
|
338
|
+
cshift_notrunc(r.value, right.value, -rval, pcap, r.prime_pow, False)
|
|
339
|
+
cshift_notrunc(q.value, self.value, -rval, pcap, q.prime_pow, False)
|
|
340
|
+
# divide
|
|
341
|
+
cdivunit(q.value, q.value, r.value, pcap, q.prime_pow)
|
|
342
|
+
csetzero(r.value, r.prime_pow)
|
|
343
|
+
else:
|
|
344
|
+
cshift(q.value, r.value, self.value, -rval, pcap, q.prime_pow, False)
|
|
345
|
+
cshift_notrunc(q.prime_pow.shift_rem, right.value, -rval, pcap, q.prime_pow, False)
|
|
346
|
+
cdivunit(q.value, q.value, q.prime_pow.shift_rem, pcap, q.prime_pow)
|
|
347
|
+
creduce(q.value, q.value, pcap, q.prime_pow)
|
|
348
|
+
return q, r
|
|
349
|
+
|
|
350
|
+
def __pow__(FMElement self, _right, dummy): # NOTE: dummy ignored, always use self.prime_pow.ram_prec_cap
|
|
351
|
+
"""
|
|
352
|
+
Exponentiation by an integer
|
|
353
|
+
|
|
354
|
+
EXAMPLES::
|
|
355
|
+
|
|
356
|
+
sage: R = ZpFM(11, 5)
|
|
357
|
+
sage: R(1/2)^5
|
|
358
|
+
10 + 7*11 + 11^2 + 5*11^3 + 4*11^4
|
|
359
|
+
sage: R(1/32)
|
|
360
|
+
10 + 7*11 + 11^2 + 5*11^3 + 4*11^4
|
|
361
|
+
sage: R(1/2)^5 == R(1/32)
|
|
362
|
+
True
|
|
363
|
+
sage: R(3)^1000 # indirect doctest
|
|
364
|
+
1 + 4*11^2 + 3*11^3 + 7*11^4
|
|
365
|
+
|
|
366
|
+
TESTS:
|
|
367
|
+
|
|
368
|
+
We check that :issue:`15640` is resolved::
|
|
369
|
+
|
|
370
|
+
sage: R(11)^-1
|
|
371
|
+
Traceback (most recent call last):
|
|
372
|
+
...
|
|
373
|
+
ValueError: cannot invert non-unit
|
|
374
|
+
"""
|
|
375
|
+
cdef FMElement ans = self._new_c()
|
|
376
|
+
cdef Integer right = Integer(_right)
|
|
377
|
+
if right < 0:
|
|
378
|
+
self = ~self
|
|
379
|
+
mpz_neg(right.value, right.value)
|
|
380
|
+
cpow(ans.value, self.value, right.value, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
381
|
+
return ans
|
|
382
|
+
|
|
383
|
+
cdef pAdicTemplateElement _lshift_c(self, long shift):
|
|
384
|
+
r"""
|
|
385
|
+
Multiply ``self`` by `\pi^{shift}`.
|
|
386
|
+
|
|
387
|
+
If shift < -self.valuation(), digits will be truncated. See
|
|
388
|
+
:meth:`__rshift__` for details.
|
|
389
|
+
|
|
390
|
+
EXAMPLES:
|
|
391
|
+
|
|
392
|
+
We create a fixed modulus ring::
|
|
393
|
+
|
|
394
|
+
sage: R = ZpFM(5, 20); a = R(1000); a
|
|
395
|
+
3*5^3 + 5^4
|
|
396
|
+
|
|
397
|
+
Shifting to the right is the same as dividing by a power of
|
|
398
|
+
the uniformizer `\pi` of the `p`-adic ring.::
|
|
399
|
+
|
|
400
|
+
sage: a >> 1
|
|
401
|
+
3*5^2 + 5^3
|
|
402
|
+
|
|
403
|
+
Shifting to the left is the same as multiplying by a power of
|
|
404
|
+
`\pi`::
|
|
405
|
+
|
|
406
|
+
sage: a << 2
|
|
407
|
+
3*5^5 + 5^6
|
|
408
|
+
sage: a*5^2
|
|
409
|
+
3*5^5 + 5^6
|
|
410
|
+
|
|
411
|
+
Shifting by a negative integer to the left is the same as
|
|
412
|
+
right shifting by the absolute value::
|
|
413
|
+
|
|
414
|
+
sage: a << -3
|
|
415
|
+
3 + 5
|
|
416
|
+
sage: a >> 3
|
|
417
|
+
3 + 5
|
|
418
|
+
"""
|
|
419
|
+
if shift < 0:
|
|
420
|
+
return self._rshift_c(-shift)
|
|
421
|
+
elif shift == 0:
|
|
422
|
+
return self
|
|
423
|
+
cdef FMElement ans = self._new_c()
|
|
424
|
+
if shift >= self.prime_pow.ram_prec_cap:
|
|
425
|
+
csetzero(ans.value, ans.prime_pow)
|
|
426
|
+
else:
|
|
427
|
+
cshift_notrunc(ans.value, self.value, shift, ans.prime_pow.ram_prec_cap, ans.prime_pow, True)
|
|
428
|
+
return ans
|
|
429
|
+
|
|
430
|
+
cdef pAdicTemplateElement _rshift_c(self, long shift):
|
|
431
|
+
r"""
|
|
432
|
+
Divide by `\pi^{shift}`, and truncate.
|
|
433
|
+
|
|
434
|
+
Note that this operation will insert arbitrary digits (in
|
|
435
|
+
practice, currently all zero) in the least significant digits.
|
|
436
|
+
|
|
437
|
+
EXAMPLES::
|
|
438
|
+
|
|
439
|
+
sage: R = ZpFM(997, 7); a = R(123456878908); a
|
|
440
|
+
964*997 + 572*997^2 + 124*997^3
|
|
441
|
+
|
|
442
|
+
Shifting to the right divides by a power of `\pi`, but
|
|
443
|
+
dropping terms with negative valuation::
|
|
444
|
+
|
|
445
|
+
sage: a >> 3
|
|
446
|
+
124
|
|
447
|
+
|
|
448
|
+
A negative shift multiplies by that power of `\pi`::
|
|
449
|
+
|
|
450
|
+
sage: a >> -3
|
|
451
|
+
964*997^4 + 572*997^5 + 124*997^6
|
|
452
|
+
"""
|
|
453
|
+
if shift < 0:
|
|
454
|
+
return self._lshift_c(-shift)
|
|
455
|
+
elif shift == 0:
|
|
456
|
+
return self
|
|
457
|
+
cdef FMElement ans = self._new_c()
|
|
458
|
+
if shift >= self.prime_pow.ram_prec_cap:
|
|
459
|
+
csetzero(ans.value, ans.prime_pow)
|
|
460
|
+
else:
|
|
461
|
+
cshift(ans.value, ans.prime_pow.shift_rem, self.value, -shift, ans.prime_pow.ram_prec_cap, ans.prime_pow, True)
|
|
462
|
+
return ans
|
|
463
|
+
|
|
464
|
+
def add_bigoh(self, absprec):
|
|
465
|
+
r"""
|
|
466
|
+
Return a new element truncated modulo `\pi^{\mbox{absprec}}`.
|
|
467
|
+
|
|
468
|
+
INPUT:
|
|
469
|
+
|
|
470
|
+
- ``absprec`` -- integer or infinity
|
|
471
|
+
|
|
472
|
+
OUTPUT: a new element truncated modulo `\pi^{\mbox{absprec}}`
|
|
473
|
+
|
|
474
|
+
EXAMPLES::
|
|
475
|
+
|
|
476
|
+
sage: R = Zp(7,4,'fixed-mod','series'); a = R(8); a.add_bigoh(1)
|
|
477
|
+
1
|
|
478
|
+
|
|
479
|
+
TESTS:
|
|
480
|
+
|
|
481
|
+
We handle very large and very small values for ``absprec`` correctly::
|
|
482
|
+
|
|
483
|
+
sage: a = R(7)
|
|
484
|
+
sage: a.add_bigoh(2^1000)
|
|
485
|
+
7
|
|
486
|
+
sage: a.add_bigoh(-2^1000)
|
|
487
|
+
0
|
|
488
|
+
"""
|
|
489
|
+
cdef long aprec
|
|
490
|
+
if absprec is infinity:
|
|
491
|
+
return self
|
|
492
|
+
if isinstance(absprec, int):
|
|
493
|
+
aprec = absprec
|
|
494
|
+
else:
|
|
495
|
+
if not isinstance(absprec, Integer):
|
|
496
|
+
absprec = Integer(absprec)
|
|
497
|
+
if mpz_sgn((<Integer>absprec).value) == -1:
|
|
498
|
+
return self.parent().fraction_field()(0)
|
|
499
|
+
elif mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
500
|
+
return self
|
|
501
|
+
else:
|
|
502
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
503
|
+
if aprec < 0:
|
|
504
|
+
return self.parent().fraction_field()(self, absprec)
|
|
505
|
+
elif aprec >= self.prime_pow.prec_cap:
|
|
506
|
+
return self
|
|
507
|
+
cdef FMElement ans = self._new_c()
|
|
508
|
+
creduce(ans.value, self.value, aprec, ans.prime_pow)
|
|
509
|
+
return ans
|
|
510
|
+
|
|
511
|
+
cpdef bint _is_exact_zero(self) except -1:
|
|
512
|
+
"""
|
|
513
|
+
Test whether this element is an exact zero, which is always
|
|
514
|
+
False for fixed modulus elements.
|
|
515
|
+
|
|
516
|
+
EXAMPLES::
|
|
517
|
+
|
|
518
|
+
sage: R = Zp(7,4,'fixed-mod','series'); a = R(8); a._is_exact_zero()
|
|
519
|
+
False
|
|
520
|
+
"""
|
|
521
|
+
return False
|
|
522
|
+
|
|
523
|
+
cpdef bint _is_inexact_zero(self) except -1:
|
|
524
|
+
"""
|
|
525
|
+
Return ``True`` if ``self`` is indistinguishable from zero.
|
|
526
|
+
|
|
527
|
+
EXAMPLES::
|
|
528
|
+
|
|
529
|
+
sage: R = ZpFM(7, 5)
|
|
530
|
+
sage: R(14)._is_inexact_zero()
|
|
531
|
+
False
|
|
532
|
+
sage: R(0)._is_inexact_zero()
|
|
533
|
+
True
|
|
534
|
+
"""
|
|
535
|
+
return ciszero(self.value, self.prime_pow)
|
|
536
|
+
|
|
537
|
+
def is_zero(self, absprec=None):
|
|
538
|
+
r"""
|
|
539
|
+
Return whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`.
|
|
540
|
+
|
|
541
|
+
INPUT:
|
|
542
|
+
|
|
543
|
+
- ``absprec`` -- integer
|
|
544
|
+
|
|
545
|
+
EXAMPLES::
|
|
546
|
+
|
|
547
|
+
sage: R = ZpFM(17, 6)
|
|
548
|
+
sage: R(0).is_zero()
|
|
549
|
+
True
|
|
550
|
+
sage: R(17^6).is_zero()
|
|
551
|
+
True
|
|
552
|
+
sage: R(17^2).is_zero(absprec=2)
|
|
553
|
+
True
|
|
554
|
+
"""
|
|
555
|
+
cdef bint iszero = ciszero(self.value, self.prime_pow)
|
|
556
|
+
if absprec is None:
|
|
557
|
+
return iszero
|
|
558
|
+
if not isinstance(absprec, Integer):
|
|
559
|
+
absprec = Integer(absprec)
|
|
560
|
+
if mpz_cmp_si((<Integer>absprec).value, self.prime_pow.ram_prec_cap) >= 0:
|
|
561
|
+
return iszero
|
|
562
|
+
cdef long val = self.valuation_c()
|
|
563
|
+
return mpz_cmp_si((<Integer>absprec).value, val) <= 0
|
|
564
|
+
|
|
565
|
+
def __bool__(self):
|
|
566
|
+
"""
|
|
567
|
+
Return ``True`` if this element is distinguishable from zero.
|
|
568
|
+
|
|
569
|
+
For most applications, explicitly specifying the power of p
|
|
570
|
+
modulo which the element is supposed to be nonzero is preferable.
|
|
571
|
+
|
|
572
|
+
EXAMPLES::
|
|
573
|
+
|
|
574
|
+
sage: R = ZpFM(5); a = R(0); b = R(75)
|
|
575
|
+
sage: bool(a), bool(b) # indirect doctest
|
|
576
|
+
(False, True)
|
|
577
|
+
"""
|
|
578
|
+
return not ciszero(self.value, self.prime_pow)
|
|
579
|
+
|
|
580
|
+
def is_equal_to(self, _right, absprec=None):
|
|
581
|
+
r"""
|
|
582
|
+
Return whether this element is equal to ``right`` modulo `p^{\mbox{absprec}}`.
|
|
583
|
+
|
|
584
|
+
If ``absprec`` is ``None``, returns if ``self == 0``.
|
|
585
|
+
|
|
586
|
+
INPUT:
|
|
587
|
+
|
|
588
|
+
- ``right`` -- a `p`-adic element with the same parent
|
|
589
|
+
- ``absprec`` -- positive integer or ``None`` (default: ``None``)
|
|
590
|
+
|
|
591
|
+
EXAMPLES::
|
|
592
|
+
|
|
593
|
+
sage: R = ZpFM(2, 6)
|
|
594
|
+
sage: R(13).is_equal_to(R(13))
|
|
595
|
+
True
|
|
596
|
+
sage: R(13).is_equal_to(R(13+2^10))
|
|
597
|
+
True
|
|
598
|
+
sage: R(13).is_equal_to(R(17), 2)
|
|
599
|
+
True
|
|
600
|
+
sage: R(13).is_equal_to(R(17), 5)
|
|
601
|
+
False
|
|
602
|
+
"""
|
|
603
|
+
cdef FMElement right
|
|
604
|
+
cdef long aprec, rprec, sval, rval
|
|
605
|
+
if self.parent() is _right.parent():
|
|
606
|
+
right = _right
|
|
607
|
+
else:
|
|
608
|
+
right = self.parent()(_right)
|
|
609
|
+
if absprec is None:
|
|
610
|
+
# The default absolute precision is given by the precision cap
|
|
611
|
+
aprec = self.prime_pow.ram_prec_cap
|
|
612
|
+
else:
|
|
613
|
+
if not isinstance(absprec, Integer):
|
|
614
|
+
absprec = Integer(absprec)
|
|
615
|
+
# If absprec is not positive, then self and right are always
|
|
616
|
+
# equal.
|
|
617
|
+
if mpz_sgn((<Integer>absprec).value) < 0:
|
|
618
|
+
return True
|
|
619
|
+
# If absprec is bigger than the precision cap, we use it
|
|
620
|
+
# instead.
|
|
621
|
+
if mpz_cmp_si((<Integer>absprec).value, self.prime_pow.ram_prec_cap) >= 0:
|
|
622
|
+
aprec = self.prime_pow.ram_prec_cap
|
|
623
|
+
else:
|
|
624
|
+
aprec = mpz_get_si((<Integer>absprec).value)
|
|
625
|
+
return ccmp(self.value,
|
|
626
|
+
right.value,
|
|
627
|
+
aprec,
|
|
628
|
+
aprec < self.prime_pow.ram_prec_cap,
|
|
629
|
+
aprec < right.prime_pow.ram_prec_cap,
|
|
630
|
+
self.prime_pow) == 0
|
|
631
|
+
|
|
632
|
+
cdef int _cmp_units(self, pAdicGenericElement _right) except -2:
|
|
633
|
+
"""
|
|
634
|
+
Comparison of units, used in equality testing.
|
|
635
|
+
|
|
636
|
+
EXAMPLES::
|
|
637
|
+
|
|
638
|
+
sage: R = ZpFM(5)
|
|
639
|
+
sage: a = R(17); b = R(0,3); c = R(85,7); d = R(2, 1)
|
|
640
|
+
sage: any([a == b, a == c, b == c, b == d, c == d, a == d]) # indirect doctest
|
|
641
|
+
False
|
|
642
|
+
sage: all([a == a, b == b, c == c, d == d])
|
|
643
|
+
True
|
|
644
|
+
"""
|
|
645
|
+
cdef FMElement right = _right
|
|
646
|
+
return ccmp(self.value, right.value, self.prime_pow.ram_prec_cap, False, False, self.prime_pow)
|
|
647
|
+
|
|
648
|
+
cdef pAdicTemplateElement lift_to_precision_c(self, long absprec):
|
|
649
|
+
"""
|
|
650
|
+
Lifts this element to another with precision at least absprec.
|
|
651
|
+
|
|
652
|
+
Since fixed modulus elements don't track precision, this
|
|
653
|
+
function just returns the same element.
|
|
654
|
+
|
|
655
|
+
EXAMPLES::
|
|
656
|
+
|
|
657
|
+
sage: R = ZpFM(5)
|
|
658
|
+
sage: a = R(77, 2); a
|
|
659
|
+
2 + 3*5^2
|
|
660
|
+
sage: a.lift_to_precision(17) # indirect doctest
|
|
661
|
+
2 + 3*5^2
|
|
662
|
+
"""
|
|
663
|
+
return self
|
|
664
|
+
|
|
665
|
+
def _teichmuller_set_unsafe(self):
|
|
666
|
+
"""
|
|
667
|
+
Set this element to the Teichmuller representative with the
|
|
668
|
+
same residue.
|
|
669
|
+
|
|
670
|
+
.. WARNING::
|
|
671
|
+
|
|
672
|
+
This function modifies the element, which is not safe.
|
|
673
|
+
Elements are supposed to be immutable.
|
|
674
|
+
|
|
675
|
+
EXAMPLES::
|
|
676
|
+
|
|
677
|
+
sage: R = ZpFM(17,5); a = R(11)
|
|
678
|
+
sage: a
|
|
679
|
+
11
|
|
680
|
+
sage: a._teichmuller_set_unsafe(); a
|
|
681
|
+
11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4
|
|
682
|
+
sage: E = a.expansion(lift_mode='teichmuller'); E
|
|
683
|
+
17-adic expansion of 11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4 (teichmuller)
|
|
684
|
+
sage: list(E)
|
|
685
|
+
[11 + 14*17 + 2*17^2 + 12*17^3 + 15*17^4, 0, 0, 0, 0]
|
|
686
|
+
|
|
687
|
+
Note that if you set an element which is congruent to 0 you
|
|
688
|
+
get 0 to maximum precision::
|
|
689
|
+
|
|
690
|
+
sage: b = R(17*5); b
|
|
691
|
+
5*17
|
|
692
|
+
sage: b._teichmuller_set_unsafe(); b
|
|
693
|
+
0
|
|
694
|
+
"""
|
|
695
|
+
if cisunit(self.value, self.prime_pow):
|
|
696
|
+
cteichmuller(self.value, self.value, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
697
|
+
else:
|
|
698
|
+
csetzero(self.value, self.prime_pow)
|
|
699
|
+
|
|
700
|
+
def _polynomial_list(self, pad=False):
|
|
701
|
+
"""
|
|
702
|
+
Return the coefficient list for a polynomial over the base ring
|
|
703
|
+
yielding this element.
|
|
704
|
+
|
|
705
|
+
INPUT:
|
|
706
|
+
|
|
707
|
+
- ``pad`` -- whether to pad the result with zeros of the appropriate precision
|
|
708
|
+
|
|
709
|
+
EXAMPLES::
|
|
710
|
+
|
|
711
|
+
sage: # needs sage.libs.flint
|
|
712
|
+
sage: R.<x> = ZZ[]
|
|
713
|
+
sage: K.<a> = ZqFM(25)
|
|
714
|
+
sage: W.<w> = K.extension(x^3 - 5)
|
|
715
|
+
sage: (1 + w)._polynomial_list()
|
|
716
|
+
[1, 1]
|
|
717
|
+
sage: (1 + w)._polynomial_list(pad=True)
|
|
718
|
+
[1, 1, 0]
|
|
719
|
+
"""
|
|
720
|
+
R = self.base_ring()
|
|
721
|
+
e = self.parent().relative_e()
|
|
722
|
+
L = ccoefficients(self.value, 0, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
723
|
+
if pad:
|
|
724
|
+
n = self.parent().relative_degree()
|
|
725
|
+
L.extend([R.zero()] * (n - len(L)))
|
|
726
|
+
return L
|
|
727
|
+
|
|
728
|
+
def polynomial(self, var='x'):
|
|
729
|
+
"""
|
|
730
|
+
Return a polynomial over the base ring that yields this element
|
|
731
|
+
when evaluated at the generator of the parent.
|
|
732
|
+
|
|
733
|
+
INPUT:
|
|
734
|
+
|
|
735
|
+
- ``var`` -- string, the variable name for the polynomial
|
|
736
|
+
|
|
737
|
+
EXAMPLES::
|
|
738
|
+
|
|
739
|
+
sage: # needs sage.libs.flint
|
|
740
|
+
sage: R.<a> = ZqFM(5^3)
|
|
741
|
+
sage: a.polynomial()
|
|
742
|
+
x
|
|
743
|
+
sage: a.polynomial(var='y')
|
|
744
|
+
y
|
|
745
|
+
sage: (5*a^2 + 25).polynomial()
|
|
746
|
+
5*x^2 + 5^2
|
|
747
|
+
"""
|
|
748
|
+
R = self.base_ring()
|
|
749
|
+
S = R[var]
|
|
750
|
+
return S(self._polynomial_list())
|
|
751
|
+
|
|
752
|
+
def precision_absolute(self):
|
|
753
|
+
"""
|
|
754
|
+
The absolute precision of this element.
|
|
755
|
+
|
|
756
|
+
EXAMPLES::
|
|
757
|
+
|
|
758
|
+
sage: R = Zp(7,4,'fixed-mod'); a = R(7); a.precision_absolute()
|
|
759
|
+
4
|
|
760
|
+
"""
|
|
761
|
+
cdef Integer ans = Integer.__new__(Integer)
|
|
762
|
+
mpz_set_si(ans.value, self.prime_pow.ram_prec_cap)
|
|
763
|
+
return ans
|
|
764
|
+
|
|
765
|
+
def precision_relative(self):
|
|
766
|
+
r"""
|
|
767
|
+
The relative precision of this element.
|
|
768
|
+
|
|
769
|
+
EXAMPLES::
|
|
770
|
+
|
|
771
|
+
sage: R = Zp(7,4,'fixed-mod'); a = R(7); a.precision_relative()
|
|
772
|
+
3
|
|
773
|
+
sage: a = R(0); a.precision_relative()
|
|
774
|
+
0
|
|
775
|
+
"""
|
|
776
|
+
cdef Integer ans = Integer.__new__(Integer)
|
|
777
|
+
mpz_set_si(ans.value, self.prime_pow.ram_prec_cap - self.valuation_c())
|
|
778
|
+
return ans
|
|
779
|
+
|
|
780
|
+
cpdef pAdicTemplateElement unit_part(FMElement self):
|
|
781
|
+
r"""
|
|
782
|
+
Return the unit part of ``self``.
|
|
783
|
+
|
|
784
|
+
If the valuation of ``self`` is positive, then the high digits of the
|
|
785
|
+
result will be zero.
|
|
786
|
+
|
|
787
|
+
EXAMPLES::
|
|
788
|
+
|
|
789
|
+
sage: R = Zp(17, 4, 'fixed-mod')
|
|
790
|
+
sage: R(5).unit_part()
|
|
791
|
+
5
|
|
792
|
+
sage: R(18*17).unit_part()
|
|
793
|
+
1 + 17
|
|
794
|
+
sage: R(0).unit_part()
|
|
795
|
+
0
|
|
796
|
+
sage: type(R(5).unit_part())
|
|
797
|
+
<class 'sage.rings.padics.padic_fixed_mod_element.pAdicFixedModElement'>
|
|
798
|
+
sage: R = ZpFM(5, 5); a = R(75); a.unit_part()
|
|
799
|
+
3
|
|
800
|
+
"""
|
|
801
|
+
cdef FMElement ans = (<FMElement>self)._new_c()
|
|
802
|
+
cremove(ans.value, (<FMElement>self).value, (<FMElement>self).prime_pow.ram_prec_cap, (<FMElement>self).prime_pow)
|
|
803
|
+
return ans
|
|
804
|
+
|
|
805
|
+
cdef long valuation_c(self) noexcept:
|
|
806
|
+
"""
|
|
807
|
+
Return the valuation of this element.
|
|
808
|
+
|
|
809
|
+
TESTS::
|
|
810
|
+
|
|
811
|
+
sage: R = ZpFM(5, 5); R(0).valuation() # indirect doctest
|
|
812
|
+
5
|
|
813
|
+
sage: R = Zp(17, 4,'fixed-mod')
|
|
814
|
+
sage: a = R(2*17^2)
|
|
815
|
+
sage: a.valuation()
|
|
816
|
+
2
|
|
817
|
+
sage: R = Zp(5, 4,'fixed-mod')
|
|
818
|
+
sage: R(0).valuation()
|
|
819
|
+
4
|
|
820
|
+
sage: R(1).valuation()
|
|
821
|
+
0
|
|
822
|
+
sage: R(2).valuation()
|
|
823
|
+
0
|
|
824
|
+
sage: R(5).valuation()
|
|
825
|
+
1
|
|
826
|
+
sage: R(10).valuation()
|
|
827
|
+
1
|
|
828
|
+
sage: R(25).valuation()
|
|
829
|
+
2
|
|
830
|
+
sage: R(50).valuation()
|
|
831
|
+
2
|
|
832
|
+
"""
|
|
833
|
+
# for backward compatibility
|
|
834
|
+
return cvaluation(self.value, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
835
|
+
|
|
836
|
+
cpdef val_unit(self):
|
|
837
|
+
"""
|
|
838
|
+
Return a 2-tuple, the first element set to the valuation of
|
|
839
|
+
``self``, and the second to the unit part of ``self``.
|
|
840
|
+
|
|
841
|
+
If ``self == 0``, then the unit part is ``O(p^self.parent().precision_cap())``.
|
|
842
|
+
|
|
843
|
+
EXAMPLES::
|
|
844
|
+
|
|
845
|
+
sage: R = ZpFM(5,5)
|
|
846
|
+
sage: a = R(75); b = a - a
|
|
847
|
+
sage: a.val_unit()
|
|
848
|
+
(2, 3)
|
|
849
|
+
sage: b.val_unit()
|
|
850
|
+
(5, 0)
|
|
851
|
+
"""
|
|
852
|
+
cdef FMElement unit = self._new_c()
|
|
853
|
+
cdef Integer valuation = Integer.__new__(Integer)
|
|
854
|
+
mpz_set_si(valuation.value, cremove(unit.value, self.value, self.prime_pow.ram_prec_cap, self.prime_pow))
|
|
855
|
+
return valuation, unit
|
|
856
|
+
|
|
857
|
+
def __hash__(self):
|
|
858
|
+
"""
|
|
859
|
+
Hashing.
|
|
860
|
+
|
|
861
|
+
EXAMPLES::
|
|
862
|
+
|
|
863
|
+
sage: R = ZpFM(11, 5)
|
|
864
|
+
sage: hash(R(3)) == hash(3)
|
|
865
|
+
True
|
|
866
|
+
"""
|
|
867
|
+
return chash(self.value, 0, self.prime_pow.ram_prec_cap, self.prime_pow)
|
|
868
|
+
|
|
869
|
+
cdef class pAdicCoercion_ZZ_FM(RingHomomorphism):
|
|
870
|
+
r"""
|
|
871
|
+
The canonical inclusion from `\ZZ` to a fixed modulus ring.
|
|
872
|
+
|
|
873
|
+
EXAMPLES::
|
|
874
|
+
|
|
875
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ); f
|
|
876
|
+
Ring morphism:
|
|
877
|
+
From: Integer Ring
|
|
878
|
+
To: 5-adic Ring of fixed modulus 5^20
|
|
879
|
+
|
|
880
|
+
TESTS::
|
|
881
|
+
|
|
882
|
+
sage: TestSuite(f).run()
|
|
883
|
+
"""
|
|
884
|
+
def __init__(self, R):
|
|
885
|
+
"""
|
|
886
|
+
Initialization.
|
|
887
|
+
|
|
888
|
+
EXAMPLES::
|
|
889
|
+
|
|
890
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ); type(f)
|
|
891
|
+
<class 'sage.rings.padics.padic_fixed_mod_element.pAdicCoercion_ZZ_FM'>
|
|
892
|
+
"""
|
|
893
|
+
RingHomomorphism.__init__(self, ZZ.Hom(R))
|
|
894
|
+
self._zero = R.element_class(R, 0)
|
|
895
|
+
self._section = pAdicConvert_FM_ZZ(R)
|
|
896
|
+
|
|
897
|
+
cdef dict _extra_slots(self):
|
|
898
|
+
"""
|
|
899
|
+
Helper for copying and pickling.
|
|
900
|
+
|
|
901
|
+
EXAMPLES::
|
|
902
|
+
|
|
903
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ)
|
|
904
|
+
sage: g = copy(f) # indirect doctest
|
|
905
|
+
sage: g == f
|
|
906
|
+
True
|
|
907
|
+
sage: g(6)
|
|
908
|
+
1 + 5
|
|
909
|
+
sage: g(6) == f(6)
|
|
910
|
+
True
|
|
911
|
+
"""
|
|
912
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
913
|
+
_slots['_zero'] = self._zero
|
|
914
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
915
|
+
return _slots
|
|
916
|
+
|
|
917
|
+
cdef _update_slots(self, dict _slots):
|
|
918
|
+
"""
|
|
919
|
+
Helper for copying and pickling.
|
|
920
|
+
|
|
921
|
+
EXAMPLES::
|
|
922
|
+
|
|
923
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ)
|
|
924
|
+
sage: g = copy(f) # indirect doctest
|
|
925
|
+
sage: g == f
|
|
926
|
+
True
|
|
927
|
+
sage: g(6)
|
|
928
|
+
1 + 5
|
|
929
|
+
sage: g(6) == f(6)
|
|
930
|
+
True
|
|
931
|
+
"""
|
|
932
|
+
self._zero = _slots['_zero']
|
|
933
|
+
self._section = _slots['_section']
|
|
934
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
935
|
+
|
|
936
|
+
cpdef Element _call_(self, x):
|
|
937
|
+
"""
|
|
938
|
+
Evaluation.
|
|
939
|
+
|
|
940
|
+
EXAMPLES::
|
|
941
|
+
|
|
942
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ)
|
|
943
|
+
sage: f(0).parent()
|
|
944
|
+
5-adic Ring of fixed modulus 5^20
|
|
945
|
+
sage: f(5)
|
|
946
|
+
5
|
|
947
|
+
"""
|
|
948
|
+
if mpz_sgn((<Integer>x).value) == 0:
|
|
949
|
+
return self._zero
|
|
950
|
+
cdef FMElement ans = self._zero._new_c()
|
|
951
|
+
cconv_mpz_t(ans.value, (<Integer>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
|
|
952
|
+
return ans
|
|
953
|
+
|
|
954
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
955
|
+
"""
|
|
956
|
+
This function is used when some precision cap is passed in (relative or absolute or both).
|
|
957
|
+
|
|
958
|
+
INPUT:
|
|
959
|
+
|
|
960
|
+
- ``x`` -- an Integer
|
|
961
|
+
|
|
962
|
+
- ``absprec``, or the first positional argument -- the maximum
|
|
963
|
+
absolute precision (unused for fixed modulus elements)
|
|
964
|
+
|
|
965
|
+
- ``relprec``, or the second positional argument -- the
|
|
966
|
+
maximum relative precision (unused for fixed modulus
|
|
967
|
+
elements)
|
|
968
|
+
|
|
969
|
+
EXAMPLES::
|
|
970
|
+
|
|
971
|
+
sage: R = ZpFM(5,4)
|
|
972
|
+
sage: type(R(10,2))
|
|
973
|
+
<class 'sage.rings.padics.padic_fixed_mod_element.pAdicFixedModElement'>
|
|
974
|
+
sage: R(30,2)
|
|
975
|
+
5 + 5^2
|
|
976
|
+
sage: R(30,3,1)
|
|
977
|
+
5 + 5^2
|
|
978
|
+
sage: R(30,absprec=2)
|
|
979
|
+
5 + 5^2
|
|
980
|
+
sage: R(30,relprec=2)
|
|
981
|
+
5 + 5^2
|
|
982
|
+
sage: R(30,absprec=1)
|
|
983
|
+
5 + 5^2
|
|
984
|
+
sage: R(30,empty=True)
|
|
985
|
+
5 + 5^2
|
|
986
|
+
"""
|
|
987
|
+
if mpz_sgn((<Integer>x).value) == 0:
|
|
988
|
+
return self._zero
|
|
989
|
+
cdef FMElement ans = self._zero._new_c()
|
|
990
|
+
cconv_mpz_t(ans.value, (<Integer>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
|
|
991
|
+
return ans
|
|
992
|
+
|
|
993
|
+
def section(self):
|
|
994
|
+
r"""
|
|
995
|
+
Return a map back to `\ZZ` that approximates an element of this
|
|
996
|
+
`p`-adic ring by an integer.
|
|
997
|
+
|
|
998
|
+
EXAMPLES::
|
|
999
|
+
|
|
1000
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ).section()
|
|
1001
|
+
sage: f(ZpFM(5)(-1)) - 5^20
|
|
1002
|
+
-1
|
|
1003
|
+
"""
|
|
1004
|
+
from sage.misc.constant_function import ConstantFunction
|
|
1005
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
1006
|
+
import copy
|
|
1007
|
+
self._section = copy.copy(self._section)
|
|
1008
|
+
return self._section
|
|
1009
|
+
|
|
1010
|
+
cdef class pAdicConvert_FM_ZZ(RingMap):
|
|
1011
|
+
r"""
|
|
1012
|
+
The map from a fixed modulus ring back to `\ZZ` that returns the smallest
|
|
1013
|
+
nonnegative integer approximation to its input which is accurate up to the precision.
|
|
1014
|
+
|
|
1015
|
+
If the input is not in the closure of the image of `\ZZ`, raises a :exc:`ValueError`.
|
|
1016
|
+
|
|
1017
|
+
EXAMPLES::
|
|
1018
|
+
|
|
1019
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ).section(); f
|
|
1020
|
+
Set-theoretic ring morphism:
|
|
1021
|
+
From: 5-adic Ring of fixed modulus 5^20
|
|
1022
|
+
To: Integer Ring
|
|
1023
|
+
"""
|
|
1024
|
+
def __init__(self, R):
|
|
1025
|
+
"""
|
|
1026
|
+
Initialization.
|
|
1027
|
+
|
|
1028
|
+
EXAMPLES::
|
|
1029
|
+
|
|
1030
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ).section(); type(f)
|
|
1031
|
+
<class 'sage.rings.padics.padic_fixed_mod_element.pAdicConvert_FM_ZZ'>
|
|
1032
|
+
sage: f.category()
|
|
1033
|
+
Category of homsets of sets
|
|
1034
|
+
"""
|
|
1035
|
+
if R.absolute_degree() > 1 or R.characteristic() != 0 or R.residue_characteristic() == 0:
|
|
1036
|
+
RingMap.__init__(self, Hom(R, ZZ, SetsWithPartialMaps()))
|
|
1037
|
+
else:
|
|
1038
|
+
RingMap.__init__(self, Hom(R, ZZ, Sets()))
|
|
1039
|
+
|
|
1040
|
+
cpdef Element _call_(self, _x):
|
|
1041
|
+
"""
|
|
1042
|
+
Evaluation.
|
|
1043
|
+
|
|
1044
|
+
EXAMPLES::
|
|
1045
|
+
|
|
1046
|
+
sage: f = ZpFM(5).coerce_map_from(ZZ).section()
|
|
1047
|
+
sage: f(ZpFM(5)(-1)) - 5^20
|
|
1048
|
+
-1
|
|
1049
|
+
sage: f(ZpFM(5)(0))
|
|
1050
|
+
0
|
|
1051
|
+
"""
|
|
1052
|
+
cdef Integer ans = Integer.__new__(Integer)
|
|
1053
|
+
cdef FMElement x = _x
|
|
1054
|
+
cconv_mpz_t_out(ans.value, x.value, 0, x.prime_pow.ram_prec_cap, x.prime_pow)
|
|
1055
|
+
return ans
|
|
1056
|
+
|
|
1057
|
+
cdef class pAdicConvert_QQ_FM(Morphism):
|
|
1058
|
+
r"""
|
|
1059
|
+
The inclusion map from `\QQ` to a fixed modulus ring that is defined
|
|
1060
|
+
on all elements with nonnegative `p`-adic valuation.
|
|
1061
|
+
|
|
1062
|
+
EXAMPLES::
|
|
1063
|
+
|
|
1064
|
+
sage: f = ZpFM(5).convert_map_from(QQ); f
|
|
1065
|
+
Generic morphism:
|
|
1066
|
+
From: Rational Field
|
|
1067
|
+
To: 5-adic Ring of fixed modulus 5^20
|
|
1068
|
+
"""
|
|
1069
|
+
def __init__(self, R):
|
|
1070
|
+
"""
|
|
1071
|
+
Initialization.
|
|
1072
|
+
|
|
1073
|
+
EXAMPLES::
|
|
1074
|
+
|
|
1075
|
+
sage: f = ZpFM(5).convert_map_from(QQ); type(f)
|
|
1076
|
+
<class 'sage.rings.padics.padic_fixed_mod_element.pAdicConvert_QQ_FM'>
|
|
1077
|
+
"""
|
|
1078
|
+
Morphism.__init__(self, Hom(QQ, R, SetsWithPartialMaps()))
|
|
1079
|
+
self._zero = R.element_class(R, 0)
|
|
1080
|
+
|
|
1081
|
+
cdef dict _extra_slots(self):
|
|
1082
|
+
"""
|
|
1083
|
+
Helper for copying and pickling.
|
|
1084
|
+
|
|
1085
|
+
EXAMPLES::
|
|
1086
|
+
|
|
1087
|
+
sage: f = ZpFM(5).convert_map_from(QQ)
|
|
1088
|
+
sage: g = copy(f) # indirect doctest
|
|
1089
|
+
sage: g == f # todo: comparison not implemented
|
|
1090
|
+
True
|
|
1091
|
+
sage: g(1/6)
|
|
1092
|
+
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
|
|
1093
|
+
sage: g(1/6) == f(1/6)
|
|
1094
|
+
True
|
|
1095
|
+
"""
|
|
1096
|
+
_slots = Morphism._extra_slots(self)
|
|
1097
|
+
_slots['_zero'] = self._zero
|
|
1098
|
+
return _slots
|
|
1099
|
+
|
|
1100
|
+
cdef _update_slots(self, dict _slots):
|
|
1101
|
+
"""
|
|
1102
|
+
Helper for copying and pickling.
|
|
1103
|
+
|
|
1104
|
+
EXAMPLES::
|
|
1105
|
+
|
|
1106
|
+
sage: f = ZpFM(5).convert_map_from(QQ)
|
|
1107
|
+
sage: g = copy(f) # indirect doctest
|
|
1108
|
+
sage: g == f # todo: comparison not implemented
|
|
1109
|
+
True
|
|
1110
|
+
sage: g(1/6)
|
|
1111
|
+
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
|
|
1112
|
+
sage: g(1/6) == f(1/6)
|
|
1113
|
+
True
|
|
1114
|
+
"""
|
|
1115
|
+
self._zero = _slots['_zero']
|
|
1116
|
+
Morphism._update_slots(self, _slots)
|
|
1117
|
+
|
|
1118
|
+
cpdef Element _call_(self, x):
|
|
1119
|
+
"""
|
|
1120
|
+
Evaluation.
|
|
1121
|
+
|
|
1122
|
+
EXAMPLES::
|
|
1123
|
+
|
|
1124
|
+
sage: f = ZpFM(5,4).convert_map_from(QQ)
|
|
1125
|
+
sage: f(1/7)
|
|
1126
|
+
3 + 3*5 + 2*5^3
|
|
1127
|
+
sage: f(0)
|
|
1128
|
+
0
|
|
1129
|
+
"""
|
|
1130
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1131
|
+
return self._zero
|
|
1132
|
+
cdef FMElement ans = self._zero._new_c()
|
|
1133
|
+
cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
|
|
1134
|
+
return ans
|
|
1135
|
+
|
|
1136
|
+
cpdef Element _call_with_args(self, x, args=(), kwds={}):
|
|
1137
|
+
"""
|
|
1138
|
+
This function is used when some precision cap is passed in (relative or absolute or both).
|
|
1139
|
+
|
|
1140
|
+
INPUT:
|
|
1141
|
+
|
|
1142
|
+
- ``x`` -- a Rational
|
|
1143
|
+
|
|
1144
|
+
- ``absprec``, or the first positional argument -- the maximum
|
|
1145
|
+
absolute precision (unused for fixed modulus elements)
|
|
1146
|
+
|
|
1147
|
+
- ``relprec``, or the second positional argument -- the
|
|
1148
|
+
maximum relative precision (unused for fixed modulus
|
|
1149
|
+
elements)
|
|
1150
|
+
|
|
1151
|
+
EXAMPLES::
|
|
1152
|
+
|
|
1153
|
+
sage: R = ZpFM(5,4)
|
|
1154
|
+
sage: type(R(1/7,2))
|
|
1155
|
+
<class 'sage.rings.padics.padic_fixed_mod_element.pAdicFixedModElement'>
|
|
1156
|
+
sage: R(1/7,2)
|
|
1157
|
+
3 + 3*5 + 2*5^3
|
|
1158
|
+
sage: R(1/7,3,1)
|
|
1159
|
+
3 + 3*5 + 2*5^3
|
|
1160
|
+
sage: R(1/7,absprec=2)
|
|
1161
|
+
3 + 3*5 + 2*5^3
|
|
1162
|
+
sage: R(1/7,relprec=2)
|
|
1163
|
+
3 + 3*5 + 2*5^3
|
|
1164
|
+
sage: R(1/7,absprec=1)
|
|
1165
|
+
3 + 3*5 + 2*5^3
|
|
1166
|
+
sage: R(1/7,empty=True)
|
|
1167
|
+
3 + 3*5 + 2*5^3
|
|
1168
|
+
"""
|
|
1169
|
+
if mpq_sgn((<Rational>x).value) == 0:
|
|
1170
|
+
return self._zero
|
|
1171
|
+
cdef FMElement ans = self._zero._new_c()
|
|
1172
|
+
cconv_mpq_t(ans.value, (<Rational>x).value, ans.prime_pow.ram_prec_cap, True, ans.prime_pow)
|
|
1173
|
+
return ans
|
|
1174
|
+
|
|
1175
|
+
cdef class pAdicCoercion_FM_frac_field(RingHomomorphism):
|
|
1176
|
+
r"""
|
|
1177
|
+
The canonical inclusion of `\ZZ_q` into its fraction field.
|
|
1178
|
+
|
|
1179
|
+
EXAMPLES::
|
|
1180
|
+
|
|
1181
|
+
sage: # needs sage.libs.flint
|
|
1182
|
+
sage: R.<a> = ZqFM(27, implementation='FLINT')
|
|
1183
|
+
sage: K = R.fraction_field()
|
|
1184
|
+
sage: f = K.coerce_map_from(R); f
|
|
1185
|
+
Ring morphism:
|
|
1186
|
+
From: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1187
|
+
To: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
1188
|
+
|
|
1189
|
+
TESTS::
|
|
1190
|
+
|
|
1191
|
+
sage: TestSuite(f).run() # needs sage.libs.flint
|
|
1192
|
+
"""
|
|
1193
|
+
def __init__(self, R, K):
|
|
1194
|
+
"""
|
|
1195
|
+
Initialization.
|
|
1196
|
+
|
|
1197
|
+
EXAMPLES::
|
|
1198
|
+
|
|
1199
|
+
sage: # needs sage.libs.flint
|
|
1200
|
+
sage: R.<a> = ZqFM(27)
|
|
1201
|
+
sage: K = R.fraction_field()
|
|
1202
|
+
sage: f = K.coerce_map_from(R); type(f)
|
|
1203
|
+
<class 'sage.rings.padics.qadic_flint_FM.pAdicCoercion_FM_frac_field'>
|
|
1204
|
+
"""
|
|
1205
|
+
RingHomomorphism.__init__(self, R.Hom(K))
|
|
1206
|
+
self._zero = K(0)
|
|
1207
|
+
self._section = pAdicConvert_FM_frac_field(K, R)
|
|
1208
|
+
|
|
1209
|
+
cpdef Element _call_(self, _x):
|
|
1210
|
+
"""
|
|
1211
|
+
Evaluation.
|
|
1212
|
+
|
|
1213
|
+
EXAMPLES::
|
|
1214
|
+
|
|
1215
|
+
sage: # needs sage.libs.flint
|
|
1216
|
+
sage: R.<a> = ZqFM(27)
|
|
1217
|
+
sage: K = R.fraction_field()
|
|
1218
|
+
sage: f = K.coerce_map_from(R)
|
|
1219
|
+
sage: f(a)
|
|
1220
|
+
a
|
|
1221
|
+
"""
|
|
1222
|
+
cdef FMElement x = _x
|
|
1223
|
+
if ciszero(x.value, x.prime_pow):
|
|
1224
|
+
return self._zero
|
|
1225
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1226
|
+
ans.ordp = cremove(ans.unit, x.value, x.prime_pow.ram_prec_cap, x.prime_pow)
|
|
1227
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1228
|
+
# The base ring is wrong, so we fix it.
|
|
1229
|
+
K = ans.unit.base_ring()
|
|
1230
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
1231
|
+
return ans
|
|
1232
|
+
|
|
1233
|
+
cpdef Element _call_with_args(self, _x, args=(), kwds={}):
|
|
1234
|
+
"""
|
|
1235
|
+
This function is used when some precision cap is passed in
|
|
1236
|
+
(relative or absolute or both).
|
|
1237
|
+
|
|
1238
|
+
See the documentation for
|
|
1239
|
+
:meth:`pAdicCappedAbsoluteElement.__init__` for more details.
|
|
1240
|
+
|
|
1241
|
+
EXAMPLES::
|
|
1242
|
+
|
|
1243
|
+
sage: # needs sage.libs.flint
|
|
1244
|
+
sage: R.<a> = ZqFM(27)
|
|
1245
|
+
sage: K = R.fraction_field()
|
|
1246
|
+
sage: f = K.coerce_map_from(R)
|
|
1247
|
+
sage: f(a, 3)
|
|
1248
|
+
a
|
|
1249
|
+
sage: b = 117*a
|
|
1250
|
+
sage: f(b, 3)
|
|
1251
|
+
a*3^2
|
|
1252
|
+
sage: f(b, 4, 1)
|
|
1253
|
+
a*3^2
|
|
1254
|
+
sage: f(b, 4, 3)
|
|
1255
|
+
a*3^2 + a*3^3
|
|
1256
|
+
sage: f(b, absprec=4)
|
|
1257
|
+
a*3^2 + a*3^3
|
|
1258
|
+
sage: f(b, relprec=3)
|
|
1259
|
+
a*3^2 + a*3^3 + a*3^4
|
|
1260
|
+
sage: f(b, absprec=1)
|
|
1261
|
+
0
|
|
1262
|
+
sage: f(R(0))
|
|
1263
|
+
0
|
|
1264
|
+
"""
|
|
1265
|
+
cdef long aprec, rprec
|
|
1266
|
+
cdef FMElement x = _x
|
|
1267
|
+
if ciszero(x.value, x.prime_pow):
|
|
1268
|
+
return self._zero
|
|
1269
|
+
cdef FPElement ans = self._zero._new_c()
|
|
1270
|
+
cdef bint reduce = False
|
|
1271
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, False, x.prime_pow)
|
|
1272
|
+
ans.ordp = cremove(ans.unit, x.value, aprec, x.prime_pow)
|
|
1273
|
+
if aprec < ans.ordp + rprec:
|
|
1274
|
+
rprec = aprec - ans.ordp
|
|
1275
|
+
if rprec <= 0:
|
|
1276
|
+
return self._zero
|
|
1277
|
+
creduce(ans.unit, ans.unit, rprec, x.prime_pow)
|
|
1278
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1279
|
+
# The base ring is wrong, so we fix it.
|
|
1280
|
+
K = ans.unit.base_ring()
|
|
1281
|
+
ans.unit._coeffs = [K(c) for c in ans.unit._coeffs]
|
|
1282
|
+
return ans
|
|
1283
|
+
|
|
1284
|
+
def section(self):
|
|
1285
|
+
"""
|
|
1286
|
+
Return a map back to the ring that converts elements of
|
|
1287
|
+
nonnegative valuation.
|
|
1288
|
+
|
|
1289
|
+
EXAMPLES::
|
|
1290
|
+
|
|
1291
|
+
sage: # needs sage.libs.flint
|
|
1292
|
+
sage: R.<a> = ZqFM(27)
|
|
1293
|
+
sage: K = R.fraction_field()
|
|
1294
|
+
sage: f = K.coerce_map_from(R)
|
|
1295
|
+
sage: f.section()(K.gen())
|
|
1296
|
+
a
|
|
1297
|
+
"""
|
|
1298
|
+
from sage.misc.constant_function import ConstantFunction
|
|
1299
|
+
if not isinstance(self._section.domain, ConstantFunction):
|
|
1300
|
+
import copy
|
|
1301
|
+
self._section = copy.copy(self._section)
|
|
1302
|
+
return self._section
|
|
1303
|
+
|
|
1304
|
+
cdef dict _extra_slots(self):
|
|
1305
|
+
"""
|
|
1306
|
+
Helper for copying and pickling.
|
|
1307
|
+
|
|
1308
|
+
TESTS::
|
|
1309
|
+
|
|
1310
|
+
sage: # needs sage.libs.flint
|
|
1311
|
+
sage: R.<a> = ZqFM(27)
|
|
1312
|
+
sage: K = R.fraction_field()
|
|
1313
|
+
sage: f = K.coerce_map_from(R)
|
|
1314
|
+
sage: g = copy(f) # indirect doctest
|
|
1315
|
+
sage: g
|
|
1316
|
+
Ring morphism:
|
|
1317
|
+
From: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1318
|
+
To: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
1319
|
+
sage: g == f
|
|
1320
|
+
True
|
|
1321
|
+
sage: g is f
|
|
1322
|
+
False
|
|
1323
|
+
sage: g(a)
|
|
1324
|
+
a
|
|
1325
|
+
sage: g(a) == f(a)
|
|
1326
|
+
True
|
|
1327
|
+
"""
|
|
1328
|
+
_slots = RingHomomorphism._extra_slots(self)
|
|
1329
|
+
_slots['_zero'] = self._zero
|
|
1330
|
+
_slots['_section'] = self.section() # use method since it copies coercion-internal sections.
|
|
1331
|
+
return _slots
|
|
1332
|
+
|
|
1333
|
+
cdef _update_slots(self, dict _slots):
|
|
1334
|
+
"""
|
|
1335
|
+
Helper for copying and pickling.
|
|
1336
|
+
|
|
1337
|
+
TESTS::
|
|
1338
|
+
|
|
1339
|
+
sage: # needs sage.libs.flint
|
|
1340
|
+
sage: R.<a> = ZqFM(9)
|
|
1341
|
+
sage: K = R.fraction_field()
|
|
1342
|
+
sage: f = K.coerce_map_from(R)
|
|
1343
|
+
sage: g = copy(f) # indirect doctest
|
|
1344
|
+
sage: g
|
|
1345
|
+
Ring morphism:
|
|
1346
|
+
From: 3-adic Unramified Extension Ring in a defined by x^2 + 2*x + 2
|
|
1347
|
+
To: 3-adic Unramified Extension Field in a defined by x^2 + 2*x + 2
|
|
1348
|
+
sage: g == f
|
|
1349
|
+
True
|
|
1350
|
+
sage: g is f
|
|
1351
|
+
False
|
|
1352
|
+
sage: g(a)
|
|
1353
|
+
a
|
|
1354
|
+
sage: g(a) == f(a)
|
|
1355
|
+
True
|
|
1356
|
+
"""
|
|
1357
|
+
self._zero = _slots['_zero']
|
|
1358
|
+
self._section = _slots['_section']
|
|
1359
|
+
RingHomomorphism._update_slots(self, _slots)
|
|
1360
|
+
|
|
1361
|
+
def is_injective(self):
|
|
1362
|
+
r"""
|
|
1363
|
+
Return whether this map is injective.
|
|
1364
|
+
|
|
1365
|
+
EXAMPLES::
|
|
1366
|
+
|
|
1367
|
+
sage: # needs sage.libs.flint
|
|
1368
|
+
sage: R.<a> = ZqFM(9)
|
|
1369
|
+
sage: K = R.fraction_field()
|
|
1370
|
+
sage: f = K.coerce_map_from(R)
|
|
1371
|
+
sage: f.is_injective()
|
|
1372
|
+
True
|
|
1373
|
+
"""
|
|
1374
|
+
return True
|
|
1375
|
+
|
|
1376
|
+
def is_surjective(self):
|
|
1377
|
+
r"""
|
|
1378
|
+
Return whether this map is surjective.
|
|
1379
|
+
|
|
1380
|
+
EXAMPLES::
|
|
1381
|
+
|
|
1382
|
+
sage: # needs sage.libs.flint
|
|
1383
|
+
sage: R.<a> = ZqFM(9)
|
|
1384
|
+
sage: K = R.fraction_field()
|
|
1385
|
+
sage: f = K.coerce_map_from(R)
|
|
1386
|
+
sage: f.is_surjective()
|
|
1387
|
+
False
|
|
1388
|
+
"""
|
|
1389
|
+
return False
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
cdef class pAdicConvert_FM_frac_field(Morphism):
|
|
1393
|
+
r"""
|
|
1394
|
+
The section of the inclusion from `\ZZ_q` to its fraction field.
|
|
1395
|
+
|
|
1396
|
+
EXAMPLES::
|
|
1397
|
+
|
|
1398
|
+
sage: # needs sage.libs.flint
|
|
1399
|
+
sage: R.<a> = ZqFM(27)
|
|
1400
|
+
sage: K = R.fraction_field()
|
|
1401
|
+
sage: f = R.convert_map_from(K); f
|
|
1402
|
+
Generic morphism:
|
|
1403
|
+
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
1404
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1405
|
+
"""
|
|
1406
|
+
def __init__(self, K, R):
|
|
1407
|
+
"""
|
|
1408
|
+
Initialization.
|
|
1409
|
+
|
|
1410
|
+
EXAMPLES::
|
|
1411
|
+
|
|
1412
|
+
sage: # needs sage.libs.flint
|
|
1413
|
+
sage: R.<a> = ZqFM(27)
|
|
1414
|
+
sage: K = R.fraction_field()
|
|
1415
|
+
sage: f = R.convert_map_from(K); type(f)
|
|
1416
|
+
<class 'sage.rings.padics.qadic_flint_FM.pAdicConvert_FM_frac_field'>
|
|
1417
|
+
"""
|
|
1418
|
+
Morphism.__init__(self, Hom(K, R, SetsWithPartialMaps()))
|
|
1419
|
+
self._zero = R(0)
|
|
1420
|
+
|
|
1421
|
+
cpdef Element _call_(self, _x):
|
|
1422
|
+
"""
|
|
1423
|
+
Evaluation.
|
|
1424
|
+
|
|
1425
|
+
EXAMPLES::
|
|
1426
|
+
|
|
1427
|
+
sage: # needs sage.libs.flint
|
|
1428
|
+
sage: R.<a> = ZqFM(27)
|
|
1429
|
+
sage: K = R.fraction_field()
|
|
1430
|
+
sage: f = R.convert_map_from(K)
|
|
1431
|
+
sage: f(K.gen())
|
|
1432
|
+
a
|
|
1433
|
+
"""
|
|
1434
|
+
cdef FPElement x = _x
|
|
1435
|
+
if x.ordp < 0:
|
|
1436
|
+
raise ValueError("negative valuation")
|
|
1437
|
+
if x.ordp >= self._zero.prime_pow.ram_prec_cap:
|
|
1438
|
+
return self._zero
|
|
1439
|
+
cdef FMElement ans = self._zero._new_c()
|
|
1440
|
+
cshift_notrunc(ans.value, x.unit, x.ordp, ans.prime_pow.ram_prec_cap, ans.prime_pow, x.ordp > 0)
|
|
1441
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1442
|
+
# The base ring is wrong, so we fix it.
|
|
1443
|
+
R = ans.value.base_ring()
|
|
1444
|
+
ans.value._coeffs = [R(c) for c in ans.value._coeffs]
|
|
1445
|
+
return ans
|
|
1446
|
+
|
|
1447
|
+
cpdef Element _call_with_args(self, _x, args=(), kwds={}):
|
|
1448
|
+
"""
|
|
1449
|
+
This function is used when some precision cap is passed in
|
|
1450
|
+
(relative or absolute or both).
|
|
1451
|
+
|
|
1452
|
+
See the documentation for
|
|
1453
|
+
:meth:`pAdicCappedAbsoluteElement.__init__` for more details.
|
|
1454
|
+
|
|
1455
|
+
EXAMPLES::
|
|
1456
|
+
|
|
1457
|
+
sage: # needs sage.libs.flint
|
|
1458
|
+
sage: R.<a> = ZqFM(27)
|
|
1459
|
+
sage: K = R.fraction_field()
|
|
1460
|
+
sage: f = R.convert_map_from(K); a = K(a)
|
|
1461
|
+
sage: f(a, 3)
|
|
1462
|
+
a
|
|
1463
|
+
sage: b = 117*a
|
|
1464
|
+
sage: f(b, 3)
|
|
1465
|
+
a*3^2
|
|
1466
|
+
sage: f(b, 4, 1)
|
|
1467
|
+
a*3^2
|
|
1468
|
+
sage: f(b, 4, 3)
|
|
1469
|
+
a*3^2 + a*3^3
|
|
1470
|
+
sage: f(b, absprec=4)
|
|
1471
|
+
a*3^2 + a*3^3
|
|
1472
|
+
sage: f(b, relprec=3)
|
|
1473
|
+
a*3^2 + a*3^3 + a*3^4
|
|
1474
|
+
sage: f(b, absprec=1)
|
|
1475
|
+
0
|
|
1476
|
+
sage: f(K(0))
|
|
1477
|
+
0
|
|
1478
|
+
"""
|
|
1479
|
+
cdef long aprec, rprec
|
|
1480
|
+
cdef FPElement x = _x
|
|
1481
|
+
if x.ordp < 0:
|
|
1482
|
+
raise ValueError("negative valuation")
|
|
1483
|
+
if x.ordp >= self._zero.prime_pow.ram_prec_cap:
|
|
1484
|
+
return self._zero
|
|
1485
|
+
cdef FMElement ans = self._zero._new_c()
|
|
1486
|
+
_process_args_and_kwds(&aprec, &rprec, args, kwds, True, ans.prime_pow)
|
|
1487
|
+
if rprec < aprec - x.ordp:
|
|
1488
|
+
aprec = x.ordp + rprec
|
|
1489
|
+
cshift_notrunc(ans.value, x.unit, x.ordp, aprec, ans.prime_pow, x.ordp > 0)
|
|
1490
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1491
|
+
# The base ring is wrong, so we fix it.
|
|
1492
|
+
R = ans.value.base_ring()
|
|
1493
|
+
ans.value._coeffs = [R(c) for c in ans.value._coeffs]
|
|
1494
|
+
return ans
|
|
1495
|
+
|
|
1496
|
+
cdef dict _extra_slots(self):
|
|
1497
|
+
"""
|
|
1498
|
+
Helper for copying and pickling.
|
|
1499
|
+
|
|
1500
|
+
TESTS::
|
|
1501
|
+
|
|
1502
|
+
sage: # needs sage.libs.flint
|
|
1503
|
+
sage: R.<a> = ZqFM(27)
|
|
1504
|
+
sage: K = R.fraction_field()
|
|
1505
|
+
sage: f = R.convert_map_from(K)
|
|
1506
|
+
sage: a = K(a)
|
|
1507
|
+
sage: g = copy(f) # indirect doctest
|
|
1508
|
+
sage: g
|
|
1509
|
+
Generic morphism:
|
|
1510
|
+
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
|
|
1511
|
+
To: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
|
|
1512
|
+
sage: g == f
|
|
1513
|
+
True
|
|
1514
|
+
sage: g is f
|
|
1515
|
+
False
|
|
1516
|
+
sage: g(a)
|
|
1517
|
+
a
|
|
1518
|
+
sage: g(a) == f(a)
|
|
1519
|
+
True
|
|
1520
|
+
"""
|
|
1521
|
+
_slots = Morphism._extra_slots(self)
|
|
1522
|
+
_slots['_zero'] = self._zero
|
|
1523
|
+
return _slots
|
|
1524
|
+
|
|
1525
|
+
cdef _update_slots(self, dict _slots):
|
|
1526
|
+
"""
|
|
1527
|
+
Helper for copying and pickling.
|
|
1528
|
+
|
|
1529
|
+
TESTS::
|
|
1530
|
+
|
|
1531
|
+
sage: # needs sage.libs.flint
|
|
1532
|
+
sage: R.<a> = ZqFM(9)
|
|
1533
|
+
sage: K = R.fraction_field()
|
|
1534
|
+
sage: f = R.convert_map_from(K)
|
|
1535
|
+
sage: a = f(a)
|
|
1536
|
+
sage: g = copy(f) # indirect doctest
|
|
1537
|
+
sage: g
|
|
1538
|
+
Generic morphism:
|
|
1539
|
+
From: 3-adic Unramified Extension Field in a defined by x^2 + 2*x + 2
|
|
1540
|
+
To: 3-adic Unramified Extension Ring in a defined by x^2 + 2*x + 2
|
|
1541
|
+
sage: g == f
|
|
1542
|
+
True
|
|
1543
|
+
sage: g is f
|
|
1544
|
+
False
|
|
1545
|
+
sage: g(a)
|
|
1546
|
+
a
|
|
1547
|
+
sage: g(a) == f(a)
|
|
1548
|
+
True
|
|
1549
|
+
"""
|
|
1550
|
+
self._zero = _slots['_zero']
|
|
1551
|
+
Morphism._update_slots(self, _slots)
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
def unpickle_fme_v2(cls, parent, value):
|
|
1555
|
+
"""
|
|
1556
|
+
Unpickles a fixed-mod element.
|
|
1557
|
+
|
|
1558
|
+
EXAMPLES::
|
|
1559
|
+
|
|
1560
|
+
sage: from sage.rings.padics.padic_fixed_mod_element import pAdicFixedModElement, unpickle_fme_v2
|
|
1561
|
+
sage: R = ZpFM(5)
|
|
1562
|
+
sage: a = unpickle_fme_v2(pAdicFixedModElement, R, 17*25); a
|
|
1563
|
+
2*5^2 + 3*5^3
|
|
1564
|
+
sage: a.parent() is R
|
|
1565
|
+
True
|
|
1566
|
+
"""
|
|
1567
|
+
cdef FMElement ans = cls.__new__(cls)
|
|
1568
|
+
ans._parent = parent
|
|
1569
|
+
ans.prime_pow = <PowComputer_?>parent.prime_pow
|
|
1570
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1571
|
+
polyt = type(ans.prime_pow.modulus)
|
|
1572
|
+
ans.value = <celement>polyt.__new__(polyt)
|
|
1573
|
+
cconstruct(ans.value, ans.prime_pow)
|
|
1574
|
+
cunpickle(ans.value, value, ans.prime_pow)
|
|
1575
|
+
return ans
|