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,1212 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
"""
|
|
3
|
+
This file gives a class from which all the `p`-adic templates inherit.
|
|
4
|
+
|
|
5
|
+
This file is included in the various precision template files (such as
|
|
6
|
+
sage/rings/padics/CR_template.pxi). While this choice means that routines here
|
|
7
|
+
do have access to the inlined functions defined in the linkage files, the
|
|
8
|
+
downside is that there will be multiple ``pAdicTemplateElement``
|
|
9
|
+
classes, one for each `p`-adic template.
|
|
10
|
+
|
|
11
|
+
AUTHORS:
|
|
12
|
+
|
|
13
|
+
- David Roe -- initial version (2012-3-1)
|
|
14
|
+
"""
|
|
15
|
+
# ****************************************************************************
|
|
16
|
+
# Copyright (C) 2007-2013 David Roe <roed.math@gmail.com>
|
|
17
|
+
# William Stein <wstein@gmail.com>
|
|
18
|
+
#
|
|
19
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
20
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
21
|
+
# the License, or (at your option) any later version.
|
|
22
|
+
#
|
|
23
|
+
# https://www.gnu.org/licenses/
|
|
24
|
+
# ****************************************************************************
|
|
25
|
+
|
|
26
|
+
from cpython.long cimport *
|
|
27
|
+
|
|
28
|
+
from sage.libs.gmp.all cimport *
|
|
29
|
+
import sage.rings.finite_rings.integer_mod
|
|
30
|
+
from cypari2.types cimport *
|
|
31
|
+
from cypari2.gen cimport Gen as pari_gen
|
|
32
|
+
from sage.libs.pari.convert_gmp cimport INT_to_mpz
|
|
33
|
+
from sage.rings.finite_rings.finite_field_base import FiniteField
|
|
34
|
+
from sage.rings.padics.common_conversion cimport get_ordp, get_preccap
|
|
35
|
+
from sage.rings.integer cimport Integer
|
|
36
|
+
from sage.rings.infinity import infinity
|
|
37
|
+
from sage.rings.rational import Rational
|
|
38
|
+
from sage.rings.padics.precision_error import PrecisionError
|
|
39
|
+
from sage.rings.padics.misc import trim_zeros
|
|
40
|
+
from sage.rings.polynomial.polynomial_element import Polynomial
|
|
41
|
+
from sage.structure.element import canonical_coercion
|
|
42
|
+
|
|
43
|
+
import itertools
|
|
44
|
+
|
|
45
|
+
cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) - 1
|
|
46
|
+
cdef long minusmaxordp = -maxordp
|
|
47
|
+
|
|
48
|
+
cdef inline int check_ordp(long ordp) except -1:
|
|
49
|
+
"""
|
|
50
|
+
Check for overflow after addition or subtraction of valuations.
|
|
51
|
+
|
|
52
|
+
There is another variant, :meth:`check_ordp_mpz`, for ``mpz_t`` input.
|
|
53
|
+
|
|
54
|
+
If overflow is detected, raises a :exc:`OverflowError`.
|
|
55
|
+
"""
|
|
56
|
+
if ordp >= maxordp or ordp <= minusmaxordp:
|
|
57
|
+
raise OverflowError("valuation overflow")
|
|
58
|
+
|
|
59
|
+
cdef class pAdicTemplateElement(pAdicGenericElement):
|
|
60
|
+
"""
|
|
61
|
+
A class for common functionality among the `p`-adic template classes.
|
|
62
|
+
|
|
63
|
+
INPUT:
|
|
64
|
+
|
|
65
|
+
- ``parent`` -- a local ring or field
|
|
66
|
+
|
|
67
|
+
- ``x`` -- data defining this element. Various types are supported,
|
|
68
|
+
including ints, Integers, Rationals, PARI `p`-adics, integers mod `p^k`
|
|
69
|
+
and other Sage `p`-adics.
|
|
70
|
+
|
|
71
|
+
- ``absprec`` -- a cap on the absolute precision of this element
|
|
72
|
+
|
|
73
|
+
- ``relprec`` -- a cap on the relative precision of this element
|
|
74
|
+
|
|
75
|
+
EXAMPLES::
|
|
76
|
+
|
|
77
|
+
sage: Zp(17)(17^3, 8, 4)
|
|
78
|
+
17^3 + O(17^7)
|
|
79
|
+
"""
|
|
80
|
+
def __init__(self, parent, x, absprec=infinity, relprec=infinity):
|
|
81
|
+
"""
|
|
82
|
+
Initialization.
|
|
83
|
+
|
|
84
|
+
.. NOTE::
|
|
85
|
+
|
|
86
|
+
This initialization function is not called for Integers
|
|
87
|
+
and Rationals since a conversion morphism has been
|
|
88
|
+
implemented. It is, however, used for python ints and longs.
|
|
89
|
+
|
|
90
|
+
EXAMPLES::
|
|
91
|
+
|
|
92
|
+
sage: a = Zp(5)(1/2,3); a
|
|
93
|
+
3 + 2*5 + 2*5^2 + O(5^3)
|
|
94
|
+
sage: type(a)
|
|
95
|
+
<class 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'>
|
|
96
|
+
sage: TestSuite(a).run()
|
|
97
|
+
|
|
98
|
+
TESTS::
|
|
99
|
+
|
|
100
|
+
sage: # needs sage.libs.ntl
|
|
101
|
+
sage: QQq.<zz> = Qq(25,4)
|
|
102
|
+
sage: FFp = Zp(5,5).residue_field()
|
|
103
|
+
sage: QQq(FFp.zero())
|
|
104
|
+
O(5)
|
|
105
|
+
sage: QQq(FFp.one())
|
|
106
|
+
1 + O(5)
|
|
107
|
+
sage: QQq(IntegerModRing(25)(15))
|
|
108
|
+
3*5 + O(5^2)
|
|
109
|
+
sage: QQq(IntegerModRing(9)(0))
|
|
110
|
+
Traceback (most recent call last):
|
|
111
|
+
...
|
|
112
|
+
TypeError: p does not divide modulus 9
|
|
113
|
+
|
|
114
|
+
::
|
|
115
|
+
|
|
116
|
+
sage: Zp(2)(Zp(5)(1))
|
|
117
|
+
Traceback (most recent call last):
|
|
118
|
+
...
|
|
119
|
+
TypeError: no conversion between padics when prime numbers differ
|
|
120
|
+
|
|
121
|
+
Check that bug :issue:`28555` is fixed::
|
|
122
|
+
|
|
123
|
+
sage: # needs sage.libs.ntl
|
|
124
|
+
sage: A.<a> = Qq(5^2)
|
|
125
|
+
sage: A.base_ring()(A(1))
|
|
126
|
+
1 + O(5^20)
|
|
127
|
+
sage: A.base_ring()(a)
|
|
128
|
+
Traceback (most recent call last):
|
|
129
|
+
...
|
|
130
|
+
TypeError: element in a proper extension
|
|
131
|
+
|
|
132
|
+
Check that bug :issue:`33527` is fixed::
|
|
133
|
+
|
|
134
|
+
sage: # needs sage.libs.ntl
|
|
135
|
+
sage: K = Qq(25, names='a')
|
|
136
|
+
sage: K0 = K.base_ring()
|
|
137
|
+
sage: K0(K(1))
|
|
138
|
+
1 + O(5^20)
|
|
139
|
+
"""
|
|
140
|
+
self.prime_pow = <PowComputer_?>parent.prime_pow
|
|
141
|
+
pAdicGenericElement.__init__(self, parent)
|
|
142
|
+
cdef long val, xprec
|
|
143
|
+
cdef GEN pari_tmp
|
|
144
|
+
if isinstance(x, int):
|
|
145
|
+
x = Integer(x)
|
|
146
|
+
elif isinstance(x, pari_gen):
|
|
147
|
+
pari_tmp = (<pari_gen>x).g
|
|
148
|
+
if typ(pari_tmp) == t_INT:
|
|
149
|
+
x = PY_NEW(Integer)
|
|
150
|
+
INT_to_mpz((<Integer>x).value, pari_tmp)
|
|
151
|
+
elif typ(pari_tmp) == t_FRAC:
|
|
152
|
+
x = Rational(x)
|
|
153
|
+
elif isinstance(x, pAdicGenericElement):
|
|
154
|
+
if self.prime_pow.prime != x.parent().prime():
|
|
155
|
+
raise TypeError("no conversion between padics when prime numbers differ")
|
|
156
|
+
if not ((<pAdicGenericElement>x)._is_base_elt(self.prime_pow.prime) or x.parent() is self.parent()):
|
|
157
|
+
if x.parent().modulus().change_ring(self.base_ring()) == self.parent().modulus():
|
|
158
|
+
x = x.polynomial().change_ring(self.base_ring()).list()
|
|
159
|
+
else:
|
|
160
|
+
if x.polynomial().degree() >= 1:
|
|
161
|
+
if self.parent() is x.parent().base_ring():
|
|
162
|
+
raise TypeError("element in a proper extension")
|
|
163
|
+
raise NotImplementedError("conversion between different p-adic extensions not implemented")
|
|
164
|
+
x = self.base_ring()(x.polynomial().constant_coefficient())
|
|
165
|
+
if x.is_zero():
|
|
166
|
+
absprec = min(absprec, x.precision_absolute()*self.prime_pow.e)
|
|
167
|
+
x = []
|
|
168
|
+
else:
|
|
169
|
+
x = [x]
|
|
170
|
+
elif isinstance(x, sage.rings.finite_rings.integer_mod.IntegerMod_abstract):
|
|
171
|
+
if not Integer(self.prime_pow.prime).divides(x.parent().order()):
|
|
172
|
+
raise TypeError("p does not divide modulus %s" % x.parent().order())
|
|
173
|
+
elif isinstance(x, Element) and isinstance(x.parent(), FiniteField):
|
|
174
|
+
k = self.parent().residue_field()
|
|
175
|
+
if not k.has_coerce_map_from(x.parent()):
|
|
176
|
+
raise NotImplementedError("conversion from finite fields which do not embed into the residue field not implemented")
|
|
177
|
+
|
|
178
|
+
x = k(x)
|
|
179
|
+
if not k.is_prime_field():
|
|
180
|
+
x = [k.prime_subfield()(c) for c in x.polynomial().list()]
|
|
181
|
+
x = x + [k.prime_subfield().zero()] * (k.degree() - len(x))
|
|
182
|
+
elif isinstance(x, (Integer, Rational, list, tuple)):
|
|
183
|
+
pass
|
|
184
|
+
elif isinstance(x, Polynomial) and x.variable_name() == self.parent().variable_name():
|
|
185
|
+
x = x.list()
|
|
186
|
+
else:
|
|
187
|
+
x = Rational(x)
|
|
188
|
+
val = get_ordp(x, self.prime_pow)
|
|
189
|
+
if val < 0 and self.prime_pow.in_field == 0:
|
|
190
|
+
raise ValueError("negative valuation")
|
|
191
|
+
xprec = get_preccap(x, self.prime_pow)
|
|
192
|
+
self._set(x, val, xprec, absprec, relprec)
|
|
193
|
+
|
|
194
|
+
cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1:
|
|
195
|
+
"""
|
|
196
|
+
Set this element from given data computed in :meth:`__init__`.
|
|
197
|
+
|
|
198
|
+
INPUT:
|
|
199
|
+
|
|
200
|
+
- ``x`` -- an int, Integer, Rational, PARI `p`-adic, integer mod `p^k` or
|
|
201
|
+
Sage `p`-adic
|
|
202
|
+
|
|
203
|
+
- ``val`` -- a long; the valuation of ``x``
|
|
204
|
+
|
|
205
|
+
- ``xprec`` -- a long; the cap on the absolute precision imposed by ``x``
|
|
206
|
+
|
|
207
|
+
- ``absprec`` -- integer or infinity; a bound on the absolute precision
|
|
208
|
+
|
|
209
|
+
- ``relprec`` -- integer or infinity; a bound on the relative precision
|
|
210
|
+
"""
|
|
211
|
+
raise NotImplementedError
|
|
212
|
+
|
|
213
|
+
cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec):
|
|
214
|
+
"""
|
|
215
|
+
Create a new element with a given value and absolute precision.
|
|
216
|
+
|
|
217
|
+
Used by code that doesn't know the precision type.
|
|
218
|
+
"""
|
|
219
|
+
raise NotImplementedError
|
|
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
|
+
raise NotImplementedError
|
|
226
|
+
|
|
227
|
+
def __lshift__(pAdicTemplateElement self, shift):
|
|
228
|
+
"""
|
|
229
|
+
Multiply ``self`` by ``pi^shift``.
|
|
230
|
+
|
|
231
|
+
If ``shift`` is negative and this element does not lie in a field,
|
|
232
|
+
digits may be truncated. See ``__rshift__`` for details.
|
|
233
|
+
|
|
234
|
+
EXAMPLES:
|
|
235
|
+
|
|
236
|
+
We create some `p`-adic rings::
|
|
237
|
+
|
|
238
|
+
sage: R = Zp(5, 20, 'capped-abs'); a = R(1000); a
|
|
239
|
+
3*5^3 + 5^4 + O(5^20)
|
|
240
|
+
sage: S = Zp(5); b = S(1000); b
|
|
241
|
+
3*5^3 + 5^4 + O(5^23)
|
|
242
|
+
|
|
243
|
+
Shifting to the right is the same as dividing by a power of
|
|
244
|
+
the uniformizer `p` of the `p`-adic ring.::
|
|
245
|
+
|
|
246
|
+
sage: a >> 1
|
|
247
|
+
3*5^2 + 5^3 + O(5^19)
|
|
248
|
+
sage: b >> 1
|
|
249
|
+
3*5^2 + 5^3 + O(5^22)
|
|
250
|
+
|
|
251
|
+
Shifting to the left is the same as multiplying by a power of
|
|
252
|
+
`p`::
|
|
253
|
+
|
|
254
|
+
sage: a << 2
|
|
255
|
+
3*5^5 + 5^6 + O(5^20)
|
|
256
|
+
sage: a*5^2
|
|
257
|
+
3*5^5 + 5^6 + O(5^20)
|
|
258
|
+
sage: b << 2
|
|
259
|
+
3*5^5 + 5^6 + O(5^25)
|
|
260
|
+
sage: b*5^2
|
|
261
|
+
3*5^5 + 5^6 + O(5^25)
|
|
262
|
+
|
|
263
|
+
Shifting by a negative integer to the left is the same as
|
|
264
|
+
right shifting by the absolute value::
|
|
265
|
+
|
|
266
|
+
sage: a << -3
|
|
267
|
+
3 + 5 + O(5^17)
|
|
268
|
+
sage: a >> 3
|
|
269
|
+
3 + 5 + O(5^17)
|
|
270
|
+
sage: b << -3
|
|
271
|
+
3 + 5 + O(5^20)
|
|
272
|
+
sage: b >> 3
|
|
273
|
+
3 + 5 + O(5^20)
|
|
274
|
+
"""
|
|
275
|
+
# TODO: move this up the hierarchy, perhaps this should go all the way to element?
|
|
276
|
+
# The "verify that shift is an integer" part could be shared
|
|
277
|
+
cdef long s
|
|
278
|
+
if isinstance(shift, int):
|
|
279
|
+
s = PyLong_AsLong(shift)
|
|
280
|
+
else:
|
|
281
|
+
if not isinstance(shift, Integer):
|
|
282
|
+
shift = Integer(shift)
|
|
283
|
+
if mpz_fits_slong_p((<Integer>shift).value) == 0:
|
|
284
|
+
raise ValueError("valuation overflow")
|
|
285
|
+
s = mpz_get_si((<Integer>shift).value)
|
|
286
|
+
check_ordp(s)
|
|
287
|
+
return self._lshift_c(s)
|
|
288
|
+
|
|
289
|
+
cdef pAdicTemplateElement _lshift_c(self, long shift):
|
|
290
|
+
raise NotImplementedError
|
|
291
|
+
|
|
292
|
+
def __rshift__(pAdicTemplateElement self, shift):
|
|
293
|
+
"""
|
|
294
|
+
Divide by ``p^shift``, and truncate (if the parent is not a field).
|
|
295
|
+
|
|
296
|
+
EXAMPLES::
|
|
297
|
+
|
|
298
|
+
sage: R = Zp(997, 7, 'capped-abs'); a = R(123456878908); a
|
|
299
|
+
964*997 + 572*997^2 + 124*997^3 + O(997^7)
|
|
300
|
+
sage: S = Zp(5); K = Qp(5); b = S(17); b
|
|
301
|
+
2 + 3*5 + O(5^20)
|
|
302
|
+
|
|
303
|
+
Shifting to the right divides by a power of `p`, but drops
|
|
304
|
+
terms with negative valuation::
|
|
305
|
+
|
|
306
|
+
sage: a >> 3
|
|
307
|
+
124 + O(997^4)
|
|
308
|
+
sage: b >> 1
|
|
309
|
+
3 + O(5^19)
|
|
310
|
+
sage: b >> 40
|
|
311
|
+
O(5^0)
|
|
312
|
+
|
|
313
|
+
If the parent is a field no truncation is performed::
|
|
314
|
+
|
|
315
|
+
sage: K(17) >> 1
|
|
316
|
+
2*5^-1 + 3 + O(5^19)
|
|
317
|
+
|
|
318
|
+
A negative shift multiplies by that power of `p`::
|
|
319
|
+
|
|
320
|
+
sage: a >> -3
|
|
321
|
+
964*997^4 + 572*997^5 + 124*997^6 + O(997^7)
|
|
322
|
+
sage: K(17) >> -5
|
|
323
|
+
2*5^5 + 3*5^6 + O(5^25)
|
|
324
|
+
"""
|
|
325
|
+
cdef long s
|
|
326
|
+
if isinstance(shift, int):
|
|
327
|
+
s = PyLong_AsLong(shift)
|
|
328
|
+
else:
|
|
329
|
+
if not isinstance(shift, Integer):
|
|
330
|
+
shift = Integer(shift)
|
|
331
|
+
if mpz_fits_slong_p((<Integer>shift).value) == 0:
|
|
332
|
+
raise ValueError("valuation overflow")
|
|
333
|
+
s = mpz_get_si((<Integer>shift).value)
|
|
334
|
+
check_ordp(s)
|
|
335
|
+
return self._rshift_c(s)
|
|
336
|
+
|
|
337
|
+
cdef pAdicTemplateElement _rshift_c(self, long shift):
|
|
338
|
+
"""
|
|
339
|
+
Divide by ``p^shift`` and truncate (if the parent is not a field).
|
|
340
|
+
"""
|
|
341
|
+
raise NotImplementedError
|
|
342
|
+
|
|
343
|
+
cdef int check_preccap(self) except -1:
|
|
344
|
+
"""
|
|
345
|
+
Check that this element doesn't have precision higher than allowed by
|
|
346
|
+
the precision cap.
|
|
347
|
+
"""
|
|
348
|
+
raise NotImplementedError
|
|
349
|
+
|
|
350
|
+
def lift_to_precision(self, absprec=None):
|
|
351
|
+
r"""
|
|
352
|
+
Return another element of the same parent with absolute precision at
|
|
353
|
+
least ``absprec``, congruent to this `p`-adic element modulo the
|
|
354
|
+
precision of this element.
|
|
355
|
+
|
|
356
|
+
INPUT:
|
|
357
|
+
|
|
358
|
+
- ``absprec`` -- integer or ``None`` (default: ``None``); the
|
|
359
|
+
absolute precision of the result. If ``None``, lifts to the maximum
|
|
360
|
+
precision allowed.
|
|
361
|
+
|
|
362
|
+
.. NOTE::
|
|
363
|
+
|
|
364
|
+
If setting ``absprec`` that high would violate the precision cap,
|
|
365
|
+
raises a precision error. Note that the new digits will not
|
|
366
|
+
necessarily be zero.
|
|
367
|
+
|
|
368
|
+
EXAMPLES::
|
|
369
|
+
|
|
370
|
+
sage: R = ZpCA(17)
|
|
371
|
+
sage: R(-1,2).lift_to_precision(10)
|
|
372
|
+
16 + 16*17 + O(17^10)
|
|
373
|
+
sage: R(1,15).lift_to_precision(10)
|
|
374
|
+
1 + O(17^15)
|
|
375
|
+
sage: R(1,15).lift_to_precision(30)
|
|
376
|
+
Traceback (most recent call last):
|
|
377
|
+
...
|
|
378
|
+
PrecisionError: precision higher than allowed by the precision cap
|
|
379
|
+
sage: R(-1,2).lift_to_precision().precision_absolute() == R.precision_cap()
|
|
380
|
+
True
|
|
381
|
+
|
|
382
|
+
sage: R = Zp(5); c = R(17,3); c.lift_to_precision(8)
|
|
383
|
+
2 + 3*5 + O(5^8)
|
|
384
|
+
sage: c.lift_to_precision().precision_relative() == R.precision_cap()
|
|
385
|
+
True
|
|
386
|
+
|
|
387
|
+
Fixed modulus elements don't raise errors::
|
|
388
|
+
|
|
389
|
+
sage: R = ZpFM(5); a = R(5); a.lift_to_precision(7)
|
|
390
|
+
5
|
|
391
|
+
sage: a.lift_to_precision(10000)
|
|
392
|
+
5
|
|
393
|
+
"""
|
|
394
|
+
if absprec is None:
|
|
395
|
+
absprec = maxordp
|
|
396
|
+
if not isinstance(absprec, Integer):
|
|
397
|
+
absprec = Integer(absprec)
|
|
398
|
+
if mpz_fits_slong_p((<Integer>absprec).value) == 0:
|
|
399
|
+
raise PrecisionError("precision higher than allowed by the precision cap")
|
|
400
|
+
ans = self.lift_to_precision_c(mpz_get_si((<Integer>absprec).value))
|
|
401
|
+
ans.check_preccap()
|
|
402
|
+
return ans
|
|
403
|
+
|
|
404
|
+
cdef pAdicTemplateElement lift_to_precision_c(self, long absprec):
|
|
405
|
+
"""
|
|
406
|
+
Lift this element to another with precision at least ``absprec``.
|
|
407
|
+
"""
|
|
408
|
+
raise NotImplementedError
|
|
409
|
+
|
|
410
|
+
def expansion(self, n=None, lift_mode='simple', start_val=None):
|
|
411
|
+
r"""
|
|
412
|
+
Return the coefficients in a `\pi`-adic expansion.
|
|
413
|
+
If this is a field element, start at
|
|
414
|
+
`\pi^{\mbox{valuation}}`, if a ring element at `\pi^0`.
|
|
415
|
+
|
|
416
|
+
For each lift mode, this function returns a list of `a_i` so
|
|
417
|
+
that this element can be expressed as
|
|
418
|
+
|
|
419
|
+
.. MATH::
|
|
420
|
+
|
|
421
|
+
\pi^v \cdot \sum_{i=0}^\infty a_i \pi^i,
|
|
422
|
+
|
|
423
|
+
where `v` is the valuation of this element when the parent is
|
|
424
|
+
a field, and `v = 0` otherwise.
|
|
425
|
+
|
|
426
|
+
Different lift modes affect the choice of `a_i`. When
|
|
427
|
+
``lift_mode`` is ``'simple'``, the resulting `a_i` will be
|
|
428
|
+
nonnegative: if the residue field is `\GF{p}` then they
|
|
429
|
+
will be integers with `0 \le a_i < p`; otherwise they will be
|
|
430
|
+
a list of integers in the same range giving the coefficients
|
|
431
|
+
of a polynomial in the indeterminant representing the maximal
|
|
432
|
+
unramified subextension.
|
|
433
|
+
|
|
434
|
+
Choosing ``lift_mode`` as ``'smallest'`` is similar to
|
|
435
|
+
``'simple'``, but uses a balanced representation `-p/2 < a_i
|
|
436
|
+
\le p/2`.
|
|
437
|
+
|
|
438
|
+
Finally, setting ``lift_mode = 'teichmuller'`` will yield
|
|
439
|
+
Teichmuller representatives for the `a_i`: `a_i^q = a_i`. In
|
|
440
|
+
this case the `a_i` will lie in the ring of integers of the
|
|
441
|
+
maximal unramified subextension of the parent of this element.
|
|
442
|
+
|
|
443
|
+
INPUT:
|
|
444
|
+
|
|
445
|
+
- ``n`` -- integer (default: ``None``); if given, returns the
|
|
446
|
+
corresponding entry in the expansion. Can also accept a slice (see
|
|
447
|
+
:meth:`slice`).
|
|
448
|
+
|
|
449
|
+
- ``lift_mode`` -- ``'simple'``, ``'smallest'`` or
|
|
450
|
+
``'teichmuller'`` (default: ``'simple'``)
|
|
451
|
+
|
|
452
|
+
- ``start_val`` -- start at this valuation rather than the
|
|
453
|
+
default (`0` or the valuation of this element)
|
|
454
|
+
|
|
455
|
+
OUTPUT:
|
|
456
|
+
|
|
457
|
+
- If ``n`` is ``None``, an iterable giving a `\pi`-adic expansion of this
|
|
458
|
+
element. For base elements the contents will be integers if
|
|
459
|
+
``lift_mode`` is ``'simple'`` or ``'smallest'``, and
|
|
460
|
+
elements of ``self.parent()`` if ``lift_mode`` is
|
|
461
|
+
``'teichmuller'``.
|
|
462
|
+
|
|
463
|
+
- If ``n`` is an integer, the coefficient of `\pi^n` in the
|
|
464
|
+
`\pi`-adic expansion of this element.
|
|
465
|
+
|
|
466
|
+
.. NOTE::
|
|
467
|
+
|
|
468
|
+
Use slice operators to get a particular range.
|
|
469
|
+
|
|
470
|
+
EXAMPLES::
|
|
471
|
+
|
|
472
|
+
sage: R = Zp(7,6); a = R(12837162817); a
|
|
473
|
+
3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6)
|
|
474
|
+
sage: E = a.expansion(); E
|
|
475
|
+
7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6)
|
|
476
|
+
sage: list(E)
|
|
477
|
+
[3, 4, 4, 0, 4, 0]
|
|
478
|
+
sage: sum([c * 7^i for i, c in enumerate(E)]) == a
|
|
479
|
+
True
|
|
480
|
+
sage: E = a.expansion(lift_mode='smallest'); E
|
|
481
|
+
7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) (balanced)
|
|
482
|
+
sage: list(E)
|
|
483
|
+
[3, -3, -2, 1, -3, 1]
|
|
484
|
+
sage: sum([c * 7^i for i, c in enumerate(E)]) == a
|
|
485
|
+
True
|
|
486
|
+
sage: E = a.expansion(lift_mode='teichmuller'); E
|
|
487
|
+
7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) (teichmuller)
|
|
488
|
+
sage: list(E)
|
|
489
|
+
[3 + 4*7 + 6*7^2 + 3*7^3 + 2*7^5 + O(7^6),
|
|
490
|
+
0,
|
|
491
|
+
5 + 2*7 + 3*7^3 + O(7^4),
|
|
492
|
+
1 + O(7^3),
|
|
493
|
+
3 + 4*7 + O(7^2),
|
|
494
|
+
5 + O(7)]
|
|
495
|
+
sage: sum(c * 7^i for i, c in enumerate(E))
|
|
496
|
+
3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6)
|
|
497
|
+
|
|
498
|
+
If the element has positive valuation then the list will start
|
|
499
|
+
with some zeros::
|
|
500
|
+
|
|
501
|
+
sage: a = R(7^3 * 17)
|
|
502
|
+
sage: E = a.expansion(); E
|
|
503
|
+
7-adic expansion of 3*7^3 + 2*7^4 + O(7^9)
|
|
504
|
+
sage: list(E)
|
|
505
|
+
[0, 0, 0, 3, 2, 0, 0, 0, 0]
|
|
506
|
+
|
|
507
|
+
The expansion of 0 is truncated::
|
|
508
|
+
|
|
509
|
+
sage: E = R(0, 7).expansion(); E
|
|
510
|
+
7-adic expansion of O(7^7)
|
|
511
|
+
sage: len(E)
|
|
512
|
+
0
|
|
513
|
+
sage: list(E)
|
|
514
|
+
[]
|
|
515
|
+
|
|
516
|
+
In fields, on the other hand, the expansion starts at the valuation::
|
|
517
|
+
|
|
518
|
+
sage: R = Qp(7,4); a = R(6*7+7**2); E = a.expansion(); E
|
|
519
|
+
7-adic expansion of 6*7 + 7^2 + O(7^5)
|
|
520
|
+
sage: list(E)
|
|
521
|
+
[6, 1, 0, 0]
|
|
522
|
+
sage: list(a.expansion(lift_mode='smallest'))
|
|
523
|
+
[-1, 2, 0, 0]
|
|
524
|
+
sage: list(a.expansion(lift_mode='teichmuller'))
|
|
525
|
+
[6 + 6*7 + 6*7^2 + 6*7^3 + O(7^4),
|
|
526
|
+
2 + 4*7 + 6*7^2 + O(7^3),
|
|
527
|
+
3 + 4*7 + O(7^2),
|
|
528
|
+
3 + O(7)]
|
|
529
|
+
|
|
530
|
+
You can ask for a specific entry in the expansion::
|
|
531
|
+
|
|
532
|
+
sage: a.expansion(1)
|
|
533
|
+
6
|
|
534
|
+
sage: a.expansion(1, lift_mode='smallest')
|
|
535
|
+
-1
|
|
536
|
+
sage: a.expansion(2, lift_mode='teichmuller')
|
|
537
|
+
2 + 4*7 + 6*7^2 + O(7^3)
|
|
538
|
+
|
|
539
|
+
TESTS:
|
|
540
|
+
|
|
541
|
+
Check to see that :issue:`10292` is resolved::
|
|
542
|
+
|
|
543
|
+
sage: # needs database_cremona_mini_ellcurve sage.schemes
|
|
544
|
+
sage: E = EllipticCurve('37a')
|
|
545
|
+
sage: R = E.padic_regulator(7)
|
|
546
|
+
sage: len(R.expansion())
|
|
547
|
+
19
|
|
548
|
+
"""
|
|
549
|
+
if isinstance(n, slice):
|
|
550
|
+
return self.slice(n.start, n.stop, n.step, lift_mode=lift_mode)
|
|
551
|
+
|
|
552
|
+
cdef long shift, prec, val
|
|
553
|
+
cdef expansion_mode mode
|
|
554
|
+
prec = self.precision_relative()
|
|
555
|
+
val = self.valuation_c()
|
|
556
|
+
if prec == 0:
|
|
557
|
+
shift = 0
|
|
558
|
+
elif start_val is not None:
|
|
559
|
+
if n is not None:
|
|
560
|
+
raise ValueError("n and start_val are incompatible options")
|
|
561
|
+
shift = val - start_val
|
|
562
|
+
elif self.prime_pow.in_field:
|
|
563
|
+
shift = 0
|
|
564
|
+
else:
|
|
565
|
+
shift = val
|
|
566
|
+
|
|
567
|
+
if lift_mode == 'simple':
|
|
568
|
+
mode = simple_mode
|
|
569
|
+
elif lift_mode == 'smallest':
|
|
570
|
+
mode = smallest_mode
|
|
571
|
+
elif lift_mode == 'teichmuller':
|
|
572
|
+
mode = teichmuller_mode
|
|
573
|
+
else:
|
|
574
|
+
raise ValueError("unknown lift_mode")
|
|
575
|
+
|
|
576
|
+
cdef ExpansionIterable expansion = ExpansionIterable(self, prec, shift, mode)
|
|
577
|
+
if n is None:
|
|
578
|
+
return expansion
|
|
579
|
+
else:
|
|
580
|
+
if n < val:
|
|
581
|
+
return _zero(mode, expansion.teich_ring)
|
|
582
|
+
elif self.prime_pow.in_field:
|
|
583
|
+
return expansion[n - val]
|
|
584
|
+
else:
|
|
585
|
+
return expansion[n]
|
|
586
|
+
|
|
587
|
+
def teichmuller_expansion(self, n=None):
|
|
588
|
+
r"""
|
|
589
|
+
Return an iterator over coefficients `a_0, a_1, \dots, a_n` such that
|
|
590
|
+
|
|
591
|
+
- `a_i^q = a_i`, where `q` is the cardinality of the residue field,
|
|
592
|
+
|
|
593
|
+
- this element can be expressed as
|
|
594
|
+
|
|
595
|
+
.. MATH::
|
|
596
|
+
|
|
597
|
+
\pi^v \cdot \sum_{i=0}^\infty a_i \pi^i
|
|
598
|
+
|
|
599
|
+
where `v` is the valuation of this element when the parent is
|
|
600
|
+
a field, and `v = 0` otherwise.
|
|
601
|
+
|
|
602
|
+
- if `a_i \ne 0`, the precision of `a_i` is `i` less
|
|
603
|
+
than the precision of this element (relative in the case that
|
|
604
|
+
the parent is a field, absolute otherwise)
|
|
605
|
+
|
|
606
|
+
.. NOTE::
|
|
607
|
+
|
|
608
|
+
The coefficients will lie in the ring of integers of the
|
|
609
|
+
maximal unramified subextension.
|
|
610
|
+
|
|
611
|
+
INPUT:
|
|
612
|
+
|
|
613
|
+
- ``n`` -- integer (default: ``None``); if given, returns the
|
|
614
|
+
coefficient of `\pi^n` in the expansion
|
|
615
|
+
|
|
616
|
+
EXAMPLES:
|
|
617
|
+
|
|
618
|
+
For fields, the expansion starts at the valuation::
|
|
619
|
+
|
|
620
|
+
sage: R = Qp(5,5); list(R(70).teichmuller_expansion())
|
|
621
|
+
[4 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5),
|
|
622
|
+
3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4),
|
|
623
|
+
2 + 5 + 2*5^2 + O(5^3),
|
|
624
|
+
1 + O(5^2),
|
|
625
|
+
4 + O(5)]
|
|
626
|
+
|
|
627
|
+
But if you specify ``n``, you get the coefficient of `\pi^n`::
|
|
628
|
+
|
|
629
|
+
sage: R(70).teichmuller_expansion(2)
|
|
630
|
+
3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)
|
|
631
|
+
"""
|
|
632
|
+
return self.expansion(n, lift_mode='teichmuller')
|
|
633
|
+
|
|
634
|
+
def _ext_p_list(self, pos):
|
|
635
|
+
"""
|
|
636
|
+
Return the `p`-adic expansion of the unit part. Used in printing.
|
|
637
|
+
|
|
638
|
+
EXAMPLES::
|
|
639
|
+
|
|
640
|
+
sage: # needs sage.libs.ntl
|
|
641
|
+
sage: R.<a> = Qq(125)
|
|
642
|
+
sage: b = a^2 + 5*a + 1
|
|
643
|
+
sage: b._ext_p_list(True)
|
|
644
|
+
[[1, 0, 1], [0, 1]]
|
|
645
|
+
"""
|
|
646
|
+
if pos:
|
|
647
|
+
return trim_zeros(list(self.unit_part().expansion(lift_mode='simple')))
|
|
648
|
+
else:
|
|
649
|
+
return trim_zeros(list(self.unit_part().expansion(lift_mode='smallest')))
|
|
650
|
+
|
|
651
|
+
cpdef pAdicTemplateElement unit_part(self):
|
|
652
|
+
r"""
|
|
653
|
+
Return the unit part of this element.
|
|
654
|
+
|
|
655
|
+
This is the `p`-adic element `u` in the same ring so that this
|
|
656
|
+
element is `\pi^v u`, where `\pi` is a uniformizer and `v` is
|
|
657
|
+
the valuation of this element.
|
|
658
|
+
|
|
659
|
+
EXAMPLES::
|
|
660
|
+
|
|
661
|
+
sage: # needs sage.libs.ntl
|
|
662
|
+
sage: R.<a> = Zq(125)
|
|
663
|
+
sage: (5*a).unit_part()
|
|
664
|
+
a + O(5^20)
|
|
665
|
+
"""
|
|
666
|
+
raise NotImplementedError
|
|
667
|
+
|
|
668
|
+
cpdef bint _is_base_elt(self, p) except -1:
|
|
669
|
+
"""
|
|
670
|
+
Return ``True`` if this element is an element of Zp or Qp (rather than
|
|
671
|
+
an extension).
|
|
672
|
+
|
|
673
|
+
INPUT:
|
|
674
|
+
|
|
675
|
+
- ``p`` -- a prime, which is compared with the parent of this element
|
|
676
|
+
|
|
677
|
+
EXAMPLES::
|
|
678
|
+
|
|
679
|
+
sage: a = Zp(5)(3); a._is_base_elt(5)
|
|
680
|
+
True
|
|
681
|
+
sage: a._is_base_elt(17)
|
|
682
|
+
False
|
|
683
|
+
"""
|
|
684
|
+
return self.prime_pow.prime == p and self.prime_pow.deg == 1
|
|
685
|
+
|
|
686
|
+
def _prime_pow(self):
|
|
687
|
+
"""
|
|
688
|
+
Provides access to this element's ``prime_pow``.
|
|
689
|
+
|
|
690
|
+
EXAMPLES::
|
|
691
|
+
|
|
692
|
+
sage: R = ZpCR(5,5)
|
|
693
|
+
sage: R(1)._prime_pow()
|
|
694
|
+
PowComputer for 5
|
|
695
|
+
"""
|
|
696
|
+
return self.prime_pow
|
|
697
|
+
|
|
698
|
+
def residue(self, absprec=1, field=None, check_prec=True):
|
|
699
|
+
r"""
|
|
700
|
+
Reduce this element modulo `p^\mathrm{absprec}`.
|
|
701
|
+
|
|
702
|
+
INPUT:
|
|
703
|
+
|
|
704
|
+
- ``absprec`` -- ``0`` or ``1``
|
|
705
|
+
|
|
706
|
+
- ``field`` -- boolean (default: ``None``); for precision 1, whether to return
|
|
707
|
+
an element of the residue field or a residue ring. Currently unused.
|
|
708
|
+
|
|
709
|
+
- ``check_prec`` -- boolean (default: ``True``); whether to raise an error if this
|
|
710
|
+
element has insufficient precision to determine the reduction. Errors are never
|
|
711
|
+
raised for fixed-mod or floating-point types.
|
|
712
|
+
|
|
713
|
+
OUTPUT:
|
|
714
|
+
|
|
715
|
+
This element reduced modulo `p^\mathrm{absprec}` as an element of the
|
|
716
|
+
residue field or the null ring.
|
|
717
|
+
|
|
718
|
+
EXAMPLES::
|
|
719
|
+
|
|
720
|
+
sage: # needs sage.libs.ntl
|
|
721
|
+
sage: R.<a> = Zq(27, 4)
|
|
722
|
+
sage: (3 + 3*a).residue()
|
|
723
|
+
0
|
|
724
|
+
sage: (a + 1).residue()
|
|
725
|
+
a0 + 1
|
|
726
|
+
|
|
727
|
+
TESTS::
|
|
728
|
+
|
|
729
|
+
sage: # needs sage.libs.ntl
|
|
730
|
+
sage: a.residue(0)
|
|
731
|
+
0
|
|
732
|
+
sage: a.residue(2)
|
|
733
|
+
Traceback (most recent call last):
|
|
734
|
+
...
|
|
735
|
+
NotImplementedError: reduction modulo p^n with n>1
|
|
736
|
+
sage: a.residue(10)
|
|
737
|
+
Traceback (most recent call last):
|
|
738
|
+
...
|
|
739
|
+
PrecisionError: insufficient precision to reduce modulo p^10
|
|
740
|
+
sage: a.residue(10, check_prec=False)
|
|
741
|
+
Traceback (most recent call last):
|
|
742
|
+
...
|
|
743
|
+
NotImplementedError: reduction modulo p^n with n>1
|
|
744
|
+
|
|
745
|
+
sage: # needs sage.libs.flint
|
|
746
|
+
sage: R.<a> = ZqCA(27, 4)
|
|
747
|
+
sage: (3 + 3*a).residue()
|
|
748
|
+
0
|
|
749
|
+
sage: (a + 1).residue()
|
|
750
|
+
a0 + 1
|
|
751
|
+
|
|
752
|
+
sage: # needs sage.libs.ntl
|
|
753
|
+
sage: R.<a> = Qq(27, 4)
|
|
754
|
+
sage: (3 + 3*a).residue()
|
|
755
|
+
0
|
|
756
|
+
sage: (a + 1).residue()
|
|
757
|
+
a0 + 1
|
|
758
|
+
sage: (a/3).residue()
|
|
759
|
+
Traceback (most recent call last):
|
|
760
|
+
...
|
|
761
|
+
ValueError: element must have nonnegative valuation in order to compute residue
|
|
762
|
+
"""
|
|
763
|
+
if absprec < 0:
|
|
764
|
+
raise ValueError("cannot reduce modulo a negative power of the uniformizer")
|
|
765
|
+
if self.valuation() < 0:
|
|
766
|
+
raise ValueError("element must have nonnegative valuation in order to compute residue")
|
|
767
|
+
R = self.parent()
|
|
768
|
+
if check_prec and (R.is_fixed_mod() or R.is_floating_point()):
|
|
769
|
+
check_prec = False
|
|
770
|
+
if check_prec and absprec > self.precision_absolute():
|
|
771
|
+
raise PrecisionError("insufficient precision to reduce modulo p^%s" % absprec)
|
|
772
|
+
if field and absprec != 1:
|
|
773
|
+
raise ValueError("field keyword may only be set at precision 1")
|
|
774
|
+
if absprec == 0:
|
|
775
|
+
from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
|
|
776
|
+
return IntegerModRing(1).zero()
|
|
777
|
+
elif absprec == 1:
|
|
778
|
+
parent = R.residue_field()
|
|
779
|
+
if self.valuation() > 0:
|
|
780
|
+
return parent.zero()
|
|
781
|
+
return parent(self.expansion(0))
|
|
782
|
+
else:
|
|
783
|
+
raise NotImplementedError("reduction modulo p^n with n>1")
|
|
784
|
+
|
|
785
|
+
cdef Integer exact_pow_helper(long *ansrelprec, long relprec, _right, PowComputer_ prime_pow):
|
|
786
|
+
"""
|
|
787
|
+
This function is used by exponentiation in both ``CR_template.pxi``
|
|
788
|
+
and ``CA_template.pxi`` to determine the extra precision gained from
|
|
789
|
+
an exponent of positive valuation. See ``__pow__`` there and in
|
|
790
|
+
``padic_ZZ_pX_CR_element.pyx`` for more details on this phenomenon.
|
|
791
|
+
|
|
792
|
+
INPUT:
|
|
793
|
+
|
|
794
|
+
- ``ansrelprec`` -- (return value) the relative precision of the answer
|
|
795
|
+
|
|
796
|
+
- ``relprec`` -- positive integer: the relative precision of the base
|
|
797
|
+
|
|
798
|
+
- ``_right`` -- the exponent, nonzero
|
|
799
|
+
|
|
800
|
+
- ``prime_pow`` -- the Powcomputer for the ring
|
|
801
|
+
|
|
802
|
+
OUTPUT: an Integer congruent to the given exponent
|
|
803
|
+
"""
|
|
804
|
+
cdef Integer right, p = prime_pow.prime
|
|
805
|
+
cdef long exp_val
|
|
806
|
+
cdef bint isbase
|
|
807
|
+
if isinstance(_right, int):
|
|
808
|
+
_right = Integer(_right)
|
|
809
|
+
if isinstance(_right, Integer):
|
|
810
|
+
right = <Integer> _right
|
|
811
|
+
# Be careful: prime_pow.e is assumed to be the absolute index of ramification!
|
|
812
|
+
exp_val = mpz_get_si((<Integer>(right.valuation(p) * prime_pow.e)).value)
|
|
813
|
+
elif isinstance(_right, Rational):
|
|
814
|
+
raise NotImplementedError
|
|
815
|
+
ansrelprec[0] = relprec + exp_val
|
|
816
|
+
# Over Z_2 or Q_2, the square of an odd number is congruent to 1 mod 8
|
|
817
|
+
if exp_val > 0 and prime_pow.deg == 1 and mpz_cmp_ui(p.value, 2) == 0 and relprec == 1:
|
|
818
|
+
ansrelprec[0] += 1
|
|
819
|
+
|
|
820
|
+
return right
|
|
821
|
+
|
|
822
|
+
cdef long padic_pow_helper(celement result, celement base, long base_val, long base_relprec,
|
|
823
|
+
celement right_unit, long right_val, long right_relprec, PowComputer_ prime_pow) except -1:
|
|
824
|
+
"""
|
|
825
|
+
INPUT:
|
|
826
|
+
|
|
827
|
+
- ``result`` -- the result of exponentiation
|
|
828
|
+
|
|
829
|
+
- ``base`` -- a celement; the base of the exponentiation
|
|
830
|
+
|
|
831
|
+
- ``base_val`` -- a long; used to check that the base is a unit
|
|
832
|
+
|
|
833
|
+
- ``base_relprec`` -- positive integer; the relative precision
|
|
834
|
+
of the base
|
|
835
|
+
|
|
836
|
+
- ``right_unit`` -- the unit part of the exponent
|
|
837
|
+
|
|
838
|
+
- ``right_val`` -- the valuation of the exponent
|
|
839
|
+
|
|
840
|
+
- ``right_relprec`` -- the relative precision of the exponent
|
|
841
|
+
|
|
842
|
+
- ``prime_pow`` -- the Powcomputer for the ring
|
|
843
|
+
|
|
844
|
+
OUTPUT: the precision of the result
|
|
845
|
+
|
|
846
|
+
EXAMPLES::
|
|
847
|
+
|
|
848
|
+
sage: R = Zp(17,print_mode='digits')
|
|
849
|
+
sage: a = R(9283732, 6); b = R(17^3*237, 7)
|
|
850
|
+
sage: str(a)
|
|
851
|
+
'...692AAF'
|
|
852
|
+
sage: str(a^b) # indirect doctest
|
|
853
|
+
'...55GA0001'
|
|
854
|
+
sage: str((a // R.teichmuller(15))^b)
|
|
855
|
+
'...55GA0001'
|
|
856
|
+
sage: str((a.log()*b).exp())
|
|
857
|
+
'...55GA0001'
|
|
858
|
+
"""
|
|
859
|
+
if base_val != 0:
|
|
860
|
+
raise ValueError("in order to raise to a p-adic exponent, base must be a unit")
|
|
861
|
+
# TODO NOTE: this function needs to be updated for extension elements.
|
|
862
|
+
cdef long loga_val, loga_aprec, bloga_val, bloga_aprec
|
|
863
|
+
cdef Integer expcheck, right
|
|
864
|
+
cteichmuller(prime_pow.powhelper_oneunit, base, base_relprec, prime_pow)
|
|
865
|
+
cdivunit(prime_pow.powhelper_oneunit, base, prime_pow.powhelper_oneunit, base_relprec, prime_pow)
|
|
866
|
+
csetone(prime_pow.powhelper_teichdiff, prime_pow)
|
|
867
|
+
csub(prime_pow.powhelper_teichdiff, prime_pow.powhelper_oneunit, prime_pow.powhelper_teichdiff, base_relprec, prime_pow)
|
|
868
|
+
# For extension elements in ramified extensions, the computation of the
|
|
869
|
+
# valuation and precision of log(a) is more complicated)
|
|
870
|
+
loga_val = cvaluation(prime_pow.powhelper_teichdiff, base_relprec, prime_pow)
|
|
871
|
+
loga_aprec = base_relprec
|
|
872
|
+
# valuation of b*log(a)
|
|
873
|
+
bloga_val = loga_val + right_val
|
|
874
|
+
bloga_aprec = bloga_val + min(right_relprec, loga_aprec - loga_val)
|
|
875
|
+
if bloga_aprec > prime_pow.ram_prec_cap:
|
|
876
|
+
bloga_aprec = prime_pow.ram_prec_cap
|
|
877
|
+
expcheck = PY_NEW(Integer)
|
|
878
|
+
mpz_sub_ui(expcheck.value, prime_pow.prime.value, 1)
|
|
879
|
+
mpz_mul_si(expcheck.value, expcheck.value, bloga_val)
|
|
880
|
+
if mpz_cmp_ui(expcheck.value, prime_pow.e) <= 0:
|
|
881
|
+
raise ValueError("exponential does not converge")
|
|
882
|
+
right = PY_NEW(Integer)
|
|
883
|
+
try:
|
|
884
|
+
cconv_mpz_t_out(right.value, right_unit, right_val, right_relprec, prime_pow)
|
|
885
|
+
except ValueError:
|
|
886
|
+
# Here we need to use the exp(b log(a)) definition,
|
|
887
|
+
# since we can't convert the exponent to an integer
|
|
888
|
+
raise NotImplementedError("exponents with negative valuation not yet supported")
|
|
889
|
+
# For extension elements in ramified extensions
|
|
890
|
+
# the following precision might need to be changed.
|
|
891
|
+
cpow(result, prime_pow.powhelper_oneunit, right.value, bloga_aprec, prime_pow)
|
|
892
|
+
return bloga_aprec
|
|
893
|
+
|
|
894
|
+
cdef _zero(expansion_mode mode, teich_ring):
|
|
895
|
+
"""
|
|
896
|
+
Return an appropriate zero for a given expansion mode.
|
|
897
|
+
|
|
898
|
+
INPUT:
|
|
899
|
+
|
|
900
|
+
- ``mode`` -- either ``simple_mode`` or ``smallest_mode`` or ``teichmuller_mode``
|
|
901
|
+
- ``teich_ring`` -- the integer ring of the maximal unramified subextension
|
|
902
|
+
of the parent. Only used in ``teichmuller_mode``.
|
|
903
|
+
"""
|
|
904
|
+
if mode == teichmuller_mode:
|
|
905
|
+
return teich_ring(0)
|
|
906
|
+
else:
|
|
907
|
+
return _expansion_zero
|
|
908
|
+
|
|
909
|
+
cdef class ExpansionIter():
|
|
910
|
+
"""
|
|
911
|
+
An iterator over a `p`-adic expansion.
|
|
912
|
+
|
|
913
|
+
This class should not be instantiated directly, but instead
|
|
914
|
+
using :meth:`expansion`.
|
|
915
|
+
|
|
916
|
+
INPUT:
|
|
917
|
+
|
|
918
|
+
- ``elt`` -- the `p`-adic element
|
|
919
|
+
- ``prec`` -- the number of terms to be emitted
|
|
920
|
+
- ``mode`` -- either ``simple_mode``, ``smallest_mode`` or ``teichmuller_mode``
|
|
921
|
+
|
|
922
|
+
EXAMPLES::
|
|
923
|
+
|
|
924
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
925
|
+
sage: I = iter(E) # indirect doctest
|
|
926
|
+
sage: type(I)
|
|
927
|
+
<class 'sage.rings.padics.padic_capped_relative_element.ExpansionIter'>
|
|
928
|
+
"""
|
|
929
|
+
cdef pAdicTemplateElement elt
|
|
930
|
+
cdef celement tmp
|
|
931
|
+
cdef celement curvalue
|
|
932
|
+
cdef long curpower
|
|
933
|
+
cdef bint tracks_prec
|
|
934
|
+
cdef expansion_mode mode
|
|
935
|
+
cdef object teich_ring
|
|
936
|
+
|
|
937
|
+
def __cinit__(self, pAdicTemplateElement elt, long prec, expansion_mode mode):
|
|
938
|
+
"""
|
|
939
|
+
Allocate memory for the iterator.
|
|
940
|
+
|
|
941
|
+
TESTS::
|
|
942
|
+
|
|
943
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
944
|
+
sage: I = iter(E)
|
|
945
|
+
sage: next(I)
|
|
946
|
+
3
|
|
947
|
+
"""
|
|
948
|
+
self.elt = elt
|
|
949
|
+
self.curpower = prec
|
|
950
|
+
self.mode = mode
|
|
951
|
+
if mode == teichmuller_mode:
|
|
952
|
+
R = elt.parent()
|
|
953
|
+
self.tracks_prec = R.is_capped_relative() or R.is_capped_absolute()
|
|
954
|
+
self.teich_ring = R.maximal_unramified_subextension().integer_ring()
|
|
955
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
956
|
+
polyt = type(elt.prime_pow.modulus)
|
|
957
|
+
self.tmp = <celement>polyt.__new__(polyt)
|
|
958
|
+
self.curvalue = <celement>polyt.__new__(polyt)
|
|
959
|
+
cconstruct(self.tmp, elt.prime_pow)
|
|
960
|
+
cconstruct(self.curvalue, elt.prime_pow)
|
|
961
|
+
elt._get_unit(self.curvalue)
|
|
962
|
+
|
|
963
|
+
def __dealloc__(self):
|
|
964
|
+
"""
|
|
965
|
+
Deallocate memory for the iterator.
|
|
966
|
+
|
|
967
|
+
TESTS::
|
|
968
|
+
|
|
969
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
970
|
+
sage: I = iter(E)
|
|
971
|
+
sage: del I
|
|
972
|
+
"""
|
|
973
|
+
cdestruct(self.tmp, self.elt.prime_pow)
|
|
974
|
+
cdestruct(self.curvalue, self.elt.prime_pow)
|
|
975
|
+
|
|
976
|
+
def __iter__(self):
|
|
977
|
+
"""
|
|
978
|
+
Characteristic property of an iterator: ``__iter__`` returns itself.
|
|
979
|
+
|
|
980
|
+
TESTS::
|
|
981
|
+
|
|
982
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
983
|
+
sage: I = iter(E)
|
|
984
|
+
sage: I is iter(I)
|
|
985
|
+
True
|
|
986
|
+
"""
|
|
987
|
+
return self
|
|
988
|
+
|
|
989
|
+
def __len__(self):
|
|
990
|
+
"""
|
|
991
|
+
Return the number of terms that will be emitted.
|
|
992
|
+
|
|
993
|
+
TESTS::
|
|
994
|
+
|
|
995
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
996
|
+
sage: I = iter(E)
|
|
997
|
+
sage: len(I)
|
|
998
|
+
4
|
|
999
|
+
sage: c = next(I); len(I)
|
|
1000
|
+
3
|
|
1001
|
+
"""
|
|
1002
|
+
return self.curpower
|
|
1003
|
+
|
|
1004
|
+
def __next__(self):
|
|
1005
|
+
"""
|
|
1006
|
+
Provide the next coefficient in the `p`-adic expansion.
|
|
1007
|
+
|
|
1008
|
+
EXAMPLES::
|
|
1009
|
+
|
|
1010
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
1011
|
+
sage: I = iter(E)
|
|
1012
|
+
sage: next(I)
|
|
1013
|
+
3
|
|
1014
|
+
sage: next(I), next(I), next(I)
|
|
1015
|
+
(4, 4, 2)
|
|
1016
|
+
"""
|
|
1017
|
+
if self.curpower <= 0:
|
|
1018
|
+
raise StopIteration
|
|
1019
|
+
self.curpower -= 1
|
|
1020
|
+
cdef pAdicTemplateElement ans
|
|
1021
|
+
cdef PowComputer_ pp = self.elt.prime_pow
|
|
1022
|
+
cdef long prec
|
|
1023
|
+
if ciszero(self.curvalue, pp):
|
|
1024
|
+
return _zero(self.mode, self.teich_ring)
|
|
1025
|
+
if self.mode == teichmuller_mode:
|
|
1026
|
+
prec = self.curpower+1 if self.tracks_prec else pp.ram_prec_cap
|
|
1027
|
+
cteichmuller(self.tmp, self.curvalue, prec, pp)
|
|
1028
|
+
if ciszero(self.tmp, pp):
|
|
1029
|
+
cshift_notrunc(self.curvalue, self.curvalue, -1, prec-1, pp, True)
|
|
1030
|
+
return _zero(teichmuller_mode, self.teich_ring)
|
|
1031
|
+
else:
|
|
1032
|
+
csub(self.curvalue, self.curvalue, self.tmp, prec, pp)
|
|
1033
|
+
cshift_notrunc(self.curvalue, self.curvalue, -1, prec-1, pp, True)
|
|
1034
|
+
return self.teich_ring(self.elt._new_with_value(self.tmp, prec))
|
|
1035
|
+
else:
|
|
1036
|
+
return cexpansion_next(self.curvalue, self.mode, self.curpower, pp)
|
|
1037
|
+
|
|
1038
|
+
cdef class ExpansionIterable():
|
|
1039
|
+
r"""
|
|
1040
|
+
An iterable storing a `p`-adic expansion of an element.
|
|
1041
|
+
|
|
1042
|
+
This class should not be instantiated directly, but instead using :meth:`expansion`.
|
|
1043
|
+
|
|
1044
|
+
INPUT:
|
|
1045
|
+
|
|
1046
|
+
- ``elt`` -- the `p`-adic element
|
|
1047
|
+
- ``prec`` -- the number of terms to be emitted
|
|
1048
|
+
- ``val_shift`` -- how many zeros to add at the beginning of the expansion,
|
|
1049
|
+
or the number of initial terms to truncate (if negative)
|
|
1050
|
+
- ``mode`` -- one of the following:
|
|
1051
|
+
|
|
1052
|
+
* ``'simple_mode'``
|
|
1053
|
+
* ``'smallest_mode'``
|
|
1054
|
+
* ``'teichmuller_mode'``
|
|
1055
|
+
|
|
1056
|
+
EXAMPLES::
|
|
1057
|
+
|
|
1058
|
+
sage: E = Zp(5,4)(373).expansion() # indirect doctest
|
|
1059
|
+
sage: type(E)
|
|
1060
|
+
<class 'sage.rings.padics.padic_capped_relative_element.ExpansionIterable'>
|
|
1061
|
+
"""
|
|
1062
|
+
cdef pAdicTemplateElement elt
|
|
1063
|
+
cdef celement tmp
|
|
1064
|
+
cdef long prec
|
|
1065
|
+
cdef long val_shift
|
|
1066
|
+
cdef expansion_mode mode
|
|
1067
|
+
cdef object teich_ring
|
|
1068
|
+
|
|
1069
|
+
def __cinit__(self, pAdicTemplateElement elt, long prec, long val_shift, expansion_mode mode):
|
|
1070
|
+
"""
|
|
1071
|
+
Allocate memory for the iterable.
|
|
1072
|
+
|
|
1073
|
+
TESTS::
|
|
1074
|
+
|
|
1075
|
+
sage: Zp(5,4)(373).expansion()
|
|
1076
|
+
5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4)
|
|
1077
|
+
"""
|
|
1078
|
+
self.elt = elt
|
|
1079
|
+
IF CELEMENT_IS_PY_OBJECT:
|
|
1080
|
+
polyt = type(elt.prime_pow.modulus)
|
|
1081
|
+
self.tmp = <celement>polyt.__new__(polyt)
|
|
1082
|
+
cconstruct(self.tmp, elt.prime_pow)
|
|
1083
|
+
self.prec = prec
|
|
1084
|
+
self.val_shift = val_shift
|
|
1085
|
+
self.mode = mode
|
|
1086
|
+
if mode == teichmuller_mode:
|
|
1087
|
+
self.teich_ring = elt.parent().maximal_unramified_subextension().integer_ring()
|
|
1088
|
+
|
|
1089
|
+
def __dealloc__(self):
|
|
1090
|
+
"""
|
|
1091
|
+
Deallocate memory for the iterable.
|
|
1092
|
+
|
|
1093
|
+
TESTS::
|
|
1094
|
+
|
|
1095
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
1096
|
+
sage: del E
|
|
1097
|
+
"""
|
|
1098
|
+
cdestruct(self.tmp, self.elt.prime_pow)
|
|
1099
|
+
|
|
1100
|
+
def __iter__(self):
|
|
1101
|
+
"""
|
|
1102
|
+
Return an iterator, based on a corresponding :class:`ExpansionIter`.
|
|
1103
|
+
|
|
1104
|
+
If ``val_shift`` is positive, will first emit that many zeros
|
|
1105
|
+
(of the appropriate type: ``[]`` instead when the inertia degree
|
|
1106
|
+
is larger than one.
|
|
1107
|
+
|
|
1108
|
+
If ``val_shift`` is negative, will truncate that many terms at
|
|
1109
|
+
the start of the expansion.
|
|
1110
|
+
|
|
1111
|
+
EXAMPLES::
|
|
1112
|
+
|
|
1113
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
1114
|
+
sage: type(iter(E))
|
|
1115
|
+
<class 'sage.rings.padics.padic_capped_relative_element.ExpansionIter'>
|
|
1116
|
+
sage: E = Zp(5,4)(373).expansion(start_val=-1)
|
|
1117
|
+
sage: type(iter(E))
|
|
1118
|
+
<class 'itertools.chain'>
|
|
1119
|
+
sage: E = Zp(5,4)(373).expansion(start_val=1)
|
|
1120
|
+
sage: type(iter(E))
|
|
1121
|
+
<class 'itertools.islice'>
|
|
1122
|
+
"""
|
|
1123
|
+
cdef ExpansionIter expansion = ExpansionIter(self.elt, self.prec, self.mode)
|
|
1124
|
+
if self.val_shift == 0:
|
|
1125
|
+
return expansion
|
|
1126
|
+
elif self.val_shift < 0:
|
|
1127
|
+
return itertools.islice(expansion, -self.val_shift, None)
|
|
1128
|
+
else:
|
|
1129
|
+
return itertools.chain(itertools.repeat(_zero(self.mode, self.teich_ring), self.val_shift), expansion)
|
|
1130
|
+
|
|
1131
|
+
def __len__(self):
|
|
1132
|
+
"""
|
|
1133
|
+
Return the number of terms that will be emitted.
|
|
1134
|
+
|
|
1135
|
+
TESTS::
|
|
1136
|
+
|
|
1137
|
+
sage: len(Zp(5,4)(373).expansion())
|
|
1138
|
+
4
|
|
1139
|
+
sage: len(Zp(5,4)(373).expansion(start_val=-1))
|
|
1140
|
+
5
|
|
1141
|
+
sage: len(Zp(5,4)(373).expansion(start_val=1))
|
|
1142
|
+
3
|
|
1143
|
+
sage: len(Zp(5,4)(0).expansion())
|
|
1144
|
+
0
|
|
1145
|
+
"""
|
|
1146
|
+
return self.prec + self.val_shift
|
|
1147
|
+
|
|
1148
|
+
def __getitem__(self, n):
|
|
1149
|
+
"""
|
|
1150
|
+
Return the ``n``-th entry in the expansion.
|
|
1151
|
+
|
|
1152
|
+
Negative indices are not allowed.
|
|
1153
|
+
|
|
1154
|
+
EXAMPLES::
|
|
1155
|
+
|
|
1156
|
+
sage: E = Zp(5,4)(373).expansion()
|
|
1157
|
+
sage: E[0]
|
|
1158
|
+
3
|
|
1159
|
+
sage: E[3]
|
|
1160
|
+
2
|
|
1161
|
+
sage: list(E[::2])
|
|
1162
|
+
[3, 4]
|
|
1163
|
+
sage: a = E[-1]
|
|
1164
|
+
Traceback (most recent call last):
|
|
1165
|
+
...
|
|
1166
|
+
ValueError: negative indices not supported
|
|
1167
|
+
sage: Zp(5,4)(373).expansion(lift_mode='smallest')[3]
|
|
1168
|
+
-2
|
|
1169
|
+
"""
|
|
1170
|
+
if isinstance(n, slice):
|
|
1171
|
+
start = int(n.start) if n.start is not None else None
|
|
1172
|
+
stop = int(n.stop) if n.stop is not None else None
|
|
1173
|
+
step = int(n.step) if n.step is not None else None
|
|
1174
|
+
return itertools.islice(iter(self), start, stop, step)
|
|
1175
|
+
cdef long m = n - self.val_shift
|
|
1176
|
+
cdef celement value
|
|
1177
|
+
if n < 0:
|
|
1178
|
+
raise ValueError("negative indices not supported")
|
|
1179
|
+
elif m < 0:
|
|
1180
|
+
return _zero(self.mode, self.teich_ring)
|
|
1181
|
+
elif m >= self.prec:
|
|
1182
|
+
raise PrecisionError
|
|
1183
|
+
elif self.mode == simple_mode:
|
|
1184
|
+
self.elt._get_unit(self.tmp)
|
|
1185
|
+
return cexpansion_getitem(self.tmp, m, self.elt.prime_pow)
|
|
1186
|
+
else:
|
|
1187
|
+
expansion = ExpansionIter(self.elt, self.prec, self.mode)
|
|
1188
|
+
# We do this in a naive way, though it should be feasible
|
|
1189
|
+
# to implement something better for smallest_mode
|
|
1190
|
+
return next(itertools.islice(expansion, m, m+1))
|
|
1191
|
+
|
|
1192
|
+
def __repr__(self):
|
|
1193
|
+
"""
|
|
1194
|
+
String representation.
|
|
1195
|
+
|
|
1196
|
+
EXAMPLES::
|
|
1197
|
+
|
|
1198
|
+
sage: Zp(5,4)(373).expansion()
|
|
1199
|
+
5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4)
|
|
1200
|
+
sage: Zp(5,4)(373).expansion(lift_mode='smallest')
|
|
1201
|
+
5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4) (balanced)
|
|
1202
|
+
sage: Zp(5,4)(373).expansion(lift_mode='teichmuller')
|
|
1203
|
+
5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4) (teichmuller)
|
|
1204
|
+
"""
|
|
1205
|
+
if self.mode == simple_mode:
|
|
1206
|
+
modestr = ""
|
|
1207
|
+
elif self.mode == smallest_mode:
|
|
1208
|
+
modestr = " (balanced)"
|
|
1209
|
+
else:
|
|
1210
|
+
modestr = " (teichmuller)"
|
|
1211
|
+
p = self.elt.prime_pow.prime
|
|
1212
|
+
return "%s-adic expansion of %s%s" % (p, self.elt, modestr)
|