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,1342 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
r"""
|
|
3
|
+
`p`-adic Elements with lattice precision.
|
|
4
|
+
|
|
5
|
+
AUTHOR:
|
|
6
|
+
|
|
7
|
+
- Xavier Caruso (2018-02): initial version
|
|
8
|
+
|
|
9
|
+
TESTS:
|
|
10
|
+
|
|
11
|
+
We create some rings and run the test suite for them. We skip the Smith form
|
|
12
|
+
tests because they take a few minutes as of mid 2018, see :issue:`25431`::
|
|
13
|
+
|
|
14
|
+
sage: R1 = ZpLC(2)
|
|
15
|
+
doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation.
|
|
16
|
+
See https://github.com/sagemath/sage/issues/23505 for details.
|
|
17
|
+
sage: R2 = ZpLF(2)
|
|
18
|
+
sage: R3 = QpLC(2)
|
|
19
|
+
sage: R4 = QpLF(2)
|
|
20
|
+
|
|
21
|
+
sage: # long time, needs sage.rings.padics
|
|
22
|
+
sage: TestSuite(R1).run(skip=['_test_teichmuller', '_test_matrix_smith'])
|
|
23
|
+
sage: TestSuite(R2).run(skip=['_test_teichmuller', '_test_matrix_smith'])
|
|
24
|
+
sage: TestSuite(R3).run(skip=['_test_teichmuller', '_test_matrix_smith'])
|
|
25
|
+
sage: TestSuite(R4).run(skip=['_test_teichmuller', '_test_matrix_smith'])
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
# ****************************************************************************
|
|
29
|
+
# Copyright (C) 2018 Xavier Caruso <xavier.caruso@normalesup.org>
|
|
30
|
+
#
|
|
31
|
+
# This program is free software: you can redistribute it and/or modify
|
|
32
|
+
# it under the terms of the GNU General Public License as published by
|
|
33
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
34
|
+
# (at your option) any later version.
|
|
35
|
+
# http://www.gnu.org/licenses/
|
|
36
|
+
# ****************************************************************************
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
from sage.misc.abstract_method import abstract_method
|
|
40
|
+
|
|
41
|
+
from sage.rings.integer import Integer
|
|
42
|
+
|
|
43
|
+
from sage.rings.integer_ring import ZZ
|
|
44
|
+
from sage.rings.rational_field import QQ
|
|
45
|
+
from sage.rings.infinity import Infinity
|
|
46
|
+
from sage.structure.richcmp import rich_to_bool, richcmp
|
|
47
|
+
from sage.rings.padics.padic_generic_element import pAdicGenericElement
|
|
48
|
+
from sage.rings.padics.lattice_precision import pRational
|
|
49
|
+
|
|
50
|
+
from sage.rings.padics.precision_error import PrecisionError
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def unpickle_le(parent, value, prec):
|
|
54
|
+
r"""
|
|
55
|
+
Unpickle `p`-adic elements.
|
|
56
|
+
|
|
57
|
+
INPUT:
|
|
58
|
+
|
|
59
|
+
- ``parent`` -- the parent, a `p`-adic ring
|
|
60
|
+
|
|
61
|
+
- ``value`` -- a rational number
|
|
62
|
+
|
|
63
|
+
- ``prec`` -- integer
|
|
64
|
+
|
|
65
|
+
EXAMPLES::
|
|
66
|
+
|
|
67
|
+
sage: from sage.rings.padics.padic_lattice_element import unpickle_le
|
|
68
|
+
sage: R = ZpLC(5,8)
|
|
69
|
+
sage: a = unpickle_le(R, 42, 6); a
|
|
70
|
+
2 + 3*5 + 5^2 + O(5^6)
|
|
71
|
+
sage: a.parent() is R
|
|
72
|
+
True
|
|
73
|
+
"""
|
|
74
|
+
return parent(value, prec)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class pAdicLatticeElement(pAdicGenericElement):
|
|
78
|
+
r"""
|
|
79
|
+
Construct new element with given parent and value.
|
|
80
|
+
|
|
81
|
+
INPUT:
|
|
82
|
+
|
|
83
|
+
- ``parent`` -- the parent of this element
|
|
84
|
+
|
|
85
|
+
- ``x`` -- the newly created element
|
|
86
|
+
|
|
87
|
+
- ``prec`` -- integer; the absolute precision at which this
|
|
88
|
+
element has to be capped
|
|
89
|
+
|
|
90
|
+
- ``dx`` -- dictionary representing the differential of ``x``
|
|
91
|
+
|
|
92
|
+
- ``dx_mode`` -- string; either ``'linear_combination'`` (the default)
|
|
93
|
+
or ``'values'``
|
|
94
|
+
|
|
95
|
+
- ``valuation`` -- integer or ``None`` (default: ``None``);
|
|
96
|
+
the valuation of this element
|
|
97
|
+
|
|
98
|
+
- ``check`` -- boolean (default: ``True``); whether the function
|
|
99
|
+
should check that the given values are well formed and coherent
|
|
100
|
+
|
|
101
|
+
- ``reduce`` -- boolean (default: ``True``); whether the given
|
|
102
|
+
values need to be reduced
|
|
103
|
+
|
|
104
|
+
TESTS::
|
|
105
|
+
|
|
106
|
+
sage: R = ZpLC(2)
|
|
107
|
+
sage: x = R(1, 10) # indirect doctest
|
|
108
|
+
sage: x
|
|
109
|
+
1 + O(2^10)
|
|
110
|
+
"""
|
|
111
|
+
def __init__(self, parent, x, prec=None, dx=[], dx_mode='linear_combination', valuation=None, check=True, reduce=True):
|
|
112
|
+
r"""
|
|
113
|
+
TESTS::
|
|
114
|
+
|
|
115
|
+
sage: R = ZpLC(2)
|
|
116
|
+
sage: x = R(1, 10) # indirect doctest
|
|
117
|
+
sage: x
|
|
118
|
+
1 + O(2^10)
|
|
119
|
+
"""
|
|
120
|
+
self._parent = parent
|
|
121
|
+
p = parent.prime()
|
|
122
|
+
pAdicGenericElement.__init__(self, parent)
|
|
123
|
+
self._precision = parent.precision()
|
|
124
|
+
if check:
|
|
125
|
+
if isinstance(x, pAdicGenericElement):
|
|
126
|
+
if parent.prime() != x.parent().prime():
|
|
127
|
+
raise TypeError("conversion between different p-adic rings/fields not supported")
|
|
128
|
+
if prec is None:
|
|
129
|
+
prec = x.precision_absolute()
|
|
130
|
+
else:
|
|
131
|
+
prec = min(prec, x.precision_absolute())
|
|
132
|
+
x = QQ(x)
|
|
133
|
+
if isinstance(x, pRational):
|
|
134
|
+
self._value = x
|
|
135
|
+
else:
|
|
136
|
+
self._value = pRational(p, QQ(x))
|
|
137
|
+
trunc = self._declare_new_element(dx, prec, dx_mode)
|
|
138
|
+
if reduce:
|
|
139
|
+
self._value = self._value.reduce(trunc)
|
|
140
|
+
|
|
141
|
+
@abstract_method
|
|
142
|
+
def _declare_new_element(self, dx, prec, dx_mode):
|
|
143
|
+
r"""
|
|
144
|
+
Declare this element to the precision object and
|
|
145
|
+
return the precision at which this element can be truncated safely.
|
|
146
|
+
|
|
147
|
+
Only for internal use.
|
|
148
|
+
|
|
149
|
+
TESTS::
|
|
150
|
+
|
|
151
|
+
sage: R = ZpLC(17)
|
|
152
|
+
sage: prec = R.precision()
|
|
153
|
+
|
|
154
|
+
sage: prec.del_elements()
|
|
155
|
+
sage: nb = len(prec.tracked_elements())
|
|
156
|
+
sage: x = R(1, 10) # indirect doctest
|
|
157
|
+
sage: len(prec.tracked_elements()) == nb + 1
|
|
158
|
+
True
|
|
159
|
+
"""
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
def _cache_key(self):
|
|
163
|
+
r"""
|
|
164
|
+
Return a hash of this element.
|
|
165
|
+
|
|
166
|
+
TESTS::
|
|
167
|
+
|
|
168
|
+
sage: R = ZpLC(2)
|
|
169
|
+
sage: x = R(1, 10)
|
|
170
|
+
sage: x._cache_key() # random
|
|
171
|
+
140533063823184
|
|
172
|
+
"""
|
|
173
|
+
return id(self)
|
|
174
|
+
|
|
175
|
+
def __reduce__(self):
|
|
176
|
+
r"""
|
|
177
|
+
Return a tuple of a function and data that can be used to unpickle this
|
|
178
|
+
element.
|
|
179
|
+
|
|
180
|
+
EXAMPLES::
|
|
181
|
+
|
|
182
|
+
sage: R = ZpLC(5)
|
|
183
|
+
sage: a = R(-3)
|
|
184
|
+
sage: loads(dumps(a)) == a
|
|
185
|
+
True
|
|
186
|
+
|
|
187
|
+
For now, diffused digits of precision are not preserved by pickling::
|
|
188
|
+
|
|
189
|
+
sage: x, y = R(1, 10), R(1, 5)
|
|
190
|
+
sage: u, v = x+y, x-y
|
|
191
|
+
sage: u + v
|
|
192
|
+
2 + O(5^10)
|
|
193
|
+
|
|
194
|
+
sage: up = loads(dumps(u))
|
|
195
|
+
sage: vp = loads(dumps(v))
|
|
196
|
+
sage: up + vp
|
|
197
|
+
2 + O(5^5)
|
|
198
|
+
"""
|
|
199
|
+
return unpickle_le, (self.parent(), self.value(), self.precision_absolute())
|
|
200
|
+
|
|
201
|
+
def _is_base_elt(self, p):
|
|
202
|
+
r"""
|
|
203
|
+
Return ``True`` if this element is an element of Zp or Qp (rather than
|
|
204
|
+
an extension).
|
|
205
|
+
|
|
206
|
+
INPUT:
|
|
207
|
+
|
|
208
|
+
- ``p`` -- a prime, which is compared with the parent of this element
|
|
209
|
+
|
|
210
|
+
EXAMPLES::
|
|
211
|
+
|
|
212
|
+
sage: K = QpLC(7)
|
|
213
|
+
sage: K.random_element()._is_base_elt(7) # not tested, known bug (see :issue:`32126`)
|
|
214
|
+
True
|
|
215
|
+
"""
|
|
216
|
+
return p == self._parent.prime()
|
|
217
|
+
|
|
218
|
+
def approximation(self):
|
|
219
|
+
r"""
|
|
220
|
+
Return an approximation of this element at
|
|
221
|
+
its absolute precision.
|
|
222
|
+
|
|
223
|
+
EXAMPLES::
|
|
224
|
+
|
|
225
|
+
sage: R = ZpLC(2, print_mode='terse')
|
|
226
|
+
sage: x = R(1234, 10); x
|
|
227
|
+
210 + O(2^10)
|
|
228
|
+
sage: x.approximation()
|
|
229
|
+
210
|
|
230
|
+
"""
|
|
231
|
+
prec = self.precision_absolute()
|
|
232
|
+
app = self._value.reduce(prec)
|
|
233
|
+
return app.value()
|
|
234
|
+
|
|
235
|
+
def value(self):
|
|
236
|
+
r"""
|
|
237
|
+
Return the actual approximation of this element
|
|
238
|
+
stored in memory.
|
|
239
|
+
In presence of diffused digits of precision, it can
|
|
240
|
+
have more precision than the absolute precision of
|
|
241
|
+
the element.
|
|
242
|
+
|
|
243
|
+
EXAMPLES::
|
|
244
|
+
|
|
245
|
+
sage: R = ZpLC(2, print_mode='terse')
|
|
246
|
+
sage: x = R(1234, 10); x
|
|
247
|
+
210 + O(2^10)
|
|
248
|
+
sage: x.approximation()
|
|
249
|
+
210
|
|
250
|
+
|
|
251
|
+
Another example with diffused digits::
|
|
252
|
+
|
|
253
|
+
sage: x = R(2, 10); y = R(7, 5)
|
|
254
|
+
sage: u = x - y
|
|
255
|
+
sage: u
|
|
256
|
+
27 + O(2^5)
|
|
257
|
+
sage: u.value()
|
|
258
|
+
1048571
|
|
259
|
+
"""
|
|
260
|
+
return self._value.value()
|
|
261
|
+
|
|
262
|
+
def residue(self, absprec=1, field=None, check_prec=True):
|
|
263
|
+
r"""
|
|
264
|
+
Reduces this element modulo `p^{\mathrm{absprec}}`.
|
|
265
|
+
|
|
266
|
+
INPUT:
|
|
267
|
+
|
|
268
|
+
- ``absprec`` -- nonnegative integer (default: 1)
|
|
269
|
+
|
|
270
|
+
- ``field`` -- boolean (default: ``None``); whether to return an
|
|
271
|
+
element of GF(p) or Zmod(p)
|
|
272
|
+
|
|
273
|
+
- ``check_prec`` -- boolean (default: ``True``); whether to raise an
|
|
274
|
+
error if this element has insufficient precision to determine the
|
|
275
|
+
reduction
|
|
276
|
+
|
|
277
|
+
OUTPUT:
|
|
278
|
+
|
|
279
|
+
This element reduced modulo `p^\mathrm{absprec}` as an element of
|
|
280
|
+
`\ZZ/p^\mathrm{absprec}\ZZ`
|
|
281
|
+
|
|
282
|
+
EXAMPLES::
|
|
283
|
+
|
|
284
|
+
sage: R = ZpLC(7,4)
|
|
285
|
+
sage: a = R(8)
|
|
286
|
+
sage: a.residue(1)
|
|
287
|
+
1
|
|
288
|
+
|
|
289
|
+
TESTS::
|
|
290
|
+
|
|
291
|
+
sage: R = ZpLC(7,4)
|
|
292
|
+
sage: a = R(8)
|
|
293
|
+
sage: a.residue(0)
|
|
294
|
+
0
|
|
295
|
+
sage: a.residue(-1)
|
|
296
|
+
Traceback (most recent call last):
|
|
297
|
+
...
|
|
298
|
+
ValueError: cannot reduce modulo a negative power of p
|
|
299
|
+
sage: a.residue(5)
|
|
300
|
+
Traceback (most recent call last):
|
|
301
|
+
...
|
|
302
|
+
PrecisionError: not enough precision known in order to compute residue
|
|
303
|
+
sage: a.residue(5, check_prec=False)
|
|
304
|
+
8
|
|
305
|
+
|
|
306
|
+
sage: a.residue(field=True).parent()
|
|
307
|
+
Finite Field of size 7
|
|
308
|
+
"""
|
|
309
|
+
if not isinstance(absprec, Integer):
|
|
310
|
+
absprec = Integer(absprec)
|
|
311
|
+
if check_prec and absprec > self.precision_absolute():
|
|
312
|
+
raise PrecisionError("not enough precision known in order to compute residue")
|
|
313
|
+
elif absprec < 0:
|
|
314
|
+
raise ValueError("cannot reduce modulo a negative power of p")
|
|
315
|
+
if self.valuation() < 0:
|
|
316
|
+
raise ValueError("element must have nonnegative valuation in order to compute residue")
|
|
317
|
+
if field is None:
|
|
318
|
+
field = (absprec == 1)
|
|
319
|
+
elif field and absprec != 1:
|
|
320
|
+
raise ValueError("field keyword may only be set at precision 1")
|
|
321
|
+
p = self._parent.prime()
|
|
322
|
+
if field:
|
|
323
|
+
from sage.rings.finite_rings.finite_field_constructor import GF
|
|
324
|
+
ring = GF(p)
|
|
325
|
+
else:
|
|
326
|
+
from sage.rings.finite_rings.integer_mod_ring import Integers
|
|
327
|
+
ring = Integers(p**absprec)
|
|
328
|
+
return ring(self.value())
|
|
329
|
+
|
|
330
|
+
def precision_lattice(self):
|
|
331
|
+
r"""
|
|
332
|
+
Return the precision object (which is a lattice in a possibly
|
|
333
|
+
high-dimensional vector space) that handles the precision of
|
|
334
|
+
this element.
|
|
335
|
+
|
|
336
|
+
EXAMPLES::
|
|
337
|
+
|
|
338
|
+
sage: R = ZpLC(2, label='precision')
|
|
339
|
+
sage: x = R.random_element()
|
|
340
|
+
sage: y = R.random_element()
|
|
341
|
+
sage: x.precision_lattice()
|
|
342
|
+
Precision lattice on 2 objects (label: precision)
|
|
343
|
+
|
|
344
|
+
.. SEEALSO::
|
|
345
|
+
|
|
346
|
+
:class:`sage.rings.padics.lattice_precision.PrecisionLattice`
|
|
347
|
+
"""
|
|
348
|
+
return self._precision
|
|
349
|
+
|
|
350
|
+
def precision_absolute(self):
|
|
351
|
+
r"""
|
|
352
|
+
Return the absolute precision of this element.
|
|
353
|
+
|
|
354
|
+
This precision is computed by projecting the lattice precision
|
|
355
|
+
onto the coordinate defined by this element.
|
|
356
|
+
|
|
357
|
+
EXAMPLES::
|
|
358
|
+
|
|
359
|
+
sage: R = ZpLC(2, print_mode='terse')
|
|
360
|
+
sage: x = R(1234, 10); x
|
|
361
|
+
210 + O(2^10)
|
|
362
|
+
sage: x.precision_absolute()
|
|
363
|
+
10
|
|
364
|
+
|
|
365
|
+
Another example with diffused digits::
|
|
366
|
+
|
|
367
|
+
sage: x = R(1, 10); y = R(1, 5)
|
|
368
|
+
sage: x, y = x+y, x-y
|
|
369
|
+
sage: x.precision_absolute()
|
|
370
|
+
5
|
|
371
|
+
sage: y.precision_absolute()
|
|
372
|
+
5
|
|
373
|
+
sage: (x+y).precision_absolute()
|
|
374
|
+
11
|
|
375
|
+
"""
|
|
376
|
+
prec = self._precision._precision_absolute(self)
|
|
377
|
+
cap = self._value.valuation() + self._parent._prec_cap_relative
|
|
378
|
+
return min(prec, cap)
|
|
379
|
+
|
|
380
|
+
def is_precision_capped(self):
|
|
381
|
+
r"""
|
|
382
|
+
Return whether the absolute precision on this element results from a
|
|
383
|
+
cap coming from the parent.
|
|
384
|
+
|
|
385
|
+
EXAMPLES::
|
|
386
|
+
|
|
387
|
+
sage: R = ZpLC(2)
|
|
388
|
+
sage: x = R(1, 10); x
|
|
389
|
+
1 + O(2^10)
|
|
390
|
+
sage: x.is_precision_capped()
|
|
391
|
+
False
|
|
392
|
+
|
|
393
|
+
sage: y = x-x; y
|
|
394
|
+
O(2^40)
|
|
395
|
+
sage: y.is_precision_capped()
|
|
396
|
+
True
|
|
397
|
+
|
|
398
|
+
sage: y = x << 35; y
|
|
399
|
+
2^35 + O(2^40)
|
|
400
|
+
sage: y.is_precision_capped()
|
|
401
|
+
True
|
|
402
|
+
sage: z = y >> 35; z
|
|
403
|
+
1 + O(2^5)
|
|
404
|
+
sage: z.is_precision_capped()
|
|
405
|
+
True
|
|
406
|
+
"""
|
|
407
|
+
return self._precision._is_precision_capped(self)
|
|
408
|
+
|
|
409
|
+
def valuation(self, secure=False):
|
|
410
|
+
r"""
|
|
411
|
+
Return the valuation of this element.
|
|
412
|
+
|
|
413
|
+
INPUT:
|
|
414
|
+
|
|
415
|
+
- ``secure`` -- boolean (default: ``False``); when ``True``,
|
|
416
|
+
an error is raised if the precision on the element is not
|
|
417
|
+
enough to determine for sure its valuation. Otherwise the
|
|
418
|
+
absolute precision (which is the smallest possible valuation)
|
|
419
|
+
is returned.
|
|
420
|
+
|
|
421
|
+
EXAMPLES::
|
|
422
|
+
|
|
423
|
+
sage: R = ZpLC(2)
|
|
424
|
+
sage: x = R(12, 10); x
|
|
425
|
+
2^2 + 2^3 + O(2^10)
|
|
426
|
+
sage: x.valuation()
|
|
427
|
+
2
|
|
428
|
+
|
|
429
|
+
sage: y = x - x; y
|
|
430
|
+
O(2^40)
|
|
431
|
+
sage: y.valuation()
|
|
432
|
+
40
|
|
433
|
+
sage: y.valuation(secure=True)
|
|
434
|
+
Traceback (most recent call last):
|
|
435
|
+
...
|
|
436
|
+
PrecisionError: not enough precision
|
|
437
|
+
"""
|
|
438
|
+
val = self._value.valuation()
|
|
439
|
+
prec = self.precision_absolute()
|
|
440
|
+
if val < prec:
|
|
441
|
+
return val
|
|
442
|
+
elif secure:
|
|
443
|
+
raise PrecisionError("not enough precision")
|
|
444
|
+
else:
|
|
445
|
+
return prec
|
|
446
|
+
|
|
447
|
+
def precision_relative(self, secure=False):
|
|
448
|
+
r"""
|
|
449
|
+
Return the relative precision of this element, that is
|
|
450
|
+
the difference between its absolute precision and its
|
|
451
|
+
valuation.
|
|
452
|
+
|
|
453
|
+
INPUT:
|
|
454
|
+
|
|
455
|
+
- ``secure`` -- boolean (default: ``False``); when ``True``,
|
|
456
|
+
an error is raised if the precision on the element is not
|
|
457
|
+
enough to determine for sure its valuation
|
|
458
|
+
|
|
459
|
+
EXAMPLES::
|
|
460
|
+
|
|
461
|
+
sage: R = ZpLC(2)
|
|
462
|
+
sage: x = R(12, 10); x
|
|
463
|
+
2^2 + 2^3 + O(2^10)
|
|
464
|
+
sage: x.precision_relative()
|
|
465
|
+
8
|
|
466
|
+
|
|
467
|
+
sage: y = x - x; y
|
|
468
|
+
O(2^40)
|
|
469
|
+
sage: y.precision_relative()
|
|
470
|
+
0
|
|
471
|
+
sage: y.precision_relative(secure=True)
|
|
472
|
+
Traceback (most recent call last):
|
|
473
|
+
...
|
|
474
|
+
PrecisionError: not enough precision
|
|
475
|
+
"""
|
|
476
|
+
if not secure and self.is_zero():
|
|
477
|
+
return ZZ(0)
|
|
478
|
+
return self.precision_absolute() - self.valuation(secure=secure)
|
|
479
|
+
|
|
480
|
+
def _richcmp_(self, other, op):
|
|
481
|
+
r"""
|
|
482
|
+
Compare this element with ``other``.
|
|
483
|
+
|
|
484
|
+
TESTS::
|
|
485
|
+
|
|
486
|
+
sage: R = ZpLC(2)
|
|
487
|
+
sage: x = R(1, 5)
|
|
488
|
+
sage: y = R(128, 10)
|
|
489
|
+
sage: z = x + y
|
|
490
|
+
|
|
491
|
+
sage: x
|
|
492
|
+
1 + O(2^5)
|
|
493
|
+
sage: z
|
|
494
|
+
1 + O(2^5)
|
|
495
|
+
|
|
496
|
+
sage: x == z # Indirect doctest
|
|
497
|
+
False
|
|
498
|
+
sage: z - x
|
|
499
|
+
2^7 + O(2^10)
|
|
500
|
+
"""
|
|
501
|
+
if (self - other).is_zero():
|
|
502
|
+
return rich_to_bool(op, 0)
|
|
503
|
+
else:
|
|
504
|
+
return richcmp(QQ(self.lift()), QQ(other.lift()), op)
|
|
505
|
+
|
|
506
|
+
def is_equal_to(self, other, prec):
|
|
507
|
+
r"""
|
|
508
|
+
Return ``True`` if this element is indistinguishable
|
|
509
|
+
from ``other`` at precision ``prec``
|
|
510
|
+
|
|
511
|
+
EXAMPLES::
|
|
512
|
+
|
|
513
|
+
sage: R = ZpLC(2)
|
|
514
|
+
sage: x = R(1, 5)
|
|
515
|
+
sage: y = R(128, 10)
|
|
516
|
+
sage: z = x + y
|
|
517
|
+
|
|
518
|
+
sage: x
|
|
519
|
+
1 + O(2^5)
|
|
520
|
+
sage: z
|
|
521
|
+
1 + O(2^5)
|
|
522
|
+
|
|
523
|
+
sage: x.is_equal_to(z, 5)
|
|
524
|
+
True
|
|
525
|
+
|
|
526
|
+
sage: x.is_equal_to(z, 10)
|
|
527
|
+
False
|
|
528
|
+
sage: z - x
|
|
529
|
+
2^7 + O(2^10)
|
|
530
|
+
"""
|
|
531
|
+
return (self-other).is_zero(prec)
|
|
532
|
+
|
|
533
|
+
def _add_(self, other):
|
|
534
|
+
r"""
|
|
535
|
+
Return the sum of this element and ``other``.
|
|
536
|
+
|
|
537
|
+
EXAMPLES::
|
|
538
|
+
|
|
539
|
+
sage: R = ZpLC(19, 5)
|
|
540
|
+
sage: a = R(-1); a
|
|
541
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
542
|
+
sage: b = R(-5/2); b
|
|
543
|
+
7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
544
|
+
sage: a + b # indirect doctest
|
|
545
|
+
6 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
546
|
+
|
|
547
|
+
TESTS::
|
|
548
|
+
|
|
549
|
+
sage: a = R.random_element()
|
|
550
|
+
sage: b = R.random_element()
|
|
551
|
+
sage: a + b == b + a
|
|
552
|
+
True
|
|
553
|
+
"""
|
|
554
|
+
x = self._value + other._value
|
|
555
|
+
# elements whose valuation are not less than _zero_cap are assumed to vanish
|
|
556
|
+
# (_zero_cap is set at the creation of the parent)
|
|
557
|
+
if self._parent._zero_cap is not None:
|
|
558
|
+
if x.valuation() >= min(self._value.valuation(), other._value.valuation()) + self._parent._zero_cap:
|
|
559
|
+
x = self._parent._approx_zero
|
|
560
|
+
dx = [ [self, self._parent._approx_one],
|
|
561
|
+
[other, self._parent._approx_one] ]
|
|
562
|
+
return self.__class__(self._parent, x, dx=dx, check=False)
|
|
563
|
+
|
|
564
|
+
def _sub_(self, other):
|
|
565
|
+
r"""
|
|
566
|
+
Return the difference of this element and ``other``.
|
|
567
|
+
|
|
568
|
+
EXAMPLES::
|
|
569
|
+
|
|
570
|
+
sage: R = ZpLC(19, 5)
|
|
571
|
+
sage: a = R(-1); a
|
|
572
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
573
|
+
sage: b = R(-5/2); b
|
|
574
|
+
7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
575
|
+
sage: a - b # indirect doctest
|
|
576
|
+
11 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
577
|
+
"""
|
|
578
|
+
x = self._value - other._value
|
|
579
|
+
if self._parent._zero_cap is not None:
|
|
580
|
+
if x.valuation() >= min(self._value.valuation(), other._value.valuation()) + self._parent._zero_cap:
|
|
581
|
+
x = self._parent._approx_zero
|
|
582
|
+
dx = [ [self, self._parent._approx_one],
|
|
583
|
+
[other, self._parent._approx_minusone] ]
|
|
584
|
+
return self.__class__(self._parent, x, dx=dx, check=False)
|
|
585
|
+
|
|
586
|
+
def _mul_(self, other):
|
|
587
|
+
r"""
|
|
588
|
+
Return the product of this element and ``other``.
|
|
589
|
+
|
|
590
|
+
EXAMPLES::
|
|
591
|
+
|
|
592
|
+
sage: R = ZpLC(19, 5)
|
|
593
|
+
sage: a = R(-1); a
|
|
594
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
595
|
+
sage: b = R(-5/2); b
|
|
596
|
+
7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
597
|
+
sage: a * b # indirect doctest
|
|
598
|
+
12 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
599
|
+
|
|
600
|
+
TESTS::
|
|
601
|
+
|
|
602
|
+
sage: a = R.random_element()
|
|
603
|
+
sage: b = R.random_element()
|
|
604
|
+
sage: a * b == b * a
|
|
605
|
+
True
|
|
606
|
+
|
|
607
|
+
sage: a = R.random_element()
|
|
608
|
+
sage: b = R.random_element()
|
|
609
|
+
sage: c = R.random_element()
|
|
610
|
+
sage: a * (b+c) == a*b + a*c
|
|
611
|
+
True
|
|
612
|
+
"""
|
|
613
|
+
x_self = self._value
|
|
614
|
+
x_other = other._value
|
|
615
|
+
x = x_self * x_other
|
|
616
|
+
dx = [ [self, x_other],
|
|
617
|
+
[other, x_self ] ]
|
|
618
|
+
return self.__class__(self._parent, x, dx=dx, check=False)
|
|
619
|
+
|
|
620
|
+
def _div_(self, other):
|
|
621
|
+
r"""
|
|
622
|
+
Return the quotient of this element and ``other``.
|
|
623
|
+
|
|
624
|
+
.. NOTE::
|
|
625
|
+
|
|
626
|
+
The result of division always lives in the fraction field,
|
|
627
|
+
even if the element to be inverted is a unit.
|
|
628
|
+
|
|
629
|
+
EXAMPLES::
|
|
630
|
+
|
|
631
|
+
sage: R = ZpLC(19)
|
|
632
|
+
sage: a = R(-1, 5); a
|
|
633
|
+
18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
|
|
634
|
+
sage: b = R(-5/2, 5); b
|
|
635
|
+
7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
636
|
+
|
|
637
|
+
sage: c = a / b # indirect doctest
|
|
638
|
+
sage: c
|
|
639
|
+
8 + 11*19 + 7*19^2 + 11*19^3 + 7*19^4 + O(19^5)
|
|
640
|
+
sage: c.parent()
|
|
641
|
+
19-adic Field with lattice-cap precision
|
|
642
|
+
|
|
643
|
+
sage: a / (19*b)
|
|
644
|
+
8*19^-1 + 11 + 7*19 + 11*19^2 + 7*19^3 + O(19^4)
|
|
645
|
+
|
|
646
|
+
If the division is indistinguishable from zero, an error is raised::
|
|
647
|
+
|
|
648
|
+
sage: c = a / (2*b + 5)
|
|
649
|
+
Traceback (most recent call last):
|
|
650
|
+
...
|
|
651
|
+
PrecisionError: cannot divide by something indistinguishable from zero
|
|
652
|
+
"""
|
|
653
|
+
if other.is_zero():
|
|
654
|
+
raise PrecisionError("cannot divide by something indistinguishable from zero")
|
|
655
|
+
x_self = self._value
|
|
656
|
+
x_other = other._value
|
|
657
|
+
x = x_self / x_other
|
|
658
|
+
# dx = (1/other)*dself - (self/other^2)*dother
|
|
659
|
+
dx = [ [self, self._parent._approx_one/x_other],
|
|
660
|
+
[other, -x_self/(x_other*x_other)] ]
|
|
661
|
+
return self.__class__(self._parent.fraction_field(), x, dx=dx, check=False)
|
|
662
|
+
|
|
663
|
+
def __invert__(self):
|
|
664
|
+
r"""
|
|
665
|
+
Return the multiplicative inverse of this element.
|
|
666
|
+
|
|
667
|
+
.. NOTE::
|
|
668
|
+
|
|
669
|
+
The result of division always lives in the fraction field,
|
|
670
|
+
even if the element to be inverted is a unit.
|
|
671
|
+
|
|
672
|
+
EXAMPLES::
|
|
673
|
+
|
|
674
|
+
sage: R = ZpLC(19)
|
|
675
|
+
sage: x = R(-5/2, 5); x
|
|
676
|
+
7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
|
|
677
|
+
|
|
678
|
+
sage: y = ~x # indirect doctest
|
|
679
|
+
sage: y
|
|
680
|
+
11 + 7*19 + 11*19^2 + 7*19^3 + 11*19^4 + O(19^5)
|
|
681
|
+
sage: y == -2/5
|
|
682
|
+
True
|
|
683
|
+
|
|
684
|
+
TESTS::
|
|
685
|
+
|
|
686
|
+
sage: a = R.random_element()
|
|
687
|
+
sage: a * ~a == 1
|
|
688
|
+
True
|
|
689
|
+
"""
|
|
690
|
+
if self.is_zero():
|
|
691
|
+
raise PrecisionError("cannot invert something indistinguishable from zero")
|
|
692
|
+
x_self = self._value
|
|
693
|
+
x = self._parent._approx_one / x_self
|
|
694
|
+
# dx = -(1/self^2)*dself
|
|
695
|
+
dx = [ [self, self._parent._approx_minusone/(x_self*x_self)] ]
|
|
696
|
+
return self.__class__(self._parent.fraction_field(), x, dx=dx, check=False)
|
|
697
|
+
|
|
698
|
+
def _quo_rem(self, other):
|
|
699
|
+
"""
|
|
700
|
+
Quotient with remainder.
|
|
701
|
+
|
|
702
|
+
EXAMPLES::
|
|
703
|
+
|
|
704
|
+
sage: R = ZpLC(2)
|
|
705
|
+
sage: a = R(373286)
|
|
706
|
+
sage: b = R(12685856)
|
|
707
|
+
sage: q,r = a.quo_rem(b); q, r
|
|
708
|
+
(1 + 2^8 + 2^12 + 2^15 + O(2^16), 2 + 2^2 + O(2^21))
|
|
709
|
+
sage: q*b+r == a
|
|
710
|
+
True
|
|
711
|
+
sage: q,r = b.quo_rem(a); q, r
|
|
712
|
+
(2^4 + 2^5 + 2^7 + 2^10 + 2^14 + 2^15 + 2^16 + 2^17 + O(2^24), O(2^40))
|
|
713
|
+
sage: q*a == b
|
|
714
|
+
True
|
|
715
|
+
"""
|
|
716
|
+
if other.is_zero():
|
|
717
|
+
# We use ZeroDivisionError since _test_quo_rem expects it.
|
|
718
|
+
raise ZeroDivisionError("cannot divide by something indistinguishable from zero")
|
|
719
|
+
if other.valuation() > self.precision_absolute():
|
|
720
|
+
raise PrecisionError
|
|
721
|
+
q, r = self._value._quo_rem(other._value)
|
|
722
|
+
rem = self.__class__(self._parent, r, check=False)
|
|
723
|
+
quo = self.parent()((self - rem) / other)
|
|
724
|
+
return quo, rem
|
|
725
|
+
|
|
726
|
+
def add_bigoh(self, prec):
|
|
727
|
+
r"""
|
|
728
|
+
Return a new element with absolute precision decreased to
|
|
729
|
+
the specified precision.
|
|
730
|
+
|
|
731
|
+
INPUT:
|
|
732
|
+
|
|
733
|
+
- ``prec`` -- integer or infinity
|
|
734
|
+
|
|
735
|
+
EXAMPLES::
|
|
736
|
+
|
|
737
|
+
sage: R = ZpLC(7)
|
|
738
|
+
sage: a = R(8); a.add_bigoh(1)
|
|
739
|
+
1 + O(7)
|
|
740
|
+
sage: b = R(0); b.add_bigoh(3)
|
|
741
|
+
O(7^3)
|
|
742
|
+
|
|
743
|
+
sage: R = QpLC(7, 4)
|
|
744
|
+
sage: a = R(8); a.add_bigoh(1)
|
|
745
|
+
1 + O(7)
|
|
746
|
+
sage: b = R(0); b.add_bigoh(3)
|
|
747
|
+
O(7^3)
|
|
748
|
+
|
|
749
|
+
The precision never increases::
|
|
750
|
+
|
|
751
|
+
sage: R(4).add_bigoh(2).add_bigoh(4)
|
|
752
|
+
4 + O(7^2)
|
|
753
|
+
|
|
754
|
+
If ``prec`` is negative, the output is an element of the
|
|
755
|
+
fraction field::
|
|
756
|
+
|
|
757
|
+
sage: c = a.add_bigoh(-1); c
|
|
758
|
+
O(7^-1)
|
|
759
|
+
sage: c.parent()
|
|
760
|
+
7-adic Field with lattice-cap precision
|
|
761
|
+
"""
|
|
762
|
+
if prec is Infinity:
|
|
763
|
+
return self
|
|
764
|
+
if not self._parent.is_field() and prec < 0:
|
|
765
|
+
field = self._parent.fraction_field()
|
|
766
|
+
return self._copy(field).add_bigoh(prec)
|
|
767
|
+
x = self._value
|
|
768
|
+
dx = [ [self, self._parent._approx_one ] ]
|
|
769
|
+
return self.__class__(self._parent, x, prec, dx=dx, check=False)
|
|
770
|
+
|
|
771
|
+
def lift_to_precision(self, prec=None, infer_precision=False):
|
|
772
|
+
r"""
|
|
773
|
+
Return another element of the same parent with absolute precision
|
|
774
|
+
at least ``prec``, congruent to this `p`-adic element modulo the
|
|
775
|
+
precision of this element.
|
|
776
|
+
|
|
777
|
+
INPUT:
|
|
778
|
+
|
|
779
|
+
- ``prec`` -- integer or ``None`` (default: ``None``); the
|
|
780
|
+
absolute precision of the result. If ``None``, lifts to the
|
|
781
|
+
maximum precision allowed.
|
|
782
|
+
|
|
783
|
+
- ``infer_precision`` -- boolean (default: ``False``)
|
|
784
|
+
|
|
785
|
+
NOTE:
|
|
786
|
+
|
|
787
|
+
In the lattice precision model, the precision of all variables is
|
|
788
|
+
handled globally by a unique object, namely a lattice in a certain
|
|
789
|
+
vector space.
|
|
790
|
+
|
|
791
|
+
When ``infer_precision`` is set to ``True``, the precision lattice
|
|
792
|
+
is recomputed. This may affect the precision of other variables
|
|
793
|
+
with the same parent.
|
|
794
|
+
|
|
795
|
+
When ``infer_precision`` is set to ``False``, the precision on the
|
|
796
|
+
newly created variable is independent as if the variable were created
|
|
797
|
+
by hand by setting independently the value of the absolute precision.
|
|
798
|
+
In particular, if ``self`` used to share diffused digits of precision
|
|
799
|
+
with other variables, they are not preserved.
|
|
800
|
+
|
|
801
|
+
EXAMPLES::
|
|
802
|
+
|
|
803
|
+
sage: R = ZpLC(2)
|
|
804
|
+
sage: x = R(1, 10); x
|
|
805
|
+
1 + O(2^10)
|
|
806
|
+
sage: x.lift_to_precision(15)
|
|
807
|
+
1 + O(2^15)
|
|
808
|
+
sage: x.lift_to_precision()
|
|
809
|
+
1 + O(2^20)
|
|
810
|
+
|
|
811
|
+
An example with diffused digits of precision::
|
|
812
|
+
|
|
813
|
+
sage: x = R(1, 10); y = R(1, 5)
|
|
814
|
+
sage: u = x+y; u
|
|
815
|
+
2 + O(2^5)
|
|
816
|
+
sage: v = x-y; v
|
|
817
|
+
O(2^5)
|
|
818
|
+
sage: u + v
|
|
819
|
+
2 + O(2^11)
|
|
820
|
+
|
|
821
|
+
The gain of precision on ``u + v`` is due to the presence of diffused
|
|
822
|
+
digits of precision between ``u`` and ``v``.
|
|
823
|
+
|
|
824
|
+
However, if we call :meth:`lift_to_precision` on one of these variables,
|
|
825
|
+
these diffused digits are lost and the precision on the sum is no longer
|
|
826
|
+
sharp::
|
|
827
|
+
|
|
828
|
+
sage: u.lift_to_precision() + v
|
|
829
|
+
2 + O(2^5)
|
|
830
|
+
|
|
831
|
+
We can avoid this issue as follows::
|
|
832
|
+
|
|
833
|
+
sage: u.lift_to_precision(infer_precision=True) + v
|
|
834
|
+
2 + O(2^11)
|
|
835
|
+
|
|
836
|
+
But now the precision on ``y`` has changed::
|
|
837
|
+
|
|
838
|
+
sage: y
|
|
839
|
+
1 + O(2^10)
|
|
840
|
+
|
|
841
|
+
Indeed if the absolute precision on ``u = x+y`` (resp. on ``x``)
|
|
842
|
+
is 20 (resp. 10), we deduce that the absolution precision on
|
|
843
|
+
``y = u-x`` is 10.
|
|
844
|
+
|
|
845
|
+
.. SEEALSO::
|
|
846
|
+
|
|
847
|
+
:meth:`lift_to_precision` of the precision object
|
|
848
|
+
"""
|
|
849
|
+
#from warnings import warn
|
|
850
|
+
#warn("use lift_to_precision with extreme caution in the framework of lattice precision")
|
|
851
|
+
parent = self._parent
|
|
852
|
+
if infer_precision:
|
|
853
|
+
cap = min(parent.precision_cap_absolute(), parent.precision_cap_relative() + self._value.valuation())
|
|
854
|
+
if prec is None or prec > cap:
|
|
855
|
+
prec = cap
|
|
856
|
+
lift = self._copy()
|
|
857
|
+
parent.precision()._lift_to_precision(lift, prec)
|
|
858
|
+
else:
|
|
859
|
+
lift = self.__class__(parent, self._value, prec, check=False)
|
|
860
|
+
return lift
|
|
861
|
+
|
|
862
|
+
def _is_inexact_zero(self):
|
|
863
|
+
r"""
|
|
864
|
+
Return ``True`` if this element is indistinguishable from zero.
|
|
865
|
+
|
|
866
|
+
EXAMPLES::
|
|
867
|
+
|
|
868
|
+
sage: R = ZpLC(5)
|
|
869
|
+
sage: R(0)._is_inexact_zero()
|
|
870
|
+
True
|
|
871
|
+
sage: R(1)._is_inexact_zero()
|
|
872
|
+
False
|
|
873
|
+
"""
|
|
874
|
+
absprec = self.precision_absolute()
|
|
875
|
+
return self._value.valuation() >= absprec
|
|
876
|
+
|
|
877
|
+
def is_zero(self, prec=None):
|
|
878
|
+
r"""
|
|
879
|
+
Return ``True`` if this element is indistinguishable from zero
|
|
880
|
+
at the given precision (if given).
|
|
881
|
+
|
|
882
|
+
INPUT:
|
|
883
|
+
|
|
884
|
+
- ``prec`` -- integer or ``None`` (default: ``None``)
|
|
885
|
+
|
|
886
|
+
EXAMPLES::
|
|
887
|
+
|
|
888
|
+
sage: R = ZpLC(2)
|
|
889
|
+
sage: x = R(2/5, 10); x
|
|
890
|
+
2 + 2^3 + 2^4 + 2^7 + 2^8 + O(2^10)
|
|
891
|
+
sage: x.is_zero()
|
|
892
|
+
False
|
|
893
|
+
sage: x.is_zero(1)
|
|
894
|
+
True
|
|
895
|
+
|
|
896
|
+
sage: (5*x-2).is_zero()
|
|
897
|
+
True
|
|
898
|
+
sage: 5*x == 2 # indirect doctest
|
|
899
|
+
True
|
|
900
|
+
"""
|
|
901
|
+
absprec = self.precision_absolute()
|
|
902
|
+
if prec is None:
|
|
903
|
+
prec = absprec
|
|
904
|
+
else:
|
|
905
|
+
prec = min(absprec, prec)
|
|
906
|
+
return self._value.valuation() >= prec
|
|
907
|
+
|
|
908
|
+
def lift(self):
|
|
909
|
+
r"""
|
|
910
|
+
Return an integer or rational congruent to this element modulo
|
|
911
|
+
its absolute precision.
|
|
912
|
+
If a rational is returned, its denominator will be a power of `p`.
|
|
913
|
+
|
|
914
|
+
EXAMPLES::
|
|
915
|
+
|
|
916
|
+
sage: R = ZpLC(7)
|
|
917
|
+
sage: a = R(8); a.lift()
|
|
918
|
+
8
|
|
919
|
+
|
|
920
|
+
sage: R = QpLC(7)
|
|
921
|
+
sage: a = R(8); a.lift()
|
|
922
|
+
8
|
|
923
|
+
sage: b = R(8/7); b.lift()
|
|
924
|
+
8/7
|
|
925
|
+
"""
|
|
926
|
+
return self._value.value()
|
|
927
|
+
|
|
928
|
+
def __rshift__(self, n):
|
|
929
|
+
r"""
|
|
930
|
+
Divide this element by ``p^n``, and truncate
|
|
931
|
+
(if the parent is not a field).
|
|
932
|
+
|
|
933
|
+
EXAMPLES::
|
|
934
|
+
|
|
935
|
+
sage: R = ZpLC(997, 7)
|
|
936
|
+
sage: a = R(123456878908); a
|
|
937
|
+
964*997 + 572*997^2 + 124*997^3 + O(997^8)
|
|
938
|
+
|
|
939
|
+
sage: S = ZpLC(5)
|
|
940
|
+
sage: b = S(17); b
|
|
941
|
+
2 + 3*5 + O(5^20)
|
|
942
|
+
|
|
943
|
+
Shifting to the right divides by a power of `p`, but drops
|
|
944
|
+
terms with negative valuation::
|
|
945
|
+
|
|
946
|
+
sage: a >> 3
|
|
947
|
+
124 + O(997^5)
|
|
948
|
+
sage: b >> 1
|
|
949
|
+
3 + O(5^19)
|
|
950
|
+
sage: b >> 40
|
|
951
|
+
O(5^0)
|
|
952
|
+
|
|
953
|
+
If the parent is a field no truncation is performed::
|
|
954
|
+
|
|
955
|
+
sage: K = QpLC(5)
|
|
956
|
+
sage: b = K(17); b
|
|
957
|
+
2 + 3*5 + O(5^20)
|
|
958
|
+
sage: b >> 1
|
|
959
|
+
2*5^-1 + 3 + O(5^19)
|
|
960
|
+
|
|
961
|
+
A negative shift multiplies by that power of `p`::
|
|
962
|
+
|
|
963
|
+
sage: a >> -3
|
|
964
|
+
964*997^4 + 572*997^5 + 124*997^6 + O(997^11)
|
|
965
|
+
sage: b >> -5
|
|
966
|
+
2*5^5 + 3*5^6 + O(5^25)
|
|
967
|
+
"""
|
|
968
|
+
return self << (-n)
|
|
969
|
+
|
|
970
|
+
def __lshift__(self, n):
|
|
971
|
+
r"""
|
|
972
|
+
Multiply this element by ``p^n``.
|
|
973
|
+
|
|
974
|
+
If ``n`` is negative and this element does not lie in a field,
|
|
975
|
+
digits may be truncated. See :meth:`__rshift__` for details.
|
|
976
|
+
|
|
977
|
+
EXAMPLES::
|
|
978
|
+
|
|
979
|
+
sage: R = ZpLC(5)
|
|
980
|
+
sage: a = R(1000); a
|
|
981
|
+
3*5^3 + 5^4 + O(5^23)
|
|
982
|
+
sage: a >> 1
|
|
983
|
+
3*5^2 + 5^3 + O(5^22)
|
|
984
|
+
|
|
985
|
+
sage: S = Zp(5); b = S(1000); b
|
|
986
|
+
3*5^3 + 5^4 + O(5^23)
|
|
987
|
+
"""
|
|
988
|
+
from sage.rings.padics.generic_nodes import pAdicRingBaseGeneric
|
|
989
|
+
parent = self._parent
|
|
990
|
+
p = parent.prime()
|
|
991
|
+
if isinstance(parent, pAdicRingBaseGeneric):
|
|
992
|
+
if self.precision_absolute() + n < 0:
|
|
993
|
+
return self.__class__(parent, pRational(p, 0), 0, dx={}, check=False)
|
|
994
|
+
powp = pRational(p, ZZ(1), n)
|
|
995
|
+
x = self._value * powp
|
|
996
|
+
if isinstance(parent, pAdicRingBaseGeneric):
|
|
997
|
+
x -= x.reduce(0)
|
|
998
|
+
dx = [ [self, powp] ]
|
|
999
|
+
return self.__class__(parent, x, dx=dx, check=False)
|
|
1000
|
+
|
|
1001
|
+
def unit_part(self):
|
|
1002
|
+
r"""
|
|
1003
|
+
Return `u`, where this element is `p^v u` and `u` is a unit.
|
|
1004
|
+
|
|
1005
|
+
EXAMPLES::
|
|
1006
|
+
|
|
1007
|
+
sage: R = ZpLC(17)
|
|
1008
|
+
sage: a = R(18*17, 4)
|
|
1009
|
+
sage: a.unit_part()
|
|
1010
|
+
1 + 17 + O(17^3)
|
|
1011
|
+
|
|
1012
|
+
sage: b=1/a; b
|
|
1013
|
+
17^-1 + 16 + O(17^2)
|
|
1014
|
+
sage: b.unit_part()
|
|
1015
|
+
1 + 16*17 + O(17^3)
|
|
1016
|
+
|
|
1017
|
+
If the element is indistinguishable from zero, an error is raised::
|
|
1018
|
+
|
|
1019
|
+
sage: c = R(0, 5); c
|
|
1020
|
+
O(17^5)
|
|
1021
|
+
sage: c.unit_part()
|
|
1022
|
+
Traceback (most recent call last):
|
|
1023
|
+
...
|
|
1024
|
+
PrecisionError: not enough precision
|
|
1025
|
+
"""
|
|
1026
|
+
v = self.valuation(secure=True)
|
|
1027
|
+
return self >> v
|
|
1028
|
+
|
|
1029
|
+
def val_unit(self):
|
|
1030
|
+
r"""
|
|
1031
|
+
Return the pair `(v, u)`, where this element is
|
|
1032
|
+
`p^v u` and `u` is a unit.
|
|
1033
|
+
|
|
1034
|
+
EXAMPLES::
|
|
1035
|
+
|
|
1036
|
+
sage: R = ZpLC(17)
|
|
1037
|
+
sage: a = R(18*17, 4)
|
|
1038
|
+
sage: a.val_unit()
|
|
1039
|
+
(1, 1 + 17 + O(17^3))
|
|
1040
|
+
|
|
1041
|
+
sage: b=1/a; b
|
|
1042
|
+
17^-1 + 16 + O(17^2)
|
|
1043
|
+
sage: b.val_unit()
|
|
1044
|
+
(-1, 1 + 16*17 + O(17^3))
|
|
1045
|
+
|
|
1046
|
+
If the element is indistinguishable from zero, an error is raised
|
|
1047
|
+
|
|
1048
|
+
sage: c = R(0, 5); c
|
|
1049
|
+
O(17^5)
|
|
1050
|
+
sage: c.val_unit()
|
|
1051
|
+
Traceback (most recent call last):
|
|
1052
|
+
...
|
|
1053
|
+
PrecisionError: not enough precision
|
|
1054
|
+
"""
|
|
1055
|
+
v = self.valuation(secure=True)
|
|
1056
|
+
return v, self >> v
|
|
1057
|
+
|
|
1058
|
+
def _copy(self, parent=None):
|
|
1059
|
+
r"""
|
|
1060
|
+
Return a copy of this element or convert this element
|
|
1061
|
+
to the given parent provided that the precision on this
|
|
1062
|
+
parent is handled by the same precision object.
|
|
1063
|
+
|
|
1064
|
+
EXAMPLES::
|
|
1065
|
+
|
|
1066
|
+
sage: R = ZpLC(2)
|
|
1067
|
+
sage: x = R(1, 10); x
|
|
1068
|
+
1 + O(2^10)
|
|
1069
|
+
sage: y = x._copy()
|
|
1070
|
+
sage: y
|
|
1071
|
+
1 + O(2^10)
|
|
1072
|
+
|
|
1073
|
+
In the lattice precision model, Sage remembers that ``y`` is
|
|
1074
|
+
actually equal to ``x``. Therefore, when we compute the difference,
|
|
1075
|
+
the `O(2^10)` cancel as well::
|
|
1076
|
+
|
|
1077
|
+
sage: x - y
|
|
1078
|
+
O(2^20)
|
|
1079
|
+
|
|
1080
|
+
This function can also be used for coercion/conversion as follows::
|
|
1081
|
+
|
|
1082
|
+
sage: K = QpLC(2)
|
|
1083
|
+
sage: y = x._copy(K)
|
|
1084
|
+
sage: y
|
|
1085
|
+
1 + O(2^10)
|
|
1086
|
+
sage: y.parent()
|
|
1087
|
+
2-adic Field with lattice-cap precision
|
|
1088
|
+
|
|
1089
|
+
sage: a = K(2, 10); a
|
|
1090
|
+
2 + O(2^10)
|
|
1091
|
+
sage: b = a._copy(R)
|
|
1092
|
+
sage: b
|
|
1093
|
+
2 + O(2^10)
|
|
1094
|
+
sage: b.parent()
|
|
1095
|
+
2-adic Ring with lattice-cap precision
|
|
1096
|
+
|
|
1097
|
+
In any case, precision is sharp::
|
|
1098
|
+
|
|
1099
|
+
sage: x - y
|
|
1100
|
+
O(2^20)
|
|
1101
|
+
sage: a - b
|
|
1102
|
+
O(2^21)
|
|
1103
|
+
|
|
1104
|
+
If a parent is given, it must share the same precision object::
|
|
1105
|
+
|
|
1106
|
+
sage: x._copy(ZpLC(5))
|
|
1107
|
+
Traceback (most recent call last):
|
|
1108
|
+
...
|
|
1109
|
+
TypeError: parent must share the same precision object
|
|
1110
|
+
|
|
1111
|
+
sage: x._copy(Zp(2))
|
|
1112
|
+
Traceback (most recent call last):
|
|
1113
|
+
...
|
|
1114
|
+
TypeError: parent must share the same precision object
|
|
1115
|
+
|
|
1116
|
+
sage: x._copy(ZpLC(2, label='other'))
|
|
1117
|
+
Traceback (most recent call last):
|
|
1118
|
+
...
|
|
1119
|
+
TypeError: parent must share the same precision object
|
|
1120
|
+
|
|
1121
|
+
TESTS::
|
|
1122
|
+
|
|
1123
|
+
sage: K(1/2)._copy(R)
|
|
1124
|
+
Traceback (most recent call last):
|
|
1125
|
+
...
|
|
1126
|
+
ValueError: element of negative valuation cannot be converted to the integer ring
|
|
1127
|
+
"""
|
|
1128
|
+
if parent is None:
|
|
1129
|
+
parent = self._parent
|
|
1130
|
+
else:
|
|
1131
|
+
try:
|
|
1132
|
+
if parent.precision() is not self._parent.precision():
|
|
1133
|
+
raise TypeError("parent must share the same precision object")
|
|
1134
|
+
except AttributeError:
|
|
1135
|
+
raise TypeError("parent must share the same precision object")
|
|
1136
|
+
from sage.rings.padics.generic_nodes import pAdicRingBaseGeneric
|
|
1137
|
+
if isinstance(parent, pAdicRingBaseGeneric) and self.valuation() < 0:
|
|
1138
|
+
raise ValueError("element of negative valuation cannot be converted to the integer ring")
|
|
1139
|
+
dx = [ [ self, self._parent._approx_one ] ]
|
|
1140
|
+
return self.__class__(parent, self._value, dx=dx, check=False)
|
|
1141
|
+
|
|
1142
|
+
def __copy__(self):
|
|
1143
|
+
r"""
|
|
1144
|
+
Return a copy of this element.
|
|
1145
|
+
|
|
1146
|
+
TESTS::
|
|
1147
|
+
|
|
1148
|
+
sage: R = ZpLC(2)
|
|
1149
|
+
sage: x = R(1, 10); x
|
|
1150
|
+
1 + O(2^10)
|
|
1151
|
+
sage: y = copy(x) # indirect doctest
|
|
1152
|
+
sage: y
|
|
1153
|
+
1 + O(2^10)
|
|
1154
|
+
|
|
1155
|
+
sage: x - y
|
|
1156
|
+
O(2^20)
|
|
1157
|
+
"""
|
|
1158
|
+
return self._copy()
|
|
1159
|
+
|
|
1160
|
+
def expansion(self, n=None, lift_mode='simple', start_val=None):
|
|
1161
|
+
r"""
|
|
1162
|
+
Return a list giving the `p`-adic expansion of this element.
|
|
1163
|
+
If this is a field element, start at
|
|
1164
|
+
`p^{\mbox{valuation}}`, if a ring element at `p^0`.
|
|
1165
|
+
|
|
1166
|
+
INPUT:
|
|
1167
|
+
|
|
1168
|
+
- ``n`` -- integer or ``None`` (default: ``None``); if given,
|
|
1169
|
+
return the corresponding entry in the expansion
|
|
1170
|
+
|
|
1171
|
+
- ``lift_mode`` -- string (default: ``'simple'``); currently
|
|
1172
|
+
only ``'simple'`` is implemented
|
|
1173
|
+
|
|
1174
|
+
- ``start_val`` -- integer or ``None`` (default: ``None``);
|
|
1175
|
+
start at this valuation rather than the default (`0` or the
|
|
1176
|
+
valuation of this element).
|
|
1177
|
+
|
|
1178
|
+
EXAMPLES::
|
|
1179
|
+
|
|
1180
|
+
sage: R = ZpLC(5, 10)
|
|
1181
|
+
sage: x = R(123456789); x
|
|
1182
|
+
4 + 2*5 + 5^2 + 4*5^3 + 5^5 + 5^6 + 5^8 + 3*5^9 + O(5^10)
|
|
1183
|
+
sage: x.expansion()
|
|
1184
|
+
[4, 2, 1, 4, 0, 1, 1, 0, 1, 3]
|
|
1185
|
+
|
|
1186
|
+
sage: x.expansion(3)
|
|
1187
|
+
4
|
|
1188
|
+
|
|
1189
|
+
sage: x.expansion(start_val=5)
|
|
1190
|
+
[1, 1, 0, 1, 3]
|
|
1191
|
+
|
|
1192
|
+
If any, trailing zeros are included in the expansion::
|
|
1193
|
+
|
|
1194
|
+
sage: y = R(1234); y
|
|
1195
|
+
4 + 5 + 4*5^2 + 4*5^3 + 5^4 + O(5^10)
|
|
1196
|
+
sage: y.expansion()
|
|
1197
|
+
[4, 1, 4, 4, 1, 0, 0, 0, 0, 0]
|
|
1198
|
+
"""
|
|
1199
|
+
if lift_mode != 'simple':
|
|
1200
|
+
raise NotImplementedError("other modes than 'simple' are not implemented yet")
|
|
1201
|
+
prec = self.precision_absolute()
|
|
1202
|
+
val = self.valuation()
|
|
1203
|
+
expansion = self._value.list(prec)
|
|
1204
|
+
if n is not None:
|
|
1205
|
+
if n < val:
|
|
1206
|
+
return ZZ(0)
|
|
1207
|
+
try:
|
|
1208
|
+
return expansion[n-val]
|
|
1209
|
+
except KeyError:
|
|
1210
|
+
raise PrecisionError("the digit in position %s is not determined" % n)
|
|
1211
|
+
if start_val is None:
|
|
1212
|
+
if self._parent.is_field():
|
|
1213
|
+
start_val = val
|
|
1214
|
+
else:
|
|
1215
|
+
start_val = 0
|
|
1216
|
+
if start_val > val:
|
|
1217
|
+
return expansion[start_val-val:]
|
|
1218
|
+
else:
|
|
1219
|
+
return (val-start_val)*[ZZ(0)] + expansion
|
|
1220
|
+
|
|
1221
|
+
def dist(self, other):
|
|
1222
|
+
r"""
|
|
1223
|
+
Return the distance between this element and ``other``.
|
|
1224
|
+
The distance is normalized so that `dist(0,p) = 1/p`.
|
|
1225
|
+
|
|
1226
|
+
EXAMPLES::
|
|
1227
|
+
|
|
1228
|
+
sage: R = ZpLC(3)
|
|
1229
|
+
sage: x = R(1, 5)
|
|
1230
|
+
sage: y = R(4, 5)
|
|
1231
|
+
sage: x.dist(y)
|
|
1232
|
+
1/3
|
|
1233
|
+
|
|
1234
|
+
TESTS::
|
|
1235
|
+
|
|
1236
|
+
sage: z = R(3^7,10)
|
|
1237
|
+
sage: x
|
|
1238
|
+
1 + O(3^5)
|
|
1239
|
+
sage: x + z
|
|
1240
|
+
1 + O(3^5)
|
|
1241
|
+
sage: x.dist(x+z)
|
|
1242
|
+
1/2187
|
|
1243
|
+
"""
|
|
1244
|
+
x = self - other
|
|
1245
|
+
p = self._parent.prime()
|
|
1246
|
+
if x.is_zero():
|
|
1247
|
+
return ZZ(0)
|
|
1248
|
+
else:
|
|
1249
|
+
return p**(-x.valuation())
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
class pAdicLatticeCapElement(pAdicLatticeElement):
|
|
1253
|
+
def _declare_new_element(self, dx, prec, dx_mode):
|
|
1254
|
+
r"""
|
|
1255
|
+
Declare this element to the precision object and
|
|
1256
|
+
return the precision at which this element can be truncated safely.
|
|
1257
|
+
|
|
1258
|
+
Only for internal use.
|
|
1259
|
+
|
|
1260
|
+
TESTS::
|
|
1261
|
+
|
|
1262
|
+
sage: R = ZpLC(17)
|
|
1263
|
+
sage: prec = R.precision()
|
|
1264
|
+
|
|
1265
|
+
sage: prec.del_elements()
|
|
1266
|
+
sage: nb = len(prec.tracked_elements())
|
|
1267
|
+
sage: x = R(1, 10) # indirect doctest
|
|
1268
|
+
sage: len(prec.tracked_elements()) == nb + 1
|
|
1269
|
+
True
|
|
1270
|
+
"""
|
|
1271
|
+
parent = self._parent
|
|
1272
|
+
cap = min(parent.precision_cap_absolute(), parent.precision_cap_relative() + self._value.valuation())
|
|
1273
|
+
if prec is None or prec > cap:
|
|
1274
|
+
capped = True
|
|
1275
|
+
prec = cap
|
|
1276
|
+
else:
|
|
1277
|
+
capped = False
|
|
1278
|
+
self._precision._new_element(self, dx, bigoh=prec, dx_mode=dx_mode, capped=capped)
|
|
1279
|
+
return prec
|
|
1280
|
+
|
|
1281
|
+
def _is_exact_zero(self):
|
|
1282
|
+
r"""
|
|
1283
|
+
Return ``True`` if this element is exactly zero.
|
|
1284
|
+
|
|
1285
|
+
.. NOTE::
|
|
1286
|
+
|
|
1287
|
+
Since exact zeros are not supported in the precision lattice
|
|
1288
|
+
model, this function always returns ``False``.
|
|
1289
|
+
|
|
1290
|
+
EXAMPLES::
|
|
1291
|
+
|
|
1292
|
+
sage: R = ZpLC(5)
|
|
1293
|
+
sage: R(0)._is_exact_zero()
|
|
1294
|
+
False
|
|
1295
|
+
sage: R(1)._is_exact_zero()
|
|
1296
|
+
False
|
|
1297
|
+
"""
|
|
1298
|
+
return False
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
class pAdicLatticeFloatElement(pAdicLatticeElement):
|
|
1302
|
+
def _declare_new_element(self, dx, prec, dx_mode):
|
|
1303
|
+
r"""
|
|
1304
|
+
Declare this element to the precision object and
|
|
1305
|
+
return the precision at which this element can be truncated safely.
|
|
1306
|
+
|
|
1307
|
+
Only for internal use.
|
|
1308
|
+
|
|
1309
|
+
TESTS::
|
|
1310
|
+
|
|
1311
|
+
sage: R = ZpLF(17)
|
|
1312
|
+
sage: prec = R.precision()
|
|
1313
|
+
|
|
1314
|
+
sage: prec.del_elements()
|
|
1315
|
+
sage: nb = len(prec.tracked_elements())
|
|
1316
|
+
sage: x = R(1, 10) # indirect doctest
|
|
1317
|
+
sage: len(prec.tracked_elements()) == nb + 1
|
|
1318
|
+
True
|
|
1319
|
+
"""
|
|
1320
|
+
self._precision._new_element(self, dx, bigoh=prec, dx_mode=dx_mode)
|
|
1321
|
+
cap = self._precision.internal_prec() + self._value.valuation()
|
|
1322
|
+
if prec is None:
|
|
1323
|
+
return cap
|
|
1324
|
+
else:
|
|
1325
|
+
return min(cap, prec)
|
|
1326
|
+
|
|
1327
|
+
def _is_exact_zero(self):
|
|
1328
|
+
r"""
|
|
1329
|
+
Return ``True`` if this element is exactly zero.
|
|
1330
|
+
|
|
1331
|
+
EXAMPLES::
|
|
1332
|
+
|
|
1333
|
+
sage: R = ZpLF(5)
|
|
1334
|
+
sage: R(0)._is_exact_zero()
|
|
1335
|
+
True
|
|
1336
|
+
sage: R(0, 10)._is_exact_zero()
|
|
1337
|
+
False
|
|
1338
|
+
|
|
1339
|
+
sage: R(1)._is_exact_zero()
|
|
1340
|
+
False
|
|
1341
|
+
"""
|
|
1342
|
+
return self._value.is_zero() and self._precision._precision_absolute(self) is Infinity
|