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,3623 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
r"""
|
|
3
|
+
Factory
|
|
4
|
+
|
|
5
|
+
This file contains the constructor classes and functions for `p`-adic rings and fields.
|
|
6
|
+
|
|
7
|
+
AUTHORS:
|
|
8
|
+
|
|
9
|
+
- David Roe
|
|
10
|
+
|
|
11
|
+
TESTS::
|
|
12
|
+
|
|
13
|
+
sage: R = ZpLC(2)
|
|
14
|
+
doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation.
|
|
15
|
+
See https://github.com/sagemath/sage/issues/23505 for details.
|
|
16
|
+
sage: R = ZpLF(2)
|
|
17
|
+
sage: R = QpLC(2)
|
|
18
|
+
sage: R = QpLF(2)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
# ****************************************************************************
|
|
22
|
+
# Copyright (C) 2007-2013 David Roe <roed.math@gmail.com>
|
|
23
|
+
# William Stein <wstein@gmail.com>
|
|
24
|
+
#
|
|
25
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
26
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
27
|
+
# the License, or (at your option) any later version.
|
|
28
|
+
#
|
|
29
|
+
# https://www.gnu.org/licenses/
|
|
30
|
+
# ****************************************************************************
|
|
31
|
+
|
|
32
|
+
from sage.misc.superseded import experimental
|
|
33
|
+
|
|
34
|
+
from sage.categories.fields import Fields
|
|
35
|
+
from sage.structure.factory import UniqueFactory
|
|
36
|
+
from sage.rings.integer import Integer
|
|
37
|
+
from sage.rings.infinity import Infinity
|
|
38
|
+
from sage.structure.factorization import Factorization
|
|
39
|
+
from sage.rings.integer_ring import ZZ
|
|
40
|
+
from sage.rings.polynomial.polynomial_element import Polynomial
|
|
41
|
+
from sage.structure.element import Element
|
|
42
|
+
from .padic_base_leaves import (pAdicRingCappedRelative,
|
|
43
|
+
pAdicRingCappedAbsolute,
|
|
44
|
+
pAdicRingFixedMod,
|
|
45
|
+
pAdicRingFloatingPoint,
|
|
46
|
+
pAdicRingLattice,
|
|
47
|
+
pAdicRingRelaxed,
|
|
48
|
+
pAdicFieldCappedRelative,
|
|
49
|
+
pAdicFieldFloatingPoint,
|
|
50
|
+
pAdicFieldLattice,
|
|
51
|
+
pAdicFieldRelaxed)
|
|
52
|
+
from . import padic_printing
|
|
53
|
+
|
|
54
|
+
######################################################
|
|
55
|
+
# ext_table --
|
|
56
|
+
# This dictionary controls what class is created by the extension
|
|
57
|
+
# factory when it finds a given class in the ground ring of the tower.
|
|
58
|
+
######################################################
|
|
59
|
+
|
|
60
|
+
from .padic_extension_leaves import (EisensteinExtensionFieldCappedRelative,
|
|
61
|
+
EisensteinExtensionRingFixedMod,
|
|
62
|
+
EisensteinExtensionRingCappedAbsolute,
|
|
63
|
+
EisensteinExtensionRingCappedRelative,
|
|
64
|
+
UnramifiedExtensionFieldCappedRelative,
|
|
65
|
+
UnramifiedExtensionRingCappedRelative,
|
|
66
|
+
UnramifiedExtensionRingCappedAbsolute,
|
|
67
|
+
UnramifiedExtensionRingFixedMod,
|
|
68
|
+
UnramifiedExtensionFieldFloatingPoint,
|
|
69
|
+
UnramifiedExtensionRingFloatingPoint)
|
|
70
|
+
from .relative_extension_leaves import \
|
|
71
|
+
(RelativeRamifiedExtensionRingFixedMod,
|
|
72
|
+
RelativeRamifiedExtensionRingCappedAbsolute,
|
|
73
|
+
RelativeRamifiedExtensionRingCappedRelative,
|
|
74
|
+
RelativeRamifiedExtensionFieldCappedRelative,
|
|
75
|
+
RelativeRamifiedExtensionRingFloatingPoint,
|
|
76
|
+
RelativeRamifiedExtensionFieldFloatingPoint)
|
|
77
|
+
from functools import reduce
|
|
78
|
+
#This imports all of the classes used in the ext_table below.
|
|
79
|
+
|
|
80
|
+
ext_table = {}
|
|
81
|
+
ext_table['e', pAdicFieldCappedRelative] = EisensteinExtensionFieldCappedRelative
|
|
82
|
+
ext_table['e', pAdicRingCappedAbsolute] = EisensteinExtensionRingCappedAbsolute
|
|
83
|
+
ext_table['e', pAdicRingCappedRelative] = EisensteinExtensionRingCappedRelative
|
|
84
|
+
ext_table['e', pAdicRingFixedMod] = EisensteinExtensionRingFixedMod
|
|
85
|
+
#ext_table['e', pAdicRingFloatingPoint] = EisensteinExtensionRingFloatingPoint
|
|
86
|
+
#ext_table['e', pAdicFieldFloatingPoint] = EisensteinExtensionFieldFloatingPoint
|
|
87
|
+
#ext_table['p', pAdicFieldCappedRelative] = pAdicGeneralExtensionFieldCappedRelative
|
|
88
|
+
#ext_table['p', pAdicRingCappedAbsolute] = pAdicGeneralExtensionRingCappedAbsolute
|
|
89
|
+
#ext_table['p', pAdicRingCappedRelative] = pAdicGeneralExtensionRingCappedRelative
|
|
90
|
+
#ext_table['p', pAdicRingFixedMod] = pAdicGeneralExtensionRingFixedMod
|
|
91
|
+
ext_table['u', pAdicFieldCappedRelative] = UnramifiedExtensionFieldCappedRelative
|
|
92
|
+
ext_table['u', pAdicRingCappedAbsolute] = UnramifiedExtensionRingCappedAbsolute
|
|
93
|
+
ext_table['u', pAdicRingCappedRelative] = UnramifiedExtensionRingCappedRelative
|
|
94
|
+
ext_table['u', pAdicRingFixedMod] = UnramifiedExtensionRingFixedMod
|
|
95
|
+
ext_table['u', pAdicRingFloatingPoint] = UnramifiedExtensionRingFloatingPoint
|
|
96
|
+
ext_table['u', pAdicFieldFloatingPoint] = UnramifiedExtensionFieldFloatingPoint
|
|
97
|
+
ext_table['re', pAdicRingFixedMod] = RelativeRamifiedExtensionRingFixedMod
|
|
98
|
+
ext_table['re', pAdicRingCappedAbsolute] = RelativeRamifiedExtensionRingCappedAbsolute
|
|
99
|
+
ext_table['re', pAdicRingCappedRelative] = RelativeRamifiedExtensionRingCappedRelative
|
|
100
|
+
ext_table['re', pAdicFieldCappedRelative] = RelativeRamifiedExtensionFieldCappedRelative
|
|
101
|
+
ext_table['re', pAdicRingFloatingPoint] = RelativeRamifiedExtensionRingFloatingPoint
|
|
102
|
+
ext_table['re', pAdicFieldFloatingPoint] = RelativeRamifiedExtensionFieldFloatingPoint
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _canonicalize_show_prec(type, print_mode, show_prec=None):
|
|
106
|
+
r"""
|
|
107
|
+
Return a canonical string value for show_prec depending of the type,
|
|
108
|
+
the print_mode and the given value.
|
|
109
|
+
|
|
110
|
+
INPUT:
|
|
111
|
+
|
|
112
|
+
- ``type`` -- string; ``'capped-rel'``, ``'capped-abs'``, ``'fixed-mod'``,
|
|
113
|
+
``'floating-point'``, ``'lattice-cap'`` or ``'lattice-float'``
|
|
114
|
+
|
|
115
|
+
- ``print_mode`` -- string; ``'series'``, ``'terse'``, ``'val-unit'``,
|
|
116
|
+
``'digits'``, ``'bars'``
|
|
117
|
+
|
|
118
|
+
- ``show_prec`` -- boolean, string, or ``None``
|
|
119
|
+
|
|
120
|
+
OUTPUT: string; either ``'bigoh'``, ``'dots'`` or ``'none'``
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: from sage.rings.padics.factory import _canonicalize_show_prec
|
|
125
|
+
sage: _canonicalize_show_prec('floating-point', 'series')
|
|
126
|
+
'none'
|
|
127
|
+
|
|
128
|
+
sage: _canonicalize_show_prec('capped-rel', 'series')
|
|
129
|
+
'bigoh'
|
|
130
|
+
sage: _canonicalize_show_prec('capped-rel', 'series', False)
|
|
131
|
+
'none'
|
|
132
|
+
|
|
133
|
+
sage: _canonicalize_show_prec('capped-abs', 'digits')
|
|
134
|
+
'dots'
|
|
135
|
+
sage: _canonicalize_show_prec('capped-abs', 'digits', 'bigoh')
|
|
136
|
+
'bigoh'
|
|
137
|
+
|
|
138
|
+
TESTS::
|
|
139
|
+
|
|
140
|
+
sage: _canonicalize_show_prec('capped-abs', 'digits', 'my_precision')
|
|
141
|
+
Traceback (most recent call last):
|
|
142
|
+
...
|
|
143
|
+
ValueError: show_prec must be either a boolean, 'none', 'bigoh' or 'dots' when printing mode is digits
|
|
144
|
+
"""
|
|
145
|
+
# Note that None means "choose the default for this ring", while 'none' means "don't print precision".
|
|
146
|
+
if show_prec is None:
|
|
147
|
+
show_prec = type not in ('floating-point', 'fixed-mod')
|
|
148
|
+
if show_prec is False:
|
|
149
|
+
return "none"
|
|
150
|
+
if show_prec is True:
|
|
151
|
+
if print_mode in ('series', 'terse', 'val-unit'):
|
|
152
|
+
return "bigoh"
|
|
153
|
+
else:
|
|
154
|
+
return "dots"
|
|
155
|
+
if print_mode in ('series', 'terse', 'val-unit'):
|
|
156
|
+
if show_prec not in ('none', 'bigoh'):
|
|
157
|
+
raise ValueError("show_prec must be either a boolean, 'none' or 'bigoh' when printing mode is %s" % print_mode)
|
|
158
|
+
else:
|
|
159
|
+
if show_prec not in ('none', 'bigoh', 'dots'):
|
|
160
|
+
raise ValueError("show_prec must be either a boolean, 'none', 'bigoh' or 'dots' when printing mode is %s" % print_mode)
|
|
161
|
+
return show_prec
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def get_key_base(p, prec, type, print_mode, names, ram_name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, check, valid_types, label=None):
|
|
165
|
+
r"""
|
|
166
|
+
This implements ``create_key`` for ``Zp`` and ``Qp``: moving it here prevents code duplication.
|
|
167
|
+
|
|
168
|
+
It fills in unspecified values and checks for contradictions in the input. It also standardizes irrelevant options so that duplicate parents are not created.
|
|
169
|
+
|
|
170
|
+
EXAMPLES::
|
|
171
|
+
|
|
172
|
+
sage: from sage.rings.padics.factory import get_key_base
|
|
173
|
+
sage: get_key_base(11, 5, 'capped-rel', None, None, None, None, ':', None, None, False, True, ['capped-rel'])
|
|
174
|
+
(11, 5, 'capped-rel', 'series', '11', True, '|', (), -1, 'none', None)
|
|
175
|
+
sage: get_key_base(12, 5, 'capped-rel', 'digits', None, None, None, None, None, None, True, False, ['capped-rel'])
|
|
176
|
+
(12,
|
|
177
|
+
5,
|
|
178
|
+
'capped-rel',
|
|
179
|
+
'digits',
|
|
180
|
+
'12',
|
|
181
|
+
True,
|
|
182
|
+
'|',
|
|
183
|
+
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'),
|
|
184
|
+
-1,
|
|
185
|
+
'dots',
|
|
186
|
+
None)
|
|
187
|
+
"""
|
|
188
|
+
if check:
|
|
189
|
+
if not isinstance(p, Integer):
|
|
190
|
+
p = Integer(p)
|
|
191
|
+
if not p.is_prime():
|
|
192
|
+
raise ValueError("p must be prime")
|
|
193
|
+
if type == 'lattice-cap':
|
|
194
|
+
relative_cap = absolute_cap = None
|
|
195
|
+
if prec is not None:
|
|
196
|
+
try:
|
|
197
|
+
relative_cap, absolute_cap = prec
|
|
198
|
+
except (ValueError, TypeError):
|
|
199
|
+
relative_cap = prec
|
|
200
|
+
if relative_cap is not None:
|
|
201
|
+
if relative_cap is not Infinity:
|
|
202
|
+
try:
|
|
203
|
+
relative_cap = Integer(relative_cap)
|
|
204
|
+
except TypeError:
|
|
205
|
+
raise TypeError("relative cap must be either a positive integer or infinity")
|
|
206
|
+
if relative_cap <= 0:
|
|
207
|
+
raise ValueError("relative cap must be positive")
|
|
208
|
+
if absolute_cap is not None:
|
|
209
|
+
try:
|
|
210
|
+
absolute_cap = Integer(absolute_cap)
|
|
211
|
+
except TypeError:
|
|
212
|
+
raise TypeError("absolute cap must be an integer")
|
|
213
|
+
if relative_cap is None and absolute_cap is None:
|
|
214
|
+
relative_cap = DEFAULT_PREC
|
|
215
|
+
absolute_cap = 2 * DEFAULT_PREC
|
|
216
|
+
elif relative_cap is None:
|
|
217
|
+
relative_cap = Infinity
|
|
218
|
+
elif absolute_cap is None:
|
|
219
|
+
absolute_cap = 2 * relative_cap
|
|
220
|
+
prec = (relative_cap, absolute_cap)
|
|
221
|
+
elif type == 'relaxed':
|
|
222
|
+
default_prec = halting_prec = None
|
|
223
|
+
secure = False
|
|
224
|
+
if isinstance(prec, (list, tuple)):
|
|
225
|
+
if len(prec) == 1:
|
|
226
|
+
default_prec = prec
|
|
227
|
+
elif len(prec) == 2:
|
|
228
|
+
default_prec, halting_prec = prec
|
|
229
|
+
else:
|
|
230
|
+
default_prec = prec[0]
|
|
231
|
+
halting_prec = prec[1]
|
|
232
|
+
secure = prec[2]
|
|
233
|
+
else:
|
|
234
|
+
default_prec = prec
|
|
235
|
+
if default_prec is None:
|
|
236
|
+
default_prec = DEFAULT_PREC
|
|
237
|
+
if halting_prec is None:
|
|
238
|
+
halting_prec = 2 * default_prec
|
|
239
|
+
halting_prec = max(default_prec, halting_prec)
|
|
240
|
+
prec = (default_prec, halting_prec, secure)
|
|
241
|
+
else:
|
|
242
|
+
if prec is not None:
|
|
243
|
+
prec = Integer(prec)
|
|
244
|
+
if prec is None:
|
|
245
|
+
if type == 'lattice-cap':
|
|
246
|
+
prec = (DEFAULT_PREC, 2*DEFAULT_PREC)
|
|
247
|
+
else:
|
|
248
|
+
prec = DEFAULT_PREC
|
|
249
|
+
print_ram_name = ram_name
|
|
250
|
+
if isinstance(print_mode, dict):
|
|
251
|
+
if 'pos' in print_mode:
|
|
252
|
+
print_pos = print_mode['pos']
|
|
253
|
+
if 'ram_name' in print_mode:
|
|
254
|
+
print_ram_name = print_mode['ram_name']
|
|
255
|
+
if 'unram_name' in print_mode:
|
|
256
|
+
# print_unram_name = print_mode['unram_name']
|
|
257
|
+
pass
|
|
258
|
+
if 'sep' in print_mode:
|
|
259
|
+
print_sep = print_mode['sep']
|
|
260
|
+
if 'alphabet' in print_mode:
|
|
261
|
+
print_alphabet = print_mode['alphabet']
|
|
262
|
+
if 'max_ram_terms' in print_mode:
|
|
263
|
+
print_max_terms = print_mode['max_ram_terms']
|
|
264
|
+
if 'max_terms' in print_mode:
|
|
265
|
+
print_max_terms = print_mode['max_terms']
|
|
266
|
+
if 'show_prec' in print_mode:
|
|
267
|
+
show_prec = print_mode['show_prec']
|
|
268
|
+
if 'mode' in print_mode:
|
|
269
|
+
print_mode = print_mode['mode']
|
|
270
|
+
else:
|
|
271
|
+
print_mode = None
|
|
272
|
+
if print_mode is None:
|
|
273
|
+
print_mode = padic_printing._printer_defaults.mode()
|
|
274
|
+
if print_pos is None:
|
|
275
|
+
print_pos = not padic_printing._printer_defaults.allow_negatives()
|
|
276
|
+
if print_sep is None:
|
|
277
|
+
print_sep = padic_printing._printer_defaults.sep()
|
|
278
|
+
if print_alphabet is None:
|
|
279
|
+
print_alphabet = padic_printing._printer_defaults.alphabet()
|
|
280
|
+
if print_max_terms is None:
|
|
281
|
+
print_max_terms = padic_printing._printer_defaults.max_series_terms()
|
|
282
|
+
|
|
283
|
+
# We eliminate irrelevant print options (e.g. print_pos if p = 2)
|
|
284
|
+
if p == 2 or print_mode == 'digits':
|
|
285
|
+
print_pos = True # we want this hard-coded so that we don't get duplicate parents if the keys differ.
|
|
286
|
+
if print_mode == 'digits':
|
|
287
|
+
print_ram_name = None
|
|
288
|
+
print_alphabet = print_alphabet[:p]
|
|
289
|
+
else:
|
|
290
|
+
print_alphabet = []
|
|
291
|
+
if print_mode != 'bars':
|
|
292
|
+
print_sep = '|'
|
|
293
|
+
if print_mode in ['terse', 'val-unit']:
|
|
294
|
+
print_max_terms = -1
|
|
295
|
+
|
|
296
|
+
if isinstance(names, tuple):
|
|
297
|
+
names = names[0]
|
|
298
|
+
if names is None and print_ram_name is None:
|
|
299
|
+
name = str(p)
|
|
300
|
+
elif names is not None and print_ram_name is not None:
|
|
301
|
+
if not isinstance(names, str):
|
|
302
|
+
names = str(names)
|
|
303
|
+
if not isinstance(print_ram_name, str):
|
|
304
|
+
print_ram_name = str(print_ram_name)
|
|
305
|
+
if names != print_ram_name:
|
|
306
|
+
raise ValueError("If both names (%s) and print_ram_name (%s) are specified, they must agree" % (names, print_ram_name))
|
|
307
|
+
name = names
|
|
308
|
+
else:
|
|
309
|
+
if names is None:
|
|
310
|
+
names = print_ram_name
|
|
311
|
+
if isinstance(names, str):
|
|
312
|
+
name = names
|
|
313
|
+
else:
|
|
314
|
+
name = str(names)
|
|
315
|
+
if type not in valid_types:
|
|
316
|
+
raise ValueError("type must be %s" % (", ".join(valid_types)))
|
|
317
|
+
show_prec = _canonicalize_show_prec(type, print_mode, show_prec)
|
|
318
|
+
key = (p, prec, type, print_mode, name, print_pos, print_sep, tuple(print_alphabet), print_max_terms, show_prec, label)
|
|
319
|
+
return key
|
|
320
|
+
|
|
321
|
+
#######################################################################################################
|
|
322
|
+
#
|
|
323
|
+
# p-adic Fields
|
|
324
|
+
# Qp -- base field
|
|
325
|
+
# Qq -- unramified extension field of Qp
|
|
326
|
+
# QpCR, QpLC, QpLF, QqCR -- shortcuts for capped relative and lattice versions of Qp and Qq
|
|
327
|
+
#
|
|
328
|
+
#######################################################################################################
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
padic_field_cache = {}
|
|
332
|
+
DEFAULT_PREC = Integer(20)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
class Qp_class(UniqueFactory):
|
|
336
|
+
r"""
|
|
337
|
+
A creation function for `p`-adic fields.
|
|
338
|
+
|
|
339
|
+
INPUT:
|
|
340
|
+
|
|
341
|
+
- ``p`` -- integer; the `p` in `\QQ_p`
|
|
342
|
+
|
|
343
|
+
- ``prec`` -- integer (default: 20); the precision cap of the field.
|
|
344
|
+
In the lattice capped case, ``prec`` can either be a
|
|
345
|
+
pair (``relative_cap``, ``absolute_cap``) or an integer
|
|
346
|
+
(understood at relative cap).
|
|
347
|
+
In the relaxed case, ``prec`` can be either a
|
|
348
|
+
pair (``default_prec``, ``halting_prec``) or an integer
|
|
349
|
+
(understood at default precision).
|
|
350
|
+
Except in the floating point case, individual elements keep track of
|
|
351
|
+
their own precision. See TYPES and PRECISION below.
|
|
352
|
+
|
|
353
|
+
- ``type`` -- string (default: ``'capped-rel'``); valid types are
|
|
354
|
+
``'capped-rel'``, ``'floating-point'``, ``'lattice-cap'``,
|
|
355
|
+
``'lattice-float'``. See TYPES and PRECISION below.
|
|
356
|
+
|
|
357
|
+
- ``print_mode`` -- string (default: ``None``); valid modes are
|
|
358
|
+
``'series'``, ``'val-unit'``, ``'terse'``, ``'digits'``, and ``'bars'``.
|
|
359
|
+
See PRINTING below.
|
|
360
|
+
|
|
361
|
+
- ``names`` -- string or tuple (defaults to a string representation of
|
|
362
|
+
`p`); what to use whenever `p` is printed
|
|
363
|
+
|
|
364
|
+
- ``ram_name`` -- string; another way to specify the name. For
|
|
365
|
+
consistency with the ``Qq`` and ``Zq`` and extension functions.
|
|
366
|
+
|
|
367
|
+
- ``print_pos`` -- boolean (default: ``None``); whether to only use
|
|
368
|
+
positive integers in the representations of elements. See PRINTING below.
|
|
369
|
+
|
|
370
|
+
- ``print_sep`` -- string (default: ``None``); the separator character used
|
|
371
|
+
in the ``'bars'`` mode. See PRINTING below.
|
|
372
|
+
|
|
373
|
+
- ``print_alphabet`` -- tuple (default: ``None``); the encoding into digits
|
|
374
|
+
for use in the 'digits' mode. See PRINTING below.
|
|
375
|
+
|
|
376
|
+
- ``print_max_terms`` -- integer (default: ``None``); the maximum number of
|
|
377
|
+
terms shown. See PRINTING below.
|
|
378
|
+
|
|
379
|
+
- ``show_prec`` -- boolean or a string (default: ``None``); specify how
|
|
380
|
+
the precision is printed. See PRINTING below.
|
|
381
|
+
|
|
382
|
+
- ``check`` -- boolean (default: ``True``); whether to check if `p` is prime.
|
|
383
|
+
Non-prime input may cause seg-faults (but can also be useful for
|
|
384
|
+
base n expansions for example).
|
|
385
|
+
|
|
386
|
+
- ``label`` -- string (default: ``None``); used for lattice precision to
|
|
387
|
+
create parents with different lattices
|
|
388
|
+
|
|
389
|
+
OUTPUT: the corresponding `p`-adic field
|
|
390
|
+
|
|
391
|
+
TYPES AND PRECISION:
|
|
392
|
+
|
|
393
|
+
There are two main types of precision for a `p`-adic element.
|
|
394
|
+
The first is relative precision, which gives the number of known
|
|
395
|
+
`p`-adic digits::
|
|
396
|
+
|
|
397
|
+
sage: R = Qp(5, 20, 'capped-rel', 'series'); a = R(675); a
|
|
398
|
+
2*5^2 + 5^4 + O(5^22)
|
|
399
|
+
sage: a.precision_relative()
|
|
400
|
+
20
|
|
401
|
+
|
|
402
|
+
The second type of precision is absolute precision, which gives
|
|
403
|
+
the power of `p` that this element is defined modulo::
|
|
404
|
+
|
|
405
|
+
sage: a.precision_absolute()
|
|
406
|
+
22
|
|
407
|
+
|
|
408
|
+
There are several types of `p`-adic fields, depending on the methods
|
|
409
|
+
used for tracking precision. Namely, we have:
|
|
410
|
+
|
|
411
|
+
- capped relative fields (``type='capped-rel'``)
|
|
412
|
+
|
|
413
|
+
- capped absolute fields (``type='capped-abs'``)
|
|
414
|
+
|
|
415
|
+
- fixed modulus fields (``type='fixed-mod'``)
|
|
416
|
+
|
|
417
|
+
- floating point fields (``type='floating-point'``)
|
|
418
|
+
|
|
419
|
+
- lattice precision fields (``type='lattice-cap'`` or ``type='lattice-float'``)
|
|
420
|
+
|
|
421
|
+
- exact fields with relaxed arithmetics (``type='relaxed'``)
|
|
422
|
+
|
|
423
|
+
In the capped relative case, the relative precision of an element
|
|
424
|
+
is restricted to be at most a certain value, specified at the
|
|
425
|
+
creation of the field. Individual elements also store their own
|
|
426
|
+
precision, so the effect of various arithmetic operations on
|
|
427
|
+
precision is tracked. When you cast an exact element into a
|
|
428
|
+
capped relative field, it truncates it to the precision cap of the
|
|
429
|
+
field. ::
|
|
430
|
+
|
|
431
|
+
sage: R = Qp(5, 5, 'capped-rel', 'series'); a = R(4006); a
|
|
432
|
+
1 + 5 + 2*5^3 + 5^4 + O(5^5)
|
|
433
|
+
sage: b = R(4025); b
|
|
434
|
+
5^2 + 2*5^3 + 5^4 + 5^5 + O(5^7)
|
|
435
|
+
sage: a + b
|
|
436
|
+
1 + 5 + 5^2 + 4*5^3 + 2*5^4 + O(5^5)
|
|
437
|
+
|
|
438
|
+
In the floating point case, elements do not track their
|
|
439
|
+
precision, but the relative precision of elements is truncated
|
|
440
|
+
during arithmetic to the precision cap of the field.
|
|
441
|
+
|
|
442
|
+
In the lattice case, precision on elements is tracked by a global
|
|
443
|
+
lattice that is updated after every operation, yielding better
|
|
444
|
+
precision behavior at the cost of higher memory and runtime usage.
|
|
445
|
+
We refer to the documentation of the function :func:`ZpLC` for a
|
|
446
|
+
small demonstration of the capabilities of this precision model.
|
|
447
|
+
|
|
448
|
+
Finally, the model for relaxed `p`-adics is quite different from any of
|
|
449
|
+
the other types. In addition to storing a finite approximation, one
|
|
450
|
+
also stores a method for increasing the precision.
|
|
451
|
+
A quite interesting feature with relaxed `p`-adics is the possibility to
|
|
452
|
+
create (in some cases) self-referent numbers, that are numbers whose
|
|
453
|
+
`n`-th digit is defined by the previous ones.
|
|
454
|
+
We refer to the documentation of the function :func:`ZpL` for a
|
|
455
|
+
small demonstration of the capabilities of this precision model.
|
|
456
|
+
|
|
457
|
+
PRINTING:
|
|
458
|
+
|
|
459
|
+
There are many different ways to print `p`-adic elements. The way
|
|
460
|
+
elements of a given field print is controlled by options passed in
|
|
461
|
+
at the creation of the field. There are five basic printing modes
|
|
462
|
+
(series, val-unit, terse, digits and bars), as well as various
|
|
463
|
+
options that either hide some information in the print
|
|
464
|
+
representation or sometimes make print representations more
|
|
465
|
+
compact. Note that the printing options affect whether different
|
|
466
|
+
`p`-adic fields are considered equal.
|
|
467
|
+
|
|
468
|
+
1. **series**: elements are displayed as series in `p`. ::
|
|
469
|
+
|
|
470
|
+
sage: R = Qp(5, print_mode='series'); a = R(70700); a
|
|
471
|
+
3*5^2 + 3*5^4 + 2*5^5 + 4*5^6 + O(5^22)
|
|
472
|
+
sage: b = R(-70700); b
|
|
473
|
+
2*5^2 + 4*5^3 + 5^4 + 2*5^5 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11
|
|
474
|
+
+ 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + 4*5^17 + 4*5^18
|
|
475
|
+
+ 4*5^19 + 4*5^20 + 4*5^21 + O(5^22)
|
|
476
|
+
|
|
477
|
+
*print_pos* controls whether negatives can be used in the
|
|
478
|
+
coefficients of powers of `p`. ::
|
|
479
|
+
|
|
480
|
+
sage: S = Qp(5, print_mode='series', print_pos=False); a = S(70700); a
|
|
481
|
+
-2*5^2 + 5^3 - 2*5^4 - 2*5^5 + 5^7 + O(5^22)
|
|
482
|
+
sage: b = S(-70700); b
|
|
483
|
+
2*5^2 - 5^3 + 2*5^4 + 2*5^5 - 5^7 + O(5^22)
|
|
484
|
+
|
|
485
|
+
*print_max_terms* limits the number of terms that appear. ::
|
|
486
|
+
|
|
487
|
+
sage: T = Qp(5, print_mode='series', print_max_terms=4); b = R(-70700); repr(b)
|
|
488
|
+
'2*5^2 + 4*5^3 + 5^4 + 2*5^5 + ... + O(5^22)'
|
|
489
|
+
|
|
490
|
+
*names* affects how the prime is printed. ::
|
|
491
|
+
|
|
492
|
+
sage: U.<p> = Qp(5); p
|
|
493
|
+
p + O(p^21)
|
|
494
|
+
|
|
495
|
+
*show_prec* determines how the precision is printed.
|
|
496
|
+
It can be either 'none' (or equivalently ``False``), 'bigoh'
|
|
497
|
+
(or equivalently ``True``) or 'bigoh'.
|
|
498
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
499
|
+
and ``True`` for all other types. ::
|
|
500
|
+
|
|
501
|
+
sage: Qp(5)(6)
|
|
502
|
+
1 + 5 + O(5^20)
|
|
503
|
+
sage: Qp(5, show_prec='none')(6)
|
|
504
|
+
1 + 5
|
|
505
|
+
|
|
506
|
+
sage: QpFP(5)(6)
|
|
507
|
+
1 + 5
|
|
508
|
+
|
|
509
|
+
*print_sep* and *print_alphabet* have no effect in series mode.
|
|
510
|
+
|
|
511
|
+
Note that print options affect equality::
|
|
512
|
+
|
|
513
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U
|
|
514
|
+
(False, False, False, False, False, False)
|
|
515
|
+
|
|
516
|
+
2. **val-unit**: elements are displayed as p^k*u::
|
|
517
|
+
|
|
518
|
+
sage: R = Qp(5, print_mode='val-unit'); a = R(70700); a
|
|
519
|
+
5^2 * 2828 + O(5^22)
|
|
520
|
+
sage: b = R(-707/5); b
|
|
521
|
+
5^-1 * 95367431639918 + O(5^19)
|
|
522
|
+
|
|
523
|
+
*print_pos* controls whether to use a balanced representation or
|
|
524
|
+
not. ::
|
|
525
|
+
|
|
526
|
+
sage: S = Qp(5, print_mode='val-unit', print_pos=False); b = S(-70700); b
|
|
527
|
+
5^2 * (-2828) + O(5^22)
|
|
528
|
+
|
|
529
|
+
*names* affects how the prime is printed. ::
|
|
530
|
+
|
|
531
|
+
sage: T = Qp(5, print_mode='val-unit', names='pi'); a = T(70700); a
|
|
532
|
+
pi^2 * 2828 + O(pi^22)
|
|
533
|
+
|
|
534
|
+
*show_prec* determines how the precision is printed.
|
|
535
|
+
It can be either 'none' (or equivalently ``False``) or 'bigoh'
|
|
536
|
+
(or equivalently ``True``).
|
|
537
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
538
|
+
and ``True`` for all other types. ::
|
|
539
|
+
|
|
540
|
+
sage: Qp(5, print_mode='val-unit', show_prec=False)(30)
|
|
541
|
+
5 * 6
|
|
542
|
+
|
|
543
|
+
*print_max_terms*, *print_sep* and *print_alphabet* have no effect.
|
|
544
|
+
|
|
545
|
+
Equality again depends on the printing options::
|
|
546
|
+
|
|
547
|
+
sage: R == S, R == T, S == T
|
|
548
|
+
(False, False, False)
|
|
549
|
+
|
|
550
|
+
3. **terse**: elements are displayed as an integer in base 10 or the
|
|
551
|
+
quotient of an integer by a power of `p` (still in base 10)::
|
|
552
|
+
|
|
553
|
+
sage: R = Qp(5, print_mode='terse'); a = R(70700); a
|
|
554
|
+
70700 + O(5^22)
|
|
555
|
+
sage: b = R(-70700); b
|
|
556
|
+
2384185790944925 + O(5^22)
|
|
557
|
+
sage: c = R(-707/5); c
|
|
558
|
+
95367431639918/5 + O(5^19)
|
|
559
|
+
|
|
560
|
+
The denominator, as of version 3.3, is always printed
|
|
561
|
+
explicitly as a power of `p`, for predictability. ::
|
|
562
|
+
|
|
563
|
+
sage: d = R(707/5^2); d
|
|
564
|
+
707/5^2 + O(5^18)
|
|
565
|
+
|
|
566
|
+
*print_pos* controls whether to use a balanced representation or not. ::
|
|
567
|
+
|
|
568
|
+
sage: S = Qp(5, print_mode='terse', print_pos=False); b = S(-70700); b
|
|
569
|
+
-70700 + O(5^22)
|
|
570
|
+
sage: c = S(-707/5); c
|
|
571
|
+
-707/5 + O(5^19)
|
|
572
|
+
|
|
573
|
+
*name* affects how the name is printed. ::
|
|
574
|
+
|
|
575
|
+
sage: T.<unif> = Qp(5, print_mode='terse'); c = T(-707/5); c
|
|
576
|
+
95367431639918/unif + O(unif^19)
|
|
577
|
+
sage: d = T(-707/5^10); d
|
|
578
|
+
95367431639918/unif^10 + O(unif^10)
|
|
579
|
+
|
|
580
|
+
*show_prec* determines how the precision is printed.
|
|
581
|
+
It can be either 'none' (or equivalently ``False``) or 'bigoh'
|
|
582
|
+
(or equivalently ``True``).
|
|
583
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
584
|
+
and ``True`` for all other types. ::
|
|
585
|
+
|
|
586
|
+
sage: Qp(5, print_mode='terse', show_prec=False)(6)
|
|
587
|
+
6
|
|
588
|
+
|
|
589
|
+
*print_max_terms*, *print_sep* and *print_alphabet* have no effect.
|
|
590
|
+
|
|
591
|
+
Equality depends on printing options::
|
|
592
|
+
|
|
593
|
+
sage: R == S, R == T, S == T
|
|
594
|
+
(False, False, False)
|
|
595
|
+
|
|
596
|
+
4. **digits**: elements are displayed as a string of base `p` digits
|
|
597
|
+
|
|
598
|
+
Restriction: you can only use the digits printing mode for
|
|
599
|
+
small primes. Namely, `p` must be less than the length of the
|
|
600
|
+
alphabet tuple (default alphabet has length 62). ::
|
|
601
|
+
|
|
602
|
+
sage: R = Qp(5, print_mode='digits'); a = R(70700); repr(a)
|
|
603
|
+
'...0000000000000004230300'
|
|
604
|
+
sage: b = R(-70700); repr(b)
|
|
605
|
+
'...4444444444444440214200'
|
|
606
|
+
sage: c = R(-707/5); repr(c)
|
|
607
|
+
'...4444444444444443413.3'
|
|
608
|
+
sage: d = R(-707/5^2); repr(d)
|
|
609
|
+
'...444444444444444341.33'
|
|
610
|
+
|
|
611
|
+
Observe that the significant 0s are printed even if they are
|
|
612
|
+
located in front of the number. On the contrary, unknown digits
|
|
613
|
+
located after the comma appears as question marks.
|
|
614
|
+
The precision can therefore be read in this mode as well.
|
|
615
|
+
Here are more examples::
|
|
616
|
+
|
|
617
|
+
sage: p = 7
|
|
618
|
+
sage: K = Qp(p, prec=10, print_mode='digits')
|
|
619
|
+
sage: repr(K(1))
|
|
620
|
+
'...0000000001'
|
|
621
|
+
sage: repr(K(p^2))
|
|
622
|
+
'...000000000100'
|
|
623
|
+
sage: repr(K(p^-5))
|
|
624
|
+
'...00000.00001'
|
|
625
|
+
sage: repr(K(p^-20))
|
|
626
|
+
'...?.??????????0000000001'
|
|
627
|
+
|
|
628
|
+
*print_max_terms* limits the number of digits that are printed.
|
|
629
|
+
Note that if the valuation of the element is very negative, more
|
|
630
|
+
digits will be printed. ::
|
|
631
|
+
|
|
632
|
+
sage: S = Qp(5, print_max_terms=4); S(-70700)
|
|
633
|
+
2*5^2 + 4*5^3 + 5^4 + 2*5^5 + ... + O(5^22)
|
|
634
|
+
sage: S(-707/5^2)
|
|
635
|
+
3*5^-2 + 3*5^-1 + 1 + 4*5 + ... + O(5^18)
|
|
636
|
+
sage: S(-707/5^6)
|
|
637
|
+
3*5^-6 + 3*5^-5 + 5^-4 + 4*5^-3 + ... + O(5^14)
|
|
638
|
+
sage: S(-707/5^6,absprec=-2)
|
|
639
|
+
3*5^-6 + 3*5^-5 + 5^-4 + 4*5^-3 + O(5^-2)
|
|
640
|
+
sage: S(-707/5^4)
|
|
641
|
+
3*5^-4 + 3*5^-3 + 5^-2 + 4*5^-1 + ... + O(5^16)
|
|
642
|
+
|
|
643
|
+
*print_alphabet* controls the symbols used to substitute for digits
|
|
644
|
+
greater than 9.
|
|
645
|
+
|
|
646
|
+
Defaults to ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')::
|
|
647
|
+
|
|
648
|
+
sage: T = Qp(5, print_mode='digits', print_alphabet=('1','2','3','4','5')); repr(T(-70700))
|
|
649
|
+
'...5555555555555551325311'
|
|
650
|
+
|
|
651
|
+
*show_prec* determines how the precision is printed.
|
|
652
|
+
It can be either 'none' (or equivalently ``False``), 'dots'
|
|
653
|
+
(or equivalently ``True``) or 'bigoh'.
|
|
654
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
655
|
+
and ``True`` for all other types. ::
|
|
656
|
+
|
|
657
|
+
sage: repr(Zp(5, print_mode='digits', show_prec=True)(6))
|
|
658
|
+
'...00000000000000000011'
|
|
659
|
+
|
|
660
|
+
sage: repr(Zp(5, print_mode='digits', show_prec='bigoh')(6))
|
|
661
|
+
'11 + O(5^20)'
|
|
662
|
+
|
|
663
|
+
*print_pos*, *name* and *print_sep* have no effect.
|
|
664
|
+
|
|
665
|
+
Equality depends on printing options::
|
|
666
|
+
|
|
667
|
+
sage: R == S, R == T, S == T
|
|
668
|
+
(False, False, False)
|
|
669
|
+
|
|
670
|
+
5. **bars**: elements are displayed as a string of base `p` digits
|
|
671
|
+
with separators::
|
|
672
|
+
|
|
673
|
+
sage: R = Qp(5, print_mode='bars'); a = R(70700); repr(a)
|
|
674
|
+
'...4|2|3|0|3|0|0'
|
|
675
|
+
sage: b = R(-70700); repr(b)
|
|
676
|
+
'...4|4|4|4|4|4|4|4|4|4|4|4|4|4|4|0|2|1|4|2|0|0'
|
|
677
|
+
sage: d = R(-707/5^2); repr(d)
|
|
678
|
+
'...4|4|4|4|4|4|4|4|4|4|4|4|4|4|4|3|4|1|.|3|3'
|
|
679
|
+
|
|
680
|
+
Again, note that it's not possible to read off the precision from the representation in this mode.
|
|
681
|
+
|
|
682
|
+
*print_pos* controls whether the digits can be negative. ::
|
|
683
|
+
|
|
684
|
+
sage: S = Qp(5, print_mode='bars',print_pos=False); b = S(-70700); repr(b)
|
|
685
|
+
'...-1|0|2|2|-1|2|0|0'
|
|
686
|
+
|
|
687
|
+
*print_max_terms* limits the number of digits that are printed.
|
|
688
|
+
Note that if the valuation of the element is very negative, more
|
|
689
|
+
digits will be printed. ::
|
|
690
|
+
|
|
691
|
+
sage: T = Qp(5, print_max_terms=4); T(-70700)
|
|
692
|
+
2*5^2 + 4*5^3 + 5^4 + 2*5^5 + ... + O(5^22)
|
|
693
|
+
sage: T(-707/5^2)
|
|
694
|
+
3*5^-2 + 3*5^-1 + 1 + 4*5 + ... + O(5^18)
|
|
695
|
+
sage: T(-707/5^6)
|
|
696
|
+
3*5^-6 + 3*5^-5 + 5^-4 + 4*5^-3 + ... + O(5^14)
|
|
697
|
+
sage: T(-707/5^6,absprec=-2)
|
|
698
|
+
3*5^-6 + 3*5^-5 + 5^-4 + 4*5^-3 + O(5^-2)
|
|
699
|
+
sage: T(-707/5^4)
|
|
700
|
+
3*5^-4 + 3*5^-3 + 5^-2 + 4*5^-1 + ... + O(5^16)
|
|
701
|
+
|
|
702
|
+
*print_sep* controls the separation character. ::
|
|
703
|
+
|
|
704
|
+
sage: U = Qp(5, print_mode='bars', print_sep=']['); a = U(70700); repr(a)
|
|
705
|
+
'...4][2][3][0][3][0][0'
|
|
706
|
+
|
|
707
|
+
*show_prec* determines how the precision is printed.
|
|
708
|
+
It can be either 'none' (or equivalently ``False``), 'dots'
|
|
709
|
+
(or equivalently ``True``) or 'bigoh'
|
|
710
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
711
|
+
and ``True`` for all other types. ::
|
|
712
|
+
|
|
713
|
+
sage: repr(Qp(5, print_mode='bars', show_prec='bigoh')(6))
|
|
714
|
+
'...1|1 + O(5^20)'
|
|
715
|
+
|
|
716
|
+
*name* and *print_alphabet* have no effect.
|
|
717
|
+
|
|
718
|
+
Equality depends on printing options::
|
|
719
|
+
|
|
720
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U
|
|
721
|
+
(False, False, False, False, False, False)
|
|
722
|
+
|
|
723
|
+
EXAMPLES::
|
|
724
|
+
|
|
725
|
+
sage: K = Qp(15, check=False); a = K(999); a
|
|
726
|
+
9 + 6*15 + 4*15^2 + O(15^20)
|
|
727
|
+
"""
|
|
728
|
+
def create_key(self, p, prec=None, type='capped-rel', print_mode=None,
|
|
729
|
+
names=None, ram_name=None, print_pos=None,
|
|
730
|
+
print_sep=None, print_alphabet=None, print_max_terms=None, show_prec=None, check=True,
|
|
731
|
+
label=None): # specific to Lattice precision
|
|
732
|
+
r"""
|
|
733
|
+
Create a key from input parameters for ``Qp``.
|
|
734
|
+
|
|
735
|
+
See the documentation for ``Qp`` for more information.
|
|
736
|
+
|
|
737
|
+
TESTS::
|
|
738
|
+
|
|
739
|
+
sage: Qp.create_key(5,40)
|
|
740
|
+
(5, 40, 'capped-rel', 'series', '5', True, '|', (), -1, 'bigoh', None)
|
|
741
|
+
"""
|
|
742
|
+
if isinstance(names, (int, Integer)):
|
|
743
|
+
# old pickle; names is what used to be halt.
|
|
744
|
+
names = ram_name
|
|
745
|
+
ram_name = print_pos
|
|
746
|
+
print_pos = print_sep
|
|
747
|
+
print_alphabet = print_max_terms
|
|
748
|
+
print_max_terms = check
|
|
749
|
+
check = True
|
|
750
|
+
if label is not None and type not in ['lattice-cap','lattice-float']:
|
|
751
|
+
raise ValueError("label keyword only supported for lattice precision")
|
|
752
|
+
return get_key_base(p, prec, type, print_mode, names, ram_name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, check, ['capped-rel', 'floating-point', 'lattice-cap', 'lattice-float', 'relaxed'], label)
|
|
753
|
+
|
|
754
|
+
def create_object(self, version, key):
|
|
755
|
+
r"""
|
|
756
|
+
Create an object using a given key.
|
|
757
|
+
|
|
758
|
+
See the documentation for ``Qp`` for more information.
|
|
759
|
+
|
|
760
|
+
TESTS::
|
|
761
|
+
|
|
762
|
+
sage: Qp.create_object((3,4,2),(5, 41, 'capped-rel', 'series', '5', True, '|', (), -1))
|
|
763
|
+
5-adic Field with capped relative precision 41
|
|
764
|
+
"""
|
|
765
|
+
if version[0] < 3 or (version[0] == 3 and version[1] < 2) or (version[0] == 3 and version[1] == 2 and version[2] < 3):
|
|
766
|
+
p, prec, type, print_mode, name = key
|
|
767
|
+
print_pos, print_sep, print_alphabet, print_max_terms = None, None, None, None
|
|
768
|
+
elif version[0] < 8:
|
|
769
|
+
p, prec, type, print_mode, name, print_pos, print_sep, print_alphabet, print_max_terms = key
|
|
770
|
+
show_prec = None
|
|
771
|
+
label = None
|
|
772
|
+
else:
|
|
773
|
+
p, prec, type, print_mode, name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, label = key
|
|
774
|
+
if (version[0] < 4 or (len(version) > 1 and version[0] == 4 and version[1] < 5) or
|
|
775
|
+
(len(version) > 2 and version[0] == 4 and version[1] == 5 and version[2] < 3)):
|
|
776
|
+
# keys changed in order to reduce irrelevant duplications: e.g. two Qps with print_mode 'series'
|
|
777
|
+
# that are identical except for different 'print_alphabet' now return the same object.
|
|
778
|
+
key = get_key_base(p, prec, type, print_mode, name, None, print_pos, print_sep, print_alphabet,
|
|
779
|
+
print_max_terms, None, False, ['capped-rel', 'fixed-mod', 'capped-abs'])
|
|
780
|
+
try:
|
|
781
|
+
obj = self._cache[version, key]()
|
|
782
|
+
if obj is not None:
|
|
783
|
+
return obj
|
|
784
|
+
except KeyError:
|
|
785
|
+
pass
|
|
786
|
+
p, prec, type, print_mode, name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, label = key
|
|
787
|
+
|
|
788
|
+
_Fields = Fields()
|
|
789
|
+
|
|
790
|
+
if type == 'capped-rel':
|
|
791
|
+
if print_mode == 'terse':
|
|
792
|
+
return pAdicFieldCappedRelative(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
793
|
+
'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name,
|
|
794
|
+
category=_Fields)
|
|
795
|
+
else:
|
|
796
|
+
return pAdicFieldCappedRelative(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
797
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name,
|
|
798
|
+
category=_Fields)
|
|
799
|
+
elif type == 'floating-point':
|
|
800
|
+
if print_mode == 'terse':
|
|
801
|
+
return pAdicFieldFloatingPoint(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
802
|
+
'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name,
|
|
803
|
+
category=_Fields)
|
|
804
|
+
else:
|
|
805
|
+
return pAdicFieldFloatingPoint(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
806
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name,
|
|
807
|
+
category=_Fields)
|
|
808
|
+
elif type == 'relaxed':
|
|
809
|
+
if print_mode == 'terse':
|
|
810
|
+
return pAdicFieldRelaxed(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
811
|
+
'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name,
|
|
812
|
+
category=_Fields)
|
|
813
|
+
else:
|
|
814
|
+
return pAdicFieldRelaxed(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
815
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name,
|
|
816
|
+
category=_Fields)
|
|
817
|
+
elif type[:8] == 'lattice-':
|
|
818
|
+
subtype = type[8:]
|
|
819
|
+
if print_mode == 'terse':
|
|
820
|
+
return pAdicFieldLattice(p, prec, subtype, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
821
|
+
'ram_name': name, 'max_terse_terms': print_max_terms, 'show_prec': show_prec}, name, label,
|
|
822
|
+
category=_Fields)
|
|
823
|
+
else:
|
|
824
|
+
return pAdicFieldLattice(p, prec, subtype, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
825
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name, label,
|
|
826
|
+
category=_Fields)
|
|
827
|
+
else:
|
|
828
|
+
raise ValueError("unexpected type")
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
Qp = Qp_class("Qp")
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
######################################################
|
|
835
|
+
# Qq -- unramified extensions
|
|
836
|
+
######################################################
|
|
837
|
+
|
|
838
|
+
def Qq(q, prec=None, type='capped-rel', modulus=None, names=None,
|
|
839
|
+
print_mode=None, ram_name=None, res_name=None, print_pos=None,
|
|
840
|
+
print_sep=None, print_max_ram_terms=None,
|
|
841
|
+
print_max_unram_terms=None, print_max_terse_terms=None, show_prec=None, check=True, implementation='FLINT'):
|
|
842
|
+
r"""
|
|
843
|
+
Given a prime power `q = p^n`, return the unique unramified
|
|
844
|
+
extension of `\QQ_p` of degree `n`.
|
|
845
|
+
|
|
846
|
+
INPUT:
|
|
847
|
+
|
|
848
|
+
- ``q`` -- integer, list, tuple or ``Factorization`` object. If ``q`` is an
|
|
849
|
+
integer, it is the prime power `q` in `\QQ_q`. If ``q`` is a
|
|
850
|
+
:class:`Factorization` object, it is the factorization of the prime power `q`.
|
|
851
|
+
As a tuple it is the pair ``(p, n)``, and as a list it is a single
|
|
852
|
+
element list ``[(p, n)]``.
|
|
853
|
+
|
|
854
|
+
- ``prec`` -- integer (default: 20); the precision cap of the field.
|
|
855
|
+
Individual elements keep track of their own precision. See
|
|
856
|
+
TYPES and PRECISION below.
|
|
857
|
+
|
|
858
|
+
- ``type`` -- string (default: ``'capped-rel'``); valid types are
|
|
859
|
+
``'capped-rel'``, ``'floating-point'``, ``'lattice-cap'``
|
|
860
|
+
and ``'lattice-float'``. See TYPES and PRECISION below.
|
|
861
|
+
|
|
862
|
+
- ``modulus`` -- polynomial (default: ``None``); a polynomial defining an
|
|
863
|
+
unramified extension of `\QQ_p`. See MODULUS below.
|
|
864
|
+
|
|
865
|
+
- ``names`` -- string or tuple (``None`` is only allowed when `q=p`); the
|
|
866
|
+
name of the generator, reducing to a generator of the residue field.
|
|
867
|
+
|
|
868
|
+
- ``print_mode`` -- string (default: ``None``); valid modes are ``'series'``,
|
|
869
|
+
``'val-unit'``, ``'terse'``, and ``'bars'``. See PRINTING below.
|
|
870
|
+
|
|
871
|
+
- ``ram_name`` -- string (defaults to string representation of `p` if
|
|
872
|
+
``None``). ``ram_name`` controls how the prime is printed. See PRINTING
|
|
873
|
+
below.
|
|
874
|
+
|
|
875
|
+
- ``res_name`` -- string (defaults to ``None``, which corresponds to
|
|
876
|
+
adding a ``'0'`` to the end of the name). Controls how elements of
|
|
877
|
+
the residue field print.
|
|
878
|
+
|
|
879
|
+
- ``print_pos`` -- boolean (default: ``None``); whether to only use positive
|
|
880
|
+
integers in the representations of elements. See PRINTING below.
|
|
881
|
+
|
|
882
|
+
- ``print_sep`` -- string (default: ``None``); the separator character used
|
|
883
|
+
in the ``'bars'`` mode. See PRINTING below.
|
|
884
|
+
|
|
885
|
+
- ``print_max_ram_terms`` -- integer (default: ``None``) the maximum number
|
|
886
|
+
of powers of `p` shown. See PRINTING below.
|
|
887
|
+
|
|
888
|
+
- ``print_max_unram_terms`` -- integer (default: ``None``); the maximum
|
|
889
|
+
number of entries shown in a coefficient of `p`. See PRINTING
|
|
890
|
+
below.
|
|
891
|
+
|
|
892
|
+
- ``print_max_terse_terms`` -- integer (default: ``None``); the maximum
|
|
893
|
+
number of terms in the polynomial representation of an element
|
|
894
|
+
(using ``'terse'``). See PRINTING below.
|
|
895
|
+
|
|
896
|
+
- ``show_prec`` -- boolean (default: ``None``); whether to show the precision
|
|
897
|
+
for elements. See PRINTING below.
|
|
898
|
+
|
|
899
|
+
- ``check`` -- boolean (default: ``True``); whether to check inputs
|
|
900
|
+
|
|
901
|
+
OUTPUT: the corresponding unramified `p`-adic field
|
|
902
|
+
|
|
903
|
+
TYPES AND PRECISION:
|
|
904
|
+
|
|
905
|
+
There are two types of precision for a `p`-adic element. The first
|
|
906
|
+
is relative precision, which gives the number of known `p`-adic
|
|
907
|
+
digits::
|
|
908
|
+
|
|
909
|
+
sage: R.<a> = Qq(25, 20, 'capped-rel', print_mode='series'); b = 25*a; b # needs sage.libs.ntl
|
|
910
|
+
a*5^2 + O(5^22)
|
|
911
|
+
sage: b.precision_relative() # needs sage.libs.ntl
|
|
912
|
+
20
|
|
913
|
+
|
|
914
|
+
The second type of precision is absolute precision, which gives
|
|
915
|
+
the power of `p` that this element is defined modulo::
|
|
916
|
+
|
|
917
|
+
sage: b.precision_absolute() # needs sage.libs.ntl
|
|
918
|
+
22
|
|
919
|
+
|
|
920
|
+
There are two types of unramified `p`-adic fields: capped relative
|
|
921
|
+
fields, floating point fields.
|
|
922
|
+
|
|
923
|
+
In the capped relative case, the relative precision of an element
|
|
924
|
+
is restricted to be at most a certain value, specified at the
|
|
925
|
+
creation of the field. Individual elements also store their own
|
|
926
|
+
precision, so the effect of various arithmetic operations on
|
|
927
|
+
precision is tracked. When you cast an exact element into a
|
|
928
|
+
capped relative field, it truncates it to the precision cap of the
|
|
929
|
+
field. ::
|
|
930
|
+
|
|
931
|
+
sage: R.<a> = Qq(9, 5, 'capped-rel', print_mode='series'); b = (1+2*a)^4; b # needs sage.libs.ntl
|
|
932
|
+
2 + (2*a + 2)*3 + (2*a + 1)*3^2 + O(3^5)
|
|
933
|
+
sage: c = R(3249); c # needs sage.libs.ntl
|
|
934
|
+
3^2 + 3^4 + 3^5 + 3^6 + O(3^7)
|
|
935
|
+
sage: b + c # needs sage.libs.ntl
|
|
936
|
+
2 + (2*a + 2)*3 + (2*a + 2)*3^2 + 3^4 + O(3^5)
|
|
937
|
+
|
|
938
|
+
In the floating point case, elements do not track their
|
|
939
|
+
precision, but the relative precision of elements is truncated
|
|
940
|
+
during arithmetic to the precision cap of the field.
|
|
941
|
+
|
|
942
|
+
MODULUS:
|
|
943
|
+
|
|
944
|
+
The modulus needs to define an unramified extension of `\QQ_p`: when it
|
|
945
|
+
is reduced to a polynomial over `\GF{p}` it should be irreducible.
|
|
946
|
+
|
|
947
|
+
The modulus can be given in a number of forms.
|
|
948
|
+
|
|
949
|
+
1. A **polynomial**.
|
|
950
|
+
|
|
951
|
+
The base ring can be `\ZZ`, `\QQ`, `\ZZ_p`, `\QQ_p`, `\GF{p}`. ::
|
|
952
|
+
|
|
953
|
+
sage: # needs sage.libs.ntl
|
|
954
|
+
sage: P.<x> = ZZ[]
|
|
955
|
+
sage: R.<a> = Qq(27, modulus = x^3 + 2*x + 1); R.modulus()
|
|
956
|
+
(1 + O(3^20))*x^3 + O(3^20)*x^2 + (2 + O(3^20))*x + 1 + O(3^20)
|
|
957
|
+
sage: P.<x> = QQ[]
|
|
958
|
+
sage: S.<a> = Qq(27, modulus = x^3 + 2*x + 1)
|
|
959
|
+
sage: P.<x> = Zp(3)[]
|
|
960
|
+
sage: T.<a> = Qq(27, modulus = x^3 + 2*x + 1)
|
|
961
|
+
sage: P.<x> = Qp(3)[]
|
|
962
|
+
sage: U.<a> = Qq(27, modulus = x^3 + 2*x + 1)
|
|
963
|
+
sage: P.<x> = GF(3)[] # needs sage.rings.finite_rings
|
|
964
|
+
sage: V.<a> = Qq(27, modulus = x^3 + 2*x + 1)
|
|
965
|
+
|
|
966
|
+
Which form the modulus is given in has no effect on the unramified
|
|
967
|
+
extension produced::
|
|
968
|
+
|
|
969
|
+
sage: R == S, S == T, T == U, U == V # needs sage.libs.ntl
|
|
970
|
+
(True, True, True, False)
|
|
971
|
+
|
|
972
|
+
unless the precision of the modulus differs. In the case of V,
|
|
973
|
+
the modulus is only given to precision 1, so the resulting field
|
|
974
|
+
has a precision cap of 1. ::
|
|
975
|
+
|
|
976
|
+
sage: # needs sage.libs.ntl
|
|
977
|
+
sage: V.precision_cap()
|
|
978
|
+
1
|
|
979
|
+
sage: U.precision_cap()
|
|
980
|
+
20
|
|
981
|
+
sage: P.<x> = Qp(3)[]
|
|
982
|
+
sage: modulus = x^3 + (2 + O(3^7))*x + (1 + O(3^10))
|
|
983
|
+
sage: modulus
|
|
984
|
+
(1 + O(3^20))*x^3 + (2 + O(3^7))*x + 1 + O(3^10)
|
|
985
|
+
sage: W.<a> = Qq(27, modulus = modulus); W.precision_cap()
|
|
986
|
+
7
|
|
987
|
+
|
|
988
|
+
2. The modulus can also be given as a **symbolic expression**. ::
|
|
989
|
+
|
|
990
|
+
sage: x = var('x') # needs sage.symbolic
|
|
991
|
+
sage: X.<a> = Qq(27, modulus = x^3 + 2*x + 1); X.modulus() # needs sage.symbolic
|
|
992
|
+
(1 + O(3^20))*x^3 + O(3^20)*x^2 + (2 + O(3^20))*x + 1 + O(3^20)
|
|
993
|
+
sage: X == R # needs sage.libs.ntl sage.symbolic
|
|
994
|
+
True
|
|
995
|
+
|
|
996
|
+
By default, the polynomial chosen is the standard lift of the
|
|
997
|
+
generator chosen for `\GF{q}`. ::
|
|
998
|
+
|
|
999
|
+
sage: GF(125, 'a').modulus() # needs sage.rings.finite_rings
|
|
1000
|
+
x^3 + 3*x + 3
|
|
1001
|
+
sage: Y.<a> = Qq(125); Y.modulus() # needs sage.libs.ntl
|
|
1002
|
+
(1 + O(5^20))*x^3 + O(5^20)*x^2 + (3 + O(5^20))*x + 3 + O(5^20)
|
|
1003
|
+
|
|
1004
|
+
However, you can choose another polynomial if desired (as long as
|
|
1005
|
+
the reduction to `\GF{p}[x]` is irreducible). ::
|
|
1006
|
+
|
|
1007
|
+
sage: P.<x> = ZZ[]
|
|
1008
|
+
sage: Z.<a> = Qq(125, modulus = x^3 + 3*x^2 + x + 1); Z.modulus() # needs sage.libs.ntl
|
|
1009
|
+
(1 + O(5^20))*x^3 + (3 + O(5^20))*x^2 + (1 + O(5^20))*x + 1 + O(5^20)
|
|
1010
|
+
sage: Y == Z # needs sage.libs.ntl
|
|
1011
|
+
False
|
|
1012
|
+
|
|
1013
|
+
PRINTING:
|
|
1014
|
+
|
|
1015
|
+
There are many different ways to print `p`-adic elements. The way
|
|
1016
|
+
elements of a given field print is controlled by options passed in
|
|
1017
|
+
at the creation of the field. There are four basic printing modes
|
|
1018
|
+
(``'series'``, ``'val-unit'``, ``'terse'`` and ``'bars'``; ``'digits'`` is not available), as
|
|
1019
|
+
well as various options that either hide some information in the
|
|
1020
|
+
print representation or sometimes make print representations more
|
|
1021
|
+
compact. Note that the printing options affect whether different
|
|
1022
|
+
`p`-adic fields are considered equal.
|
|
1023
|
+
|
|
1024
|
+
1. **series**: elements are displayed as series in `p`. ::
|
|
1025
|
+
|
|
1026
|
+
sage: R.<a> = Qq(9, 20, 'capped-rel', print_mode='series'); (1+2*a)^4 # needs sage.libs.ntl
|
|
1027
|
+
2 + (2*a + 2)*3 + (2*a + 1)*3^2 + O(3^20)
|
|
1028
|
+
sage: -3*(1+2*a)^4 # needs sage.libs.ntl
|
|
1029
|
+
3 + a*3^2 + 3^3 + (2*a + 2)*3^4 + (2*a + 2)*3^5 + (2*a + 2)*3^6 + (2*a + 2)*3^7
|
|
1030
|
+
+ (2*a + 2)*3^8 + (2*a + 2)*3^9 + (2*a + 2)*3^10 + (2*a + 2)*3^11
|
|
1031
|
+
+ (2*a + 2)*3^12 + (2*a + 2)*3^13 + (2*a + 2)*3^14 + (2*a + 2)*3^15
|
|
1032
|
+
+ (2*a + 2)*3^16 + (2*a + 2)*3^17 + (2*a + 2)*3^18 + (2*a + 2)*3^19
|
|
1033
|
+
+ (2*a + 2)*3^20 + O(3^21)
|
|
1034
|
+
sage: ~(3*a+18) # needs sage.libs.ntl
|
|
1035
|
+
(a + 2)*3^-1 + 1 + 2*3 + (a + 1)*3^2 + 3^3 + 2*3^4 + (a + 1)*3^5 + 3^6 + 2*3^7
|
|
1036
|
+
+ (a + 1)*3^8 + 3^9 + 2*3^10 + (a + 1)*3^11 + 3^12 + 2*3^13 + (a + 1)*3^14
|
|
1037
|
+
+ 3^15 + 2*3^16 + (a + 1)*3^17 + 3^18 + O(3^19)
|
|
1038
|
+
|
|
1039
|
+
*print_pos* controls whether negatives can be used in the
|
|
1040
|
+
coefficients of powers of `p`. ::
|
|
1041
|
+
|
|
1042
|
+
sage: S.<b> = Qq(9, print_mode='series', print_pos=False); (1+2*b)^4 # needs sage.libs.ntl
|
|
1043
|
+
-1 - b*3 - 3^2 + (b + 1)*3^3 + O(3^20)
|
|
1044
|
+
sage: -3*(1+2*b)^4 # needs sage.libs.ntl
|
|
1045
|
+
3 + b*3^2 + 3^3 + (-b - 1)*3^4 + O(3^21)
|
|
1046
|
+
|
|
1047
|
+
*ram_name* controls how the prime is printed. ::
|
|
1048
|
+
|
|
1049
|
+
sage: T.<d> = Qq(9, print_mode='series', ram_name='p'); 3*(1+2*d)^4 # needs sage.libs.ntl
|
|
1050
|
+
2*p + (2*d + 2)*p^2 + (2*d + 1)*p^3 + O(p^21)
|
|
1051
|
+
|
|
1052
|
+
*print_max_ram_terms* limits the number of powers of `p` that appear. ::
|
|
1053
|
+
|
|
1054
|
+
sage: U.<e> = Qq(9, print_mode='series', print_max_ram_terms=4); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
1055
|
+
'3 + e*3^2 + 3^3 + (2*e + 2)*3^4 + ... + O(3^21)'
|
|
1056
|
+
|
|
1057
|
+
*print_max_unram_terms* limits the number of terms that appear in a
|
|
1058
|
+
coefficient of a power of `p`. ::
|
|
1059
|
+
|
|
1060
|
+
sage: # needs sage.libs.ntl
|
|
1061
|
+
sage: V.<f> = Qq(128, prec = 8, print_mode='series'); repr((1+f)^9)
|
|
1062
|
+
'(f^3 + 1) + (f^5 + f^4 + f^3 + f^2)*2 + (f^6 + f^5 + f^4 + f + 1)*2^2 + (f^5 + f^4 + f^2 + f + 1)*2^3 + (f^6 + f^5 + f^4 + f^3 + f^2 + f + 1)*2^4 + (f^5 + f^4)*2^5 + (f^6 + f^5 + f^4 + f^3 + f + 1)*2^6 + (f + 1)*2^7 + O(2^8)'
|
|
1063
|
+
sage: V.<f> = Qq(128, prec = 8, print_mode='series', print_max_unram_terms = 3); repr((1+f)^9)
|
|
1064
|
+
'(f^3 + 1) + (f^5 + f^4 + ... + f^2)*2 + (f^6 + f^5 + ... + 1)*2^2 + (f^5 + f^4 + ... + 1)*2^3 + (f^6 + f^5 + ... + 1)*2^4 + (f^5 + f^4)*2^5 + (f^6 + f^5 + ... + 1)*2^6 + (f + 1)*2^7 + O(2^8)'
|
|
1065
|
+
sage: V.<f> = Qq(128, prec = 8, print_mode='series', print_max_unram_terms = 2); repr((1+f)^9)
|
|
1066
|
+
'(f^3 + 1) + (f^5 + ... + f^2)*2 + (f^6 + ... + 1)*2^2 + (f^5 + ... + 1)*2^3 + (f^6 + ... + 1)*2^4 + (f^5 + f^4)*2^5 + (f^6 + ... + 1)*2^6 + (f + 1)*2^7 + O(2^8)'
|
|
1067
|
+
sage: V.<f> = Qq(128, prec = 8, print_mode='series', print_max_unram_terms = 1); repr((1+f)^9)
|
|
1068
|
+
'(f^3 + ...) + (f^5 + ...)*2 + (f^6 + ...)*2^2 + (f^5 + ...)*2^3 + (f^6 + ...)*2^4 + (f^5 + ...)*2^5 + (f^6 + ...)*2^6 + (f + ...)*2^7 + O(2^8)'
|
|
1069
|
+
sage: V.<f> = Qq(128, prec = 8, print_mode='series', print_max_unram_terms = 0); repr((1+f)^9 - 1 - f^3)
|
|
1070
|
+
'(...)*2 + (...)*2^2 + (...)*2^3 + (...)*2^4 + (...)*2^5 + (...)*2^6 + (...)*2^7 + O(2^8)'
|
|
1071
|
+
|
|
1072
|
+
*show_prec* determines how the precision is printed.
|
|
1073
|
+
It can be either 'none' (or equivalently ``False``), 'bigoh'
|
|
1074
|
+
(or equivalently ``True``).
|
|
1075
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
1076
|
+
and ``True`` for all other types. ::
|
|
1077
|
+
|
|
1078
|
+
sage: U.<e> = Qq(9, 2, show_prec=False); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
1079
|
+
'3 + e*3^2'
|
|
1080
|
+
|
|
1081
|
+
*print_sep* and *print_max_terse_terms* have no effect.
|
|
1082
|
+
|
|
1083
|
+
Note that print options affect equality::
|
|
1084
|
+
|
|
1085
|
+
sage: R == S, R == T, R == U, R == V, S == T, S == U, S == V, T == U, T == V, U == V # needs sage.libs.ntl
|
|
1086
|
+
(False, False, False, False, False, False, False, False, False, False)
|
|
1087
|
+
|
|
1088
|
+
2. **val-unit**: elements are displayed as `p^k u`::
|
|
1089
|
+
|
|
1090
|
+
sage: R.<a> = Qq(9, 7, print_mode='val-unit'); b = (1+3*a)^9 - 1; b # needs sage.libs.ntl
|
|
1091
|
+
3^3 * (15 + 64*a) + O(3^7)
|
|
1092
|
+
sage: ~b # needs sage.libs.ntl
|
|
1093
|
+
3^-3 * (41 + a) + O(3)
|
|
1094
|
+
|
|
1095
|
+
*print_pos* controls whether to use a balanced representation or
|
|
1096
|
+
not. ::
|
|
1097
|
+
|
|
1098
|
+
sage: S.<a> = Qq(9, 7, print_mode='val-unit', print_pos=False) # needs sage.libs.ntl
|
|
1099
|
+
sage: b = (1+3*a)^9 - 1; b # needs sage.libs.ntl
|
|
1100
|
+
3^3 * (15 - 17*a) + O(3^7)
|
|
1101
|
+
sage: ~b # needs sage.libs.ntl
|
|
1102
|
+
3^-3 * (-40 + a) + O(3)
|
|
1103
|
+
|
|
1104
|
+
*ram_name* affects how the prime is printed. ::
|
|
1105
|
+
|
|
1106
|
+
sage: # needs sage.libs.ntl
|
|
1107
|
+
sage: A.<x> = Qp(next_prime(10^6), print_mode='val-unit')[]
|
|
1108
|
+
sage: T.<a> = Qq(next_prime(10^6)^3, 4, print_mode='val-unit', ram_name='p',
|
|
1109
|
+
....: modulus=x^3+385831*x^2+106556*x+321036)
|
|
1110
|
+
sage: b = ~(next_prime(10^6)^2*(a^2 + a - 4)); b
|
|
1111
|
+
p^-2 * (503009563508519137754940 + 704413692798200940253892*a
|
|
1112
|
+
+ 968097057817740999537581*a^2) + O(p^2)
|
|
1113
|
+
sage: b * (a^2 + a - 4)
|
|
1114
|
+
p^-2 * 1 + O(p^2)
|
|
1115
|
+
|
|
1116
|
+
*print_max_terse_terms* controls how many terms of the polynomial
|
|
1117
|
+
appear in the unit part. ::
|
|
1118
|
+
|
|
1119
|
+
sage: U.<a> = Qq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3) # needs sage.libs.ntl
|
|
1120
|
+
sage: b = ~(17*(a^3-a+14)); b # needs sage.libs.ntl
|
|
1121
|
+
17^-1 * (22110411 + 11317400*a + 20656972*a^2 + ...) + O(17^5)
|
|
1122
|
+
sage: b*17*(a^3-a+14) # needs sage.libs.ntl
|
|
1123
|
+
1 + O(17^6)
|
|
1124
|
+
|
|
1125
|
+
*show_prec* determines how the precision is printed.
|
|
1126
|
+
It can be either 'none' (or equivalently ``False``), 'bigoh'
|
|
1127
|
+
(or equivalently ``True``).
|
|
1128
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
1129
|
+
and ``True`` for all other types. ::
|
|
1130
|
+
|
|
1131
|
+
sage: U.<e> = Qq(9, 2, print_mode='val-unit', show_prec=False); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
1132
|
+
'3 * (1 + 3*e)'
|
|
1133
|
+
|
|
1134
|
+
*print_sep*, *print_max_ram_terms* and *print_max_unram_terms* have no
|
|
1135
|
+
effect.
|
|
1136
|
+
|
|
1137
|
+
Equality again depends on the printing options::
|
|
1138
|
+
|
|
1139
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U # needs sage.libs.ntl
|
|
1140
|
+
(False, False, False, False, False, False)
|
|
1141
|
+
|
|
1142
|
+
3. **terse**: elements are displayed as a polynomial of degree less
|
|
1143
|
+
than the degree of the extension. ::
|
|
1144
|
+
|
|
1145
|
+
sage: R.<a> = Qq(125, print_mode='terse') # needs sage.libs.ntl
|
|
1146
|
+
sage: (a+5)^177 # needs sage.libs.ntl
|
|
1147
|
+
68210977979428 + 90313850704069*a + 73948093055069*a^2 + O(5^20)
|
|
1148
|
+
sage: (a/5+1)^177 # needs sage.libs.ntl
|
|
1149
|
+
68210977979428/5^177 + 90313850704069/5^177*a + 73948093055069/5^177*a^2 + O(5^-157)
|
|
1150
|
+
|
|
1151
|
+
As of version 3.3, if coefficients of the polynomial are
|
|
1152
|
+
non-integral, they are always printed with an explicit power of `p`
|
|
1153
|
+
in the denominator. ::
|
|
1154
|
+
|
|
1155
|
+
sage: 5*a + a^2/25 # needs sage.libs.ntl
|
|
1156
|
+
5*a + 1/5^2*a^2 + O(5^18)
|
|
1157
|
+
|
|
1158
|
+
*print_pos* controls whether to use a balanced representation or
|
|
1159
|
+
not. ::
|
|
1160
|
+
|
|
1161
|
+
sage: (a-5)^6 # needs sage.libs.ntl
|
|
1162
|
+
22864 + 95367431627998*a + 8349*a^2 + O(5^20)
|
|
1163
|
+
sage: S.<a> = Qq(125, print_mode='terse', print_pos=False); b = (a-5)^6; b # needs sage.libs.ntl
|
|
1164
|
+
22864 - 12627*a + 8349*a^2 + O(5^20)
|
|
1165
|
+
sage: (a - 1/5)^6 # needs sage.libs.ntl
|
|
1166
|
+
-20624/5^6 + 18369/5^5*a + 1353/5^3*a^2 + O(5^14)
|
|
1167
|
+
|
|
1168
|
+
*ram_name* affects how the prime is printed. ::
|
|
1169
|
+
|
|
1170
|
+
sage: T.<a> = Qq(125, print_mode='terse', ram_name='p'); (a - 1/5)^6 # needs sage.libs.ntl
|
|
1171
|
+
95367431620001/p^6 + 18369/p^5*a + 1353/p^3*a^2 + O(p^14)
|
|
1172
|
+
|
|
1173
|
+
*print_max_terse_terms* controls how many terms of the polynomial
|
|
1174
|
+
are shown. ::
|
|
1175
|
+
|
|
1176
|
+
sage: U.<a> = Qq(625, print_mode='terse', print_max_terse_terms=2); (a-1/5)^6 # needs sage.libs.ntl
|
|
1177
|
+
106251/5^6 + 49994/5^5*a + ... + O(5^14)
|
|
1178
|
+
|
|
1179
|
+
*show_prec* determines how the precision is printed.
|
|
1180
|
+
It can be either 'none' (or equivalently ``False``), 'bigoh'
|
|
1181
|
+
(or equivalently ``True``).
|
|
1182
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
1183
|
+
and ``True`` for all other types. ::
|
|
1184
|
+
|
|
1185
|
+
sage: U.<e> = Qq(9, 2, print_mode='terse', show_prec=False); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
1186
|
+
'3 + 9*e'
|
|
1187
|
+
|
|
1188
|
+
*print_sep*, *print_max_ram_terms* and *print_max_unram_terms* have no
|
|
1189
|
+
effect.
|
|
1190
|
+
|
|
1191
|
+
Equality again depends on the printing options::
|
|
1192
|
+
|
|
1193
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U # needs sage.libs.ntl
|
|
1194
|
+
(False, False, False, False, False, False)
|
|
1195
|
+
|
|
1196
|
+
4. **digits**: This print mode is not available when the residue
|
|
1197
|
+
field is not prime.
|
|
1198
|
+
|
|
1199
|
+
It might make sense to have a dictionary for small fields, but
|
|
1200
|
+
this isn't implemented.
|
|
1201
|
+
|
|
1202
|
+
5. **bars**: elements are displayed in a similar fashion to
|
|
1203
|
+
series, but more compactly. ::
|
|
1204
|
+
|
|
1205
|
+
sage: R.<a> = Qq(125); (a+5)^6 # needs sage.libs.ntl
|
|
1206
|
+
(4*a^2 + 3*a + 4) + (3*a^2 + 2*a)*5 + (a^2 + a + 1)*5^2 + (3*a + 2)*5^3
|
|
1207
|
+
+ (3*a^2 + a + 3)*5^4 + (2*a^2 + 3*a + 2)*5^5 + O(5^20)
|
|
1208
|
+
sage: R.<a> = Qq(125, print_mode='bars', prec=8); repr((a+5)^6) # needs sage.libs.ntl
|
|
1209
|
+
'...[2, 3, 2]|[3, 1, 3]|[2, 3]|[1, 1, 1]|[0, 2, 3]|[4, 3, 4]'
|
|
1210
|
+
sage: repr((a-5)^6) # needs sage.libs.ntl
|
|
1211
|
+
'...[0, 4]|[1, 4]|[2, 0, 2]|[1, 4, 3]|[2, 3, 1]|[4, 4, 3]|[2, 4, 4]|[4, 3, 4]'
|
|
1212
|
+
|
|
1213
|
+
Note that elements with negative valuation are shown with a
|
|
1214
|
+
decimal point at valuation 0. ::
|
|
1215
|
+
|
|
1216
|
+
sage: repr((a+1/5)^6) # needs sage.libs.ntl
|
|
1217
|
+
'...[3]|[4, 1, 3]|.|[1, 2, 3]|[3, 3]|[0, 0, 3]|[0, 1]|[0, 1]|[1]'
|
|
1218
|
+
sage: repr((a+1/5)^2) # needs sage.libs.ntl
|
|
1219
|
+
'...[0, 0, 1]|.|[0, 2]|[1]'
|
|
1220
|
+
|
|
1221
|
+
If not enough precision is known, ``'?'`` is used instead. ::
|
|
1222
|
+
|
|
1223
|
+
sage: repr((a+R(1/5,relprec=3))^7) # needs sage.libs.ntl
|
|
1224
|
+
'...|.|?|?|?|?|[0, 1, 1]|[0, 2]|[1]'
|
|
1225
|
+
|
|
1226
|
+
Note that it's not possible to read off the precision from the
|
|
1227
|
+
representation in this mode. ::
|
|
1228
|
+
|
|
1229
|
+
sage: # needs sage.libs.ntl
|
|
1230
|
+
sage: b = a + 3; repr(b)
|
|
1231
|
+
'...[3, 1]'
|
|
1232
|
+
sage: c = a + R(3, 4); repr(c)
|
|
1233
|
+
'...[3, 1]'
|
|
1234
|
+
sage: b.precision_absolute()
|
|
1235
|
+
8
|
|
1236
|
+
sage: c.precision_absolute()
|
|
1237
|
+
4
|
|
1238
|
+
|
|
1239
|
+
*print_pos* controls whether the digits can be negative. ::
|
|
1240
|
+
|
|
1241
|
+
sage: S.<a> = Qq(125, print_mode='bars', print_pos=False); repr((a-5)^6) # needs sage.libs.ntl
|
|
1242
|
+
'...[1, -1, 1]|[2, 1, -2]|[2, 0, -2]|[-2, -1, 2]|[0, 0, -1]|[-2]|[-1, -2, -1]'
|
|
1243
|
+
sage: repr((a-1/5)^6) # needs sage.libs.ntl
|
|
1244
|
+
'...[0, 1, 2]|[-1, 1, 1]|.|[-2, -1, -1]|[2, 2, 1]|[0, 0, -2]|[0, -1]|[0, -1]|[1]'
|
|
1245
|
+
|
|
1246
|
+
*print_max_ram_terms* controls the maximum number of "digits" shown.
|
|
1247
|
+
Note that this puts a cap on the relative precision, not the
|
|
1248
|
+
absolute precision. ::
|
|
1249
|
+
|
|
1250
|
+
sage: T.<a> = Qq(125, print_max_ram_terms=3, print_pos=False); (a-5)^6 # needs sage.libs.ntl
|
|
1251
|
+
(-a^2 - 2*a - 1) - 2*5 - a^2*5^2 + ... + O(5^20)
|
|
1252
|
+
sage: 5*(a-5)^6 + 50 # needs sage.libs.ntl
|
|
1253
|
+
(-a^2 - 2*a - 1)*5 - a^2*5^3 + (2*a^2 - a - 2)*5^4 + ... + O(5^21)
|
|
1254
|
+
|
|
1255
|
+
*print_sep* controls the separating character (``'|'`` by default). ::
|
|
1256
|
+
|
|
1257
|
+
sage: U.<a> = Qq(625, print_mode='bars', print_sep=''); b = (a+5)^6; repr(b) # needs sage.libs.ntl
|
|
1258
|
+
'...[0, 1][4, 0, 2][3, 2, 2, 3][4, 2, 2, 4][0, 3][1, 1, 3][3, 1, 4, 1]'
|
|
1259
|
+
|
|
1260
|
+
*print_max_unram_terms* controls how many terms are shown in each
|
|
1261
|
+
"digit"::
|
|
1262
|
+
|
|
1263
|
+
sage: # needs sage.libs.ntl
|
|
1264
|
+
sage: with local_print_mode(U, {'max_unram_terms': 3}): repr(b)
|
|
1265
|
+
'...[0, 1][4,..., 0, 2][3,..., 2, 3][4,..., 2, 4][0, 3][1,..., 1, 3][3,..., 4, 1]'
|
|
1266
|
+
sage: with local_print_mode(U, {'max_unram_terms': 2}): repr(b)
|
|
1267
|
+
'...[0, 1][4,..., 2][3,..., 3][4,..., 4][0, 3][1,..., 3][3,..., 1]'
|
|
1268
|
+
sage: with local_print_mode(U, {'max_unram_terms': 1}): repr(b)
|
|
1269
|
+
'...[..., 1][..., 2][..., 3][..., 4][..., 3][..., 3][..., 1]'
|
|
1270
|
+
sage: with local_print_mode(U, {'max_unram_terms':0}): repr(b-75*a)
|
|
1271
|
+
'...[...][...][...][...][][...][...]'
|
|
1272
|
+
|
|
1273
|
+
*show_prec* determines how the precision is printed.
|
|
1274
|
+
It can be either 'none' (or equivalently ``False``), 'dots'
|
|
1275
|
+
(or equivalently ``True``) or 'bigoh'
|
|
1276
|
+
The default is ``False`` for the ``'floating-point'`` type
|
|
1277
|
+
and ``True`` for all other types. ::
|
|
1278
|
+
|
|
1279
|
+
sage: U.<e> = Qq(9, 2, print_mode='bars', show_prec=True); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
1280
|
+
'...[0, 1]|[1]|[]'
|
|
1281
|
+
|
|
1282
|
+
*ram_name* and *print_max_terse_terms* have no effect.
|
|
1283
|
+
|
|
1284
|
+
Equality depends on printing options::
|
|
1285
|
+
|
|
1286
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U # needs sage.libs.ntl
|
|
1287
|
+
(False, False, False, False, False, False)
|
|
1288
|
+
|
|
1289
|
+
EXAMPLES:
|
|
1290
|
+
|
|
1291
|
+
Unlike for ``Qp``, you can't create ``Qq(N)`` when ``N`` is not a prime power.
|
|
1292
|
+
|
|
1293
|
+
However, you can use ``check=False`` to pass in a pair in order to not
|
|
1294
|
+
have to factor. If you do so, you need to use names explicitly
|
|
1295
|
+
rather than the ``R.<a>`` syntax. ::
|
|
1296
|
+
|
|
1297
|
+
sage: p = next_prime(2^123)
|
|
1298
|
+
sage: k = Qp(p)
|
|
1299
|
+
sage: R.<x> = k[] # needs sage.libs.ntl
|
|
1300
|
+
sage: K = Qq([(p, 5)], modulus=x^5+x+4, names='a', ram_name='p', # needs sage.libs.ntl
|
|
1301
|
+
....: print_pos=False, check=False)
|
|
1302
|
+
sage: K.0^5 # needs sage.libs.ntl
|
|
1303
|
+
(-a - 4) + O(p^20)
|
|
1304
|
+
|
|
1305
|
+
In tests on ``sage.math.washington.edu``, the creation of ``K`` as above took an
|
|
1306
|
+
average of 1.58ms, while::
|
|
1307
|
+
|
|
1308
|
+
sage: K = Qq(p^5, modulus=x^5+x+4, names='a', ram_name='p', # needs sage.libs.ntl
|
|
1309
|
+
....: print_pos=False, check=True)
|
|
1310
|
+
|
|
1311
|
+
took an average of 24.5ms. Of course, with smaller primes these
|
|
1312
|
+
savings disappear.
|
|
1313
|
+
|
|
1314
|
+
TESTS:
|
|
1315
|
+
|
|
1316
|
+
Check that :issue:`8162` is resolved::
|
|
1317
|
+
|
|
1318
|
+
sage: R = Qq([(5,3)], names='alpha', check=False); R # needs sage.libs.ntl
|
|
1319
|
+
5-adic Unramified Extension Field in alpha defined by x^3 + 3*x + 3
|
|
1320
|
+
sage: Qq((5, 3), names='alpha') is R # needs sage.libs.ntl
|
|
1321
|
+
True
|
|
1322
|
+
sage: Qq(125.factor(), names='alpha') is R # needs sage.libs.ntl
|
|
1323
|
+
True
|
|
1324
|
+
|
|
1325
|
+
Check that :issue:`18606` is resolved::
|
|
1326
|
+
|
|
1327
|
+
sage: x = QQ['x'].gen()
|
|
1328
|
+
sage: F = Qp(5,20)
|
|
1329
|
+
sage: K0 = F.extension(x^2-F(13),names = 'g')
|
|
1330
|
+
sage: K1 = F.extension(x^2-13,names = 'g') # needs sage.libs.ntl
|
|
1331
|
+
sage: K0 is K1 # needs sage.libs.ntl
|
|
1332
|
+
True
|
|
1333
|
+
"""
|
|
1334
|
+
if isinstance(q, Element):
|
|
1335
|
+
F = Integer(q).factor()
|
|
1336
|
+
if len(F) != 1:
|
|
1337
|
+
raise ValueError("q must be a prime power")
|
|
1338
|
+
q = F
|
|
1339
|
+
if isinstance(q, Factorization):
|
|
1340
|
+
if len(q) != 1:
|
|
1341
|
+
raise ValueError("q must be a factorization of a prime power")
|
|
1342
|
+
q = list(q)
|
|
1343
|
+
if not isinstance(q, (list, tuple)):
|
|
1344
|
+
raise TypeError("q must be an integer, list, tuple or Factorization")
|
|
1345
|
+
if len(q) != 2:
|
|
1346
|
+
if len(q) != 1:
|
|
1347
|
+
raise ValueError("q must have shape [(p,k)]")
|
|
1348
|
+
q = q[0]
|
|
1349
|
+
if len(q) != 2:
|
|
1350
|
+
raise ValueError("q must have shape (p,k)")
|
|
1351
|
+
if not isinstance(q, tuple):
|
|
1352
|
+
q = tuple(q)
|
|
1353
|
+
|
|
1354
|
+
p,k = q
|
|
1355
|
+
if not isinstance(p, Integer):
|
|
1356
|
+
p = Integer(p)
|
|
1357
|
+
if not isinstance(k, Integer):
|
|
1358
|
+
k = Integer(k)
|
|
1359
|
+
|
|
1360
|
+
if check:
|
|
1361
|
+
if not p.is_prime() or k <= 0:
|
|
1362
|
+
raise ValueError("q must be a prime power")
|
|
1363
|
+
|
|
1364
|
+
if prec is not None and not isinstance(prec, Integer):
|
|
1365
|
+
prec = Integer(prec)
|
|
1366
|
+
|
|
1367
|
+
base = Qp(p=p, prec=prec, type=type, print_mode=print_mode, names=ram_name, print_pos=print_pos,
|
|
1368
|
+
print_sep=print_sep, print_max_terms=print_max_ram_terms, show_prec=show_prec, check=check)
|
|
1369
|
+
|
|
1370
|
+
if k == 1:
|
|
1371
|
+
return base
|
|
1372
|
+
|
|
1373
|
+
if isinstance(names, (list, tuple)):
|
|
1374
|
+
if len(names) != 1:
|
|
1375
|
+
raise ValueError("must provide exactly one generator name")
|
|
1376
|
+
names = names[0]
|
|
1377
|
+
if names is None:
|
|
1378
|
+
raise TypeError("You must specify the name of the generator.")
|
|
1379
|
+
if not isinstance(names, str):
|
|
1380
|
+
names = str(names)
|
|
1381
|
+
|
|
1382
|
+
if res_name is None:
|
|
1383
|
+
res_name = names + '0'
|
|
1384
|
+
|
|
1385
|
+
if modulus is None:
|
|
1386
|
+
from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
|
|
1387
|
+
modulus = GF((p, k), res_name).modulus().change_ring(ZZ)
|
|
1388
|
+
return ExtensionFactory(base=base, modulus=modulus, prec=prec, print_mode=print_mode,
|
|
1389
|
+
names=names, res_name=res_name, ram_name=ram_name, print_pos=print_pos,
|
|
1390
|
+
print_sep=print_sep, print_max_ram_terms=print_max_ram_terms,
|
|
1391
|
+
print_max_unram_terms=print_max_unram_terms,
|
|
1392
|
+
print_max_terse_terms=print_max_terse_terms, show_prec=show_prec, check=check,
|
|
1393
|
+
unram=True, implementation=implementation)
|
|
1394
|
+
|
|
1395
|
+
######################################################
|
|
1396
|
+
# Short constructor names for different types
|
|
1397
|
+
######################################################
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
def QpCR(p, prec=None, *args, **kwds):
|
|
1401
|
+
r"""
|
|
1402
|
+
A shortcut function to create capped relative `p`-adic fields.
|
|
1403
|
+
|
|
1404
|
+
Same functionality as :func:`Qp`. See documentation for :func:`Qp` for a
|
|
1405
|
+
description of the input parameters.
|
|
1406
|
+
|
|
1407
|
+
EXAMPLES::
|
|
1408
|
+
|
|
1409
|
+
sage: QpCR(5, 40)
|
|
1410
|
+
5-adic Field with capped relative precision 40
|
|
1411
|
+
"""
|
|
1412
|
+
return Qp(p, prec, 'capped-rel', *args, **kwds)
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
def QpFP(p, prec=None, *args, **kwds):
|
|
1416
|
+
r"""
|
|
1417
|
+
A shortcut function to create floating point `p`-adic fields.
|
|
1418
|
+
|
|
1419
|
+
Same functionality as :func:`Qp`. See documentation for :func:`Qp` for a
|
|
1420
|
+
description of the input parameters.
|
|
1421
|
+
|
|
1422
|
+
EXAMPLES::
|
|
1423
|
+
|
|
1424
|
+
sage: QpFP(5, 40)
|
|
1425
|
+
5-adic Field with floating precision 40
|
|
1426
|
+
"""
|
|
1427
|
+
return Qp(p, prec, 'floating-point', *args, **kwds)
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
def QqCR(q, prec=None, *args, **kwds):
|
|
1431
|
+
r"""
|
|
1432
|
+
A shortcut function to create capped relative unramified `p`-adic
|
|
1433
|
+
fields.
|
|
1434
|
+
|
|
1435
|
+
Same functionality as :func:`Qq`. See documentation for :func:`Qq` for a
|
|
1436
|
+
description of the input parameters.
|
|
1437
|
+
|
|
1438
|
+
EXAMPLES::
|
|
1439
|
+
|
|
1440
|
+
sage: R.<a> = QqCR(25, 40); R # needs sage.libs.ntl
|
|
1441
|
+
5-adic Unramified Extension Field in a defined by x^2 + 4*x + 2
|
|
1442
|
+
"""
|
|
1443
|
+
return Qq(q, prec, 'capped-rel', *args, **kwds)
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
def QqFP(q, prec=None, *args, **kwds):
|
|
1447
|
+
r"""
|
|
1448
|
+
A shortcut function to create floating point unramified `p`-adic
|
|
1449
|
+
fields.
|
|
1450
|
+
|
|
1451
|
+
Same functionality as :func:`Qq`. See documentation for :func:`Qq` for a
|
|
1452
|
+
description of the input parameters.
|
|
1453
|
+
|
|
1454
|
+
EXAMPLES::
|
|
1455
|
+
|
|
1456
|
+
sage: R.<a> = QqFP(25, 40); R # needs sage.libs.flint
|
|
1457
|
+
5-adic Unramified Extension Field in a defined by x^2 + 4*x + 2
|
|
1458
|
+
"""
|
|
1459
|
+
return Qq(q, prec, 'floating-point', *args, **kwds)
|
|
1460
|
+
|
|
1461
|
+
|
|
1462
|
+
@experimental(23505)
|
|
1463
|
+
def QpLC(p, prec=None, *args, **kwds):
|
|
1464
|
+
r"""
|
|
1465
|
+
A shortcut function to create `p`-adic fields with lattice precision.
|
|
1466
|
+
|
|
1467
|
+
See :func:`ZpLC` for more information about this model of precision.
|
|
1468
|
+
|
|
1469
|
+
EXAMPLES::
|
|
1470
|
+
|
|
1471
|
+
sage: R = QpLC(2)
|
|
1472
|
+
sage: R
|
|
1473
|
+
2-adic Field with lattice-cap precision
|
|
1474
|
+
"""
|
|
1475
|
+
return Qp(p, prec, 'lattice-cap', *args, **kwds)
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
@experimental(23505)
|
|
1479
|
+
def QpLF(p, prec=None, *args, **kwds):
|
|
1480
|
+
r"""
|
|
1481
|
+
A shortcut function to create `p`-adic fields with lattice precision.
|
|
1482
|
+
|
|
1483
|
+
See :func:`ZpLC` for more information about this model of precision.
|
|
1484
|
+
|
|
1485
|
+
EXAMPLES::
|
|
1486
|
+
|
|
1487
|
+
sage: R = QpLF(2)
|
|
1488
|
+
sage: R
|
|
1489
|
+
2-adic Field with lattice-float precision
|
|
1490
|
+
"""
|
|
1491
|
+
return Qp(p, prec, 'lattice-float', *args, **kwds)
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
def QpER(p, prec=None, halt=None, secure=False, *args, **kwds):
|
|
1495
|
+
r"""
|
|
1496
|
+
A shortcut function to create relaxed `p`-adic fields.
|
|
1497
|
+
|
|
1498
|
+
See :func:`ZpER` for more information about this model of precision.
|
|
1499
|
+
|
|
1500
|
+
EXAMPLES::
|
|
1501
|
+
|
|
1502
|
+
sage: R = QpER(2); R # needs sage.libs.flint
|
|
1503
|
+
2-adic Field handled with relaxed arithmetics
|
|
1504
|
+
"""
|
|
1505
|
+
return Qp(p, (prec, halt, secure), 'relaxed', *args, **kwds)
|
|
1506
|
+
|
|
1507
|
+
#######################################################################################################
|
|
1508
|
+
#
|
|
1509
|
+
# p-adic Rings
|
|
1510
|
+
# Zp -- base rings
|
|
1511
|
+
# Zq -- unramified extension ring of Zp
|
|
1512
|
+
# ZpCR, ZpCA, ZpFM, ZpL, ZqCR, ZqCA, ZqFM, ZqL -- shortcuts for precision-type versions of Zp and Zq
|
|
1513
|
+
#
|
|
1514
|
+
#######################################################################################################
|
|
1515
|
+
|
|
1516
|
+
|
|
1517
|
+
class Zp_class(UniqueFactory):
|
|
1518
|
+
r"""
|
|
1519
|
+
A creation function for `p`-adic rings.
|
|
1520
|
+
|
|
1521
|
+
INPUT:
|
|
1522
|
+
|
|
1523
|
+
- ``p`` -- integer; the `p` in `\ZZ_p`
|
|
1524
|
+
|
|
1525
|
+
- ``prec`` -- integer (default: 20); the precision cap of the
|
|
1526
|
+
ring. In the lattice capped case, ``prec`` can either be a
|
|
1527
|
+
pair (``relative_cap``, ``absolute_cap``) or an integer
|
|
1528
|
+
(understood as relative cap).
|
|
1529
|
+
In the relaxed case, ``prec`` can be either a
|
|
1530
|
+
pair (``default_prec``, ``halting_prec``) or an integer
|
|
1531
|
+
(understood as default precision).
|
|
1532
|
+
Except for the fixed modulus and floating point cases, individual elements
|
|
1533
|
+
keep track of their own precision. See TYPES and PRECISION
|
|
1534
|
+
below.
|
|
1535
|
+
|
|
1536
|
+
- ``type`` -- string (default: ``'capped-rel'``); valid types are
|
|
1537
|
+
``'capped-rel'``, ``'capped-abs'``, ``'fixed-mod'``, ``'floating-point'``,
|
|
1538
|
+
``'lattice-cap'``, ``'lattice-float'``, ``'relaxed'``.
|
|
1539
|
+
See TYPES and PRECISION below.
|
|
1540
|
+
|
|
1541
|
+
- ``print_mode`` -- string (default: ``None``); valid modes are
|
|
1542
|
+
``'series'``, ``'val-unit'``, ``'terse'``, ``'digits'``, and
|
|
1543
|
+
``'bars'``. See PRINTING below.
|
|
1544
|
+
|
|
1545
|
+
- ``names`` -- string or tuple (defaults to a string
|
|
1546
|
+
representation of `p`); what to use whenever `p` is printed
|
|
1547
|
+
|
|
1548
|
+
- ``print_pos`` -- boolean (default: ``None``); whether to only use
|
|
1549
|
+
positive integers in the representations of elements. See
|
|
1550
|
+
PRINTING below.
|
|
1551
|
+
|
|
1552
|
+
- ``print_sep`` -- string (default: ``None``); the separator
|
|
1553
|
+
character used in the ``'bars'`` mode. See PRINTING below.
|
|
1554
|
+
|
|
1555
|
+
- ``print_alphabet`` -- tuple (default: ``None``); the encoding into
|
|
1556
|
+
digits for use in the ``'digits'`` mode. See PRINTING below.
|
|
1557
|
+
|
|
1558
|
+
- ``print_max_terms`` -- integer (default: ``None``); the maximum
|
|
1559
|
+
number of terms shown. See PRINTING below.
|
|
1560
|
+
|
|
1561
|
+
- ``show_prec`` -- boolean (default: ``None``) whether to show the precision
|
|
1562
|
+
for elements. See PRINTING below.
|
|
1563
|
+
|
|
1564
|
+
- ``check`` -- boolean (default: ``True``) whether to check if `p` is
|
|
1565
|
+
prime. Non-prime input may cause seg-faults (but can also be
|
|
1566
|
+
useful for base `n` expansions for example)
|
|
1567
|
+
|
|
1568
|
+
- ``label`` -- string (default: ``None``); used for lattice precision to
|
|
1569
|
+
create parents with different lattices
|
|
1570
|
+
|
|
1571
|
+
OUTPUT: the corresponding `p`-adic ring
|
|
1572
|
+
|
|
1573
|
+
TYPES AND PRECISION:
|
|
1574
|
+
|
|
1575
|
+
There are two main types of precision.
|
|
1576
|
+
The first is relative precision; it gives the number of known
|
|
1577
|
+
`p`-adic digits::
|
|
1578
|
+
|
|
1579
|
+
sage: R = Zp(5, 20, 'capped-rel', 'series'); a = R(675); a
|
|
1580
|
+
2*5^2 + 5^4 + O(5^22)
|
|
1581
|
+
sage: a.precision_relative()
|
|
1582
|
+
20
|
|
1583
|
+
|
|
1584
|
+
The second type of precision is absolute precision, which gives
|
|
1585
|
+
the power of `p` that this element is defined modulo::
|
|
1586
|
+
|
|
1587
|
+
sage: a.precision_absolute()
|
|
1588
|
+
22
|
|
1589
|
+
|
|
1590
|
+
There are several types of `p`-adic rings, depending on the methods
|
|
1591
|
+
used for tracking precision. Namely, we have:
|
|
1592
|
+
|
|
1593
|
+
- capped relative rings (``type='capped-rel'``)
|
|
1594
|
+
|
|
1595
|
+
- capped absolute rings (``type='capped-abs'``)
|
|
1596
|
+
|
|
1597
|
+
- fixed modulus rings (``type='fixed-mod'``)
|
|
1598
|
+
|
|
1599
|
+
- floating point rings (``type='floating-point'``)
|
|
1600
|
+
|
|
1601
|
+
- lattice precision rings (``type='lattice-cap'`` or ``type='lattice-float'``)
|
|
1602
|
+
|
|
1603
|
+
- exact fields with relaxed arithmetics (``type='relaxed'``)
|
|
1604
|
+
|
|
1605
|
+
In the capped relative case, the relative precision of an element
|
|
1606
|
+
is restricted to be at most a certain value, specified at the
|
|
1607
|
+
creation of the field. Individual elements also store their own
|
|
1608
|
+
precision, so the effect of various arithmetic operations on
|
|
1609
|
+
precision is tracked. When you cast an exact element into a
|
|
1610
|
+
capped relative field, it truncates it to the precision cap of the
|
|
1611
|
+
field. ::
|
|
1612
|
+
|
|
1613
|
+
sage: R = Zp(5, 5, 'capped-rel', 'series'); a = R(4006); a
|
|
1614
|
+
1 + 5 + 2*5^3 + 5^4 + O(5^5)
|
|
1615
|
+
sage: b = R(4025); b
|
|
1616
|
+
5^2 + 2*5^3 + 5^4 + 5^5 + O(5^7)
|
|
1617
|
+
sage: a + b
|
|
1618
|
+
1 + 5 + 5^2 + 4*5^3 + 2*5^4 + O(5^5)
|
|
1619
|
+
|
|
1620
|
+
In the capped absolute type, instead of having a cap on the
|
|
1621
|
+
relative precision of an element there is instead a cap on the
|
|
1622
|
+
absolute precision. Elements still store their own precisions,
|
|
1623
|
+
and as with the capped relative case, exact elements are truncated
|
|
1624
|
+
when cast into the ring. ::
|
|
1625
|
+
|
|
1626
|
+
sage: R = Zp(5, 5, 'capped-abs', 'series'); a = R(4005); a
|
|
1627
|
+
5 + 2*5^3 + 5^4 + O(5^5)
|
|
1628
|
+
sage: b = R(4025); b
|
|
1629
|
+
5^2 + 2*5^3 + 5^4 + O(5^5)
|
|
1630
|
+
sage: a * b
|
|
1631
|
+
5^3 + 2*5^4 + O(5^5)
|
|
1632
|
+
sage: (a * b) // 5^3
|
|
1633
|
+
1 + 2*5 + O(5^2)
|
|
1634
|
+
|
|
1635
|
+
The fixed modulus type is the leanest of the `p`-adic rings: it is
|
|
1636
|
+
basically just a wrapper around `\ZZ / p^n \ZZ` providing a unified
|
|
1637
|
+
interface with the rest of the `p`-adics. This is the type you
|
|
1638
|
+
should use if your sole interest is speed. It does not track
|
|
1639
|
+
precision of elements. ::
|
|
1640
|
+
|
|
1641
|
+
sage: R = Zp(5,5,'fixed-mod','series'); a = R(4005); a
|
|
1642
|
+
5 + 2*5^3 + 5^4
|
|
1643
|
+
sage: a // 5
|
|
1644
|
+
1 + 2*5^2 + 5^3
|
|
1645
|
+
|
|
1646
|
+
The floating point case is similar to the fixed modulus type
|
|
1647
|
+
in that elements do not track their own precision. However, relative
|
|
1648
|
+
precision is truncated with each operation rather than absolute precision.
|
|
1649
|
+
|
|
1650
|
+
On the contrary, the lattice type tracks precision using lattices
|
|
1651
|
+
and automatic differentiation. It is rather slow but provides sharp
|
|
1652
|
+
(often optimal) results regarding precision.
|
|
1653
|
+
We refer to the documentation of the function :func:`ZpLC` for a
|
|
1654
|
+
small demonstration of the capabilities of this precision model.
|
|
1655
|
+
|
|
1656
|
+
Finally, the model for relaxed `p`-adics is quite different from any of
|
|
1657
|
+
the other types. In addition to storing a finite approximation, one
|
|
1658
|
+
also stores a method for increasing the precision.
|
|
1659
|
+
A quite interesting feature with relaxed `p`-adics is the possibility to
|
|
1660
|
+
create (in some cases) self-referent numbers, that are numbers whose
|
|
1661
|
+
`n`-th digit is defined by the previous ones.
|
|
1662
|
+
We refer to the documentation of the function :func:`ZpL` for a
|
|
1663
|
+
small demonstration of the capabilities of this precision model.
|
|
1664
|
+
|
|
1665
|
+
PRINTING:
|
|
1666
|
+
|
|
1667
|
+
There are many different ways to print `p`-adic elements. The
|
|
1668
|
+
way elements of a given ring print is controlled by options
|
|
1669
|
+
passed in at the creation of the ring. There are five basic
|
|
1670
|
+
printing modes (``'series'``, ``'val-unit'``, ``'terse'``, ``'digits'`` and ``'bars'``), as
|
|
1671
|
+
well as various options that either hide some information in
|
|
1672
|
+
the print representation or sometimes make print
|
|
1673
|
+
representations more compact. Note that the printing options
|
|
1674
|
+
affect whether different `p`-adic fields are considered equal.
|
|
1675
|
+
|
|
1676
|
+
1. **series**: elements are displayed as series in `p`. ::
|
|
1677
|
+
|
|
1678
|
+
sage: R = Zp(5, print_mode='series'); a = R(70700); a
|
|
1679
|
+
3*5^2 + 3*5^4 + 2*5^5 + 4*5^6 + O(5^22)
|
|
1680
|
+
sage: b = R(-70700); b
|
|
1681
|
+
2*5^2 + 4*5^3 + 5^4 + 2*5^5 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11
|
|
1682
|
+
+ 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + 4*5^17 + 4*5^18
|
|
1683
|
+
+ 4*5^19 + 4*5^20 + 4*5^21 + O(5^22)
|
|
1684
|
+
|
|
1685
|
+
*print_pos* controls whether negatives can be used in the
|
|
1686
|
+
coefficients of powers of `p`. ::
|
|
1687
|
+
|
|
1688
|
+
sage: S = Zp(5, print_mode='series', print_pos=False); a = S(70700); a
|
|
1689
|
+
-2*5^2 + 5^3 - 2*5^4 - 2*5^5 + 5^7 + O(5^22)
|
|
1690
|
+
sage: b = S(-70700); b
|
|
1691
|
+
2*5^2 - 5^3 + 2*5^4 + 2*5^5 - 5^7 + O(5^22)
|
|
1692
|
+
|
|
1693
|
+
*print_max_terms* limits the number of terms that appear. ::
|
|
1694
|
+
|
|
1695
|
+
sage: T = Zp(5, print_mode='series', print_max_terms=4); b = R(-70700); b
|
|
1696
|
+
2*5^2 + 4*5^3 + 5^4 + 2*5^5 + ... + O(5^22)
|
|
1697
|
+
|
|
1698
|
+
*names* affects how the prime is printed. ::
|
|
1699
|
+
|
|
1700
|
+
sage: U.<p> = Zp(5); p
|
|
1701
|
+
p + O(p^21)
|
|
1702
|
+
|
|
1703
|
+
*show_prec* determines how the precision is printed.
|
|
1704
|
+
It can be either 'none' (or equivalently ``False``), 'bigoh'
|
|
1705
|
+
(or equivalently ``True``).
|
|
1706
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
1707
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
1708
|
+
|
|
1709
|
+
sage: Zp(5, show_prec=False)(6)
|
|
1710
|
+
1 + 5
|
|
1711
|
+
|
|
1712
|
+
*print_sep* and *print_alphabet* have no effect.
|
|
1713
|
+
|
|
1714
|
+
Note that print options affect equality::
|
|
1715
|
+
|
|
1716
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U
|
|
1717
|
+
(False, False, False, False, False, False)
|
|
1718
|
+
|
|
1719
|
+
2. **val-unit**: elements are displayed as `p^k u`::
|
|
1720
|
+
|
|
1721
|
+
sage: R = Zp(5, print_mode='val-unit'); a = R(70700); a
|
|
1722
|
+
5^2 * 2828 + O(5^22)
|
|
1723
|
+
sage: b = R(-707*5); b
|
|
1724
|
+
5 * 95367431639918 + O(5^21)
|
|
1725
|
+
|
|
1726
|
+
*print_pos* controls whether to use a balanced representation or
|
|
1727
|
+
not. ::
|
|
1728
|
+
|
|
1729
|
+
sage: S = Zp(5, print_mode='val-unit', print_pos=False); b = S(-70700); b
|
|
1730
|
+
5^2 * (-2828) + O(5^22)
|
|
1731
|
+
|
|
1732
|
+
*names* affects how the prime is printed. ::
|
|
1733
|
+
|
|
1734
|
+
sage: T = Zp(5, print_mode='val-unit', names='pi'); a = T(70700); a
|
|
1735
|
+
pi^2 * 2828 + O(pi^22)
|
|
1736
|
+
|
|
1737
|
+
*show_prec* determines how the precision is printed.
|
|
1738
|
+
It can be either 'none' (or equivalently ``False``), 'bigoh'
|
|
1739
|
+
(or equivalently ``True``).
|
|
1740
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
1741
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
1742
|
+
|
|
1743
|
+
sage: Zp(5, print_mode='val-unit', show_prec=False)(30)
|
|
1744
|
+
5 * 6
|
|
1745
|
+
|
|
1746
|
+
*print_max_terms*, *print_sep* and *print_alphabet* have no effect.
|
|
1747
|
+
|
|
1748
|
+
Equality again depends on the printing options::
|
|
1749
|
+
|
|
1750
|
+
sage: R == S, R == T, S == T
|
|
1751
|
+
(False, False, False)
|
|
1752
|
+
|
|
1753
|
+
3. **terse**: elements are displayed as an integer in base 10::
|
|
1754
|
+
|
|
1755
|
+
sage: R = Zp(5, print_mode='terse'); a = R(70700); a
|
|
1756
|
+
70700 + O(5^22)
|
|
1757
|
+
sage: b = R(-70700); b
|
|
1758
|
+
2384185790944925 + O(5^22)
|
|
1759
|
+
|
|
1760
|
+
*print_pos* controls whether to use a balanced representation or not. ::
|
|
1761
|
+
|
|
1762
|
+
sage: S = Zp(5, print_mode='terse', print_pos=False); b = S(-70700); b
|
|
1763
|
+
-70700 + O(5^22)
|
|
1764
|
+
|
|
1765
|
+
*name* affects how the name is printed. Note that this interacts
|
|
1766
|
+
with the choice of shorter string for denominators. ::
|
|
1767
|
+
|
|
1768
|
+
sage: T.<unif> = Zp(5, print_mode='terse'); c = T(-707); c
|
|
1769
|
+
95367431639918 + O(unif^20)
|
|
1770
|
+
|
|
1771
|
+
*show_prec* determines how the precision is printed.
|
|
1772
|
+
It can be either 'none' (or equivalently ``False``), 'bigoh'
|
|
1773
|
+
(or equivalently ``True``).
|
|
1774
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
1775
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
1776
|
+
|
|
1777
|
+
sage: Zp(5, print_mode='terse', show_prec=False)(30)
|
|
1778
|
+
30
|
|
1779
|
+
|
|
1780
|
+
*print_max_terms*, *print_sep* and *print_alphabet* have no effect.
|
|
1781
|
+
|
|
1782
|
+
Equality depends on printing options::
|
|
1783
|
+
|
|
1784
|
+
sage: R == S, R == T, S == T
|
|
1785
|
+
(False, False, False)
|
|
1786
|
+
|
|
1787
|
+
4. **digits**: elements are displayed as a string of base `p` digits
|
|
1788
|
+
|
|
1789
|
+
Restriction: you can only use the digits printing mode for small
|
|
1790
|
+
primes. Namely, `p` must be less than the length of the alphabet
|
|
1791
|
+
tuple (default alphabet has length 62). ::
|
|
1792
|
+
|
|
1793
|
+
sage: R = Zp(5, print_mode='digits'); a = R(70700); repr(a)
|
|
1794
|
+
'...4230300'
|
|
1795
|
+
sage: b = R(-70700); repr(b)
|
|
1796
|
+
'...4444444444444440214200'
|
|
1797
|
+
|
|
1798
|
+
Note that it's not possible to read off the precision from the
|
|
1799
|
+
representation in this mode.
|
|
1800
|
+
|
|
1801
|
+
*print_max_terms* limits the number of digits that are printed. ::
|
|
1802
|
+
|
|
1803
|
+
sage: S = Zp(5, print_max_terms=4); S(-70700)
|
|
1804
|
+
2*5^2 + 4*5^3 + 5^4 + 2*5^5 + ... + O(5^22)
|
|
1805
|
+
|
|
1806
|
+
*print_alphabet* controls the symbols used to substitute for digits
|
|
1807
|
+
greater than 9. Defaults to
|
|
1808
|
+
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')::
|
|
1809
|
+
|
|
1810
|
+
sage: T = Zp(5, print_mode='digits', print_alphabet=('1','2','3','4','5'))
|
|
1811
|
+
sage: repr(T(-70700))
|
|
1812
|
+
'...5555555555555551325311'
|
|
1813
|
+
|
|
1814
|
+
*show_prec* determines how the precision is printed.
|
|
1815
|
+
It can be either ``'none'`` (or equivalently ``False``), ``'dots'``
|
|
1816
|
+
(or equivalently ``True``) or ``'bigoh'``.
|
|
1817
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
1818
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
1819
|
+
|
|
1820
|
+
sage: repr(Zp(5, 2, print_mode='digits', show_prec=True)(6))
|
|
1821
|
+
'...11'
|
|
1822
|
+
sage: repr(Zp(5, 2, print_mode='digits', show_prec='bigoh')(6))
|
|
1823
|
+
'11 + O(5^2)'
|
|
1824
|
+
|
|
1825
|
+
*print_pos*, *name* and *print_sep* have no effect.
|
|
1826
|
+
|
|
1827
|
+
Equality depends on printing options::
|
|
1828
|
+
|
|
1829
|
+
sage: R == S, R == T, S == T
|
|
1830
|
+
(False, False, False)
|
|
1831
|
+
|
|
1832
|
+
5. **bars**: elements are displayed as a string of base `p` digits
|
|
1833
|
+
with separators::
|
|
1834
|
+
|
|
1835
|
+
sage: R = Zp(5, print_mode='bars'); a = R(70700); repr(a)
|
|
1836
|
+
'...4|2|3|0|3|0|0'
|
|
1837
|
+
sage: b = R(-70700); repr(b)
|
|
1838
|
+
'...4|4|4|4|4|4|4|4|4|4|4|4|4|4|4|0|2|1|4|2|0|0'
|
|
1839
|
+
|
|
1840
|
+
Again, note that it's not possible to read off the precision from
|
|
1841
|
+
the representation in this mode.
|
|
1842
|
+
|
|
1843
|
+
*print_pos* controls whether the digits can be negative. ::
|
|
1844
|
+
|
|
1845
|
+
sage: S = Zp(5, print_mode='bars', print_pos=False); b = S(-70700); repr(b)
|
|
1846
|
+
'...-1|0|2|2|-1|2|0|0'
|
|
1847
|
+
|
|
1848
|
+
*print_max_terms* limits the number of digits that are printed. ::
|
|
1849
|
+
|
|
1850
|
+
sage: T = Zp(5, print_max_terms=4); T(-70700)
|
|
1851
|
+
2*5^2 + 4*5^3 + 5^4 + 2*5^5 + ... + O(5^22)
|
|
1852
|
+
|
|
1853
|
+
*print_sep* controls the separation character. ::
|
|
1854
|
+
|
|
1855
|
+
sage: U = Zp(5, print_mode='bars', print_sep=']['); a = U(70700); repr(a)
|
|
1856
|
+
'...4][2][3][0][3][0][0'
|
|
1857
|
+
|
|
1858
|
+
*show_prec* determines how the precision is printed.
|
|
1859
|
+
It can be either 'none' (or equivalently ``False``), 'dots'
|
|
1860
|
+
(or equivalently ``True``) or 'bigoh'.
|
|
1861
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
1862
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
1863
|
+
|
|
1864
|
+
sage: repr(Zp(5, 2, print_mode='bars', show_prec=True)(6))
|
|
1865
|
+
'...1|1'
|
|
1866
|
+
sage: repr(Zp(5, 2, print_mode='bars', show_prec=False)(6))
|
|
1867
|
+
'1|1'
|
|
1868
|
+
|
|
1869
|
+
*name* and *print_alphabet* have no effect.
|
|
1870
|
+
|
|
1871
|
+
Equality depends on printing options::
|
|
1872
|
+
|
|
1873
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U
|
|
1874
|
+
(False, False, False, False, False, False)
|
|
1875
|
+
|
|
1876
|
+
EXAMPLES:
|
|
1877
|
+
|
|
1878
|
+
We allow non-prime `p`, but only if ``check=False``. Note that some
|
|
1879
|
+
features will not work. ::
|
|
1880
|
+
|
|
1881
|
+
sage: K = Zp(15, check=False); a = K(999); a
|
|
1882
|
+
9 + 6*15 + 4*15^2 + O(15^20)
|
|
1883
|
+
|
|
1884
|
+
We create rings with various parameters::
|
|
1885
|
+
|
|
1886
|
+
sage: Zp(7)
|
|
1887
|
+
7-adic Ring with capped relative precision 20
|
|
1888
|
+
sage: Zp(9)
|
|
1889
|
+
Traceback (most recent call last):
|
|
1890
|
+
...
|
|
1891
|
+
ValueError: p must be prime
|
|
1892
|
+
sage: Zp(17, 5)
|
|
1893
|
+
17-adic Ring with capped relative precision 5
|
|
1894
|
+
sage: Zp(17, 5)(-1)
|
|
1895
|
+
16 + 16*17 + 16*17^2 + 16*17^3 + 16*17^4 + O(17^5)
|
|
1896
|
+
|
|
1897
|
+
It works even with a fairly huge cap::
|
|
1898
|
+
|
|
1899
|
+
sage: Zp(next_prime(10^50), 100000)
|
|
1900
|
+
100000000000000000000000000000000000000000000000151-adic Ring
|
|
1901
|
+
with capped relative precision 100000
|
|
1902
|
+
|
|
1903
|
+
We create each type of ring::
|
|
1904
|
+
|
|
1905
|
+
sage: Zp(7, 20, 'capped-rel')
|
|
1906
|
+
7-adic Ring with capped relative precision 20
|
|
1907
|
+
sage: Zp(7, 20, 'fixed-mod')
|
|
1908
|
+
7-adic Ring of fixed modulus 7^20
|
|
1909
|
+
sage: Zp(7, 20, 'capped-abs')
|
|
1910
|
+
7-adic Ring with capped absolute precision 20
|
|
1911
|
+
|
|
1912
|
+
We create a capped relative ring with each print mode::
|
|
1913
|
+
|
|
1914
|
+
sage: k = Zp(7, 8, print_mode='series'); k
|
|
1915
|
+
7-adic Ring with capped relative precision 8
|
|
1916
|
+
sage: k(7*(19))
|
|
1917
|
+
5*7 + 2*7^2 + O(7^9)
|
|
1918
|
+
sage: k(7*(-19))
|
|
1919
|
+
2*7 + 4*7^2 + 6*7^3 + 6*7^4 + 6*7^5 + 6*7^6 + 6*7^7 + 6*7^8 + O(7^9)
|
|
1920
|
+
|
|
1921
|
+
::
|
|
1922
|
+
|
|
1923
|
+
sage: k = Zp(7, print_mode='val-unit'); k
|
|
1924
|
+
7-adic Ring with capped relative precision 20
|
|
1925
|
+
sage: k(7*(19))
|
|
1926
|
+
7 * 19 + O(7^21)
|
|
1927
|
+
sage: k(7*(-19))
|
|
1928
|
+
7 * 79792266297611982 + O(7^21)
|
|
1929
|
+
|
|
1930
|
+
::
|
|
1931
|
+
|
|
1932
|
+
sage: k = Zp(7, print_mode='terse'); k
|
|
1933
|
+
7-adic Ring with capped relative precision 20
|
|
1934
|
+
sage: k(7*(19))
|
|
1935
|
+
133 + O(7^21)
|
|
1936
|
+
sage: k(7*(-19))
|
|
1937
|
+
558545864083283874 + O(7^21)
|
|
1938
|
+
|
|
1939
|
+
Note that `p`-adic rings are cached (via weak references)::
|
|
1940
|
+
|
|
1941
|
+
sage: a = Zp(7); b = Zp(7)
|
|
1942
|
+
sage: a is b
|
|
1943
|
+
True
|
|
1944
|
+
|
|
1945
|
+
We create some elements in various rings::
|
|
1946
|
+
|
|
1947
|
+
sage: R = Zp(5); a = R(4); a
|
|
1948
|
+
4 + O(5^20)
|
|
1949
|
+
sage: S = Zp(5, 10, type = 'capped-abs'); b = S(2); b
|
|
1950
|
+
2 + O(5^10)
|
|
1951
|
+
sage: a + b
|
|
1952
|
+
1 + 5 + O(5^10)
|
|
1953
|
+
"""
|
|
1954
|
+
def create_key(self, p, prec=None, type='capped-rel', print_mode=None,
|
|
1955
|
+
names=None, ram_name=None, print_pos=None, print_sep=None, print_alphabet=None,
|
|
1956
|
+
print_max_terms=None, show_prec=None, check=True,
|
|
1957
|
+
label=None):
|
|
1958
|
+
r"""
|
|
1959
|
+
Create a key from input parameters for ``Zp``.
|
|
1960
|
+
|
|
1961
|
+
See the documentation for :func:`Zp` for more information.
|
|
1962
|
+
|
|
1963
|
+
TESTS::
|
|
1964
|
+
|
|
1965
|
+
sage: Zp.create_key(5,40)
|
|
1966
|
+
(5, 40, 'capped-rel', 'series', '5', True, '|', (), -1, 'bigoh', None)
|
|
1967
|
+
sage: Zp.create_key(5,40,print_mode='digits')
|
|
1968
|
+
(5,
|
|
1969
|
+
40,
|
|
1970
|
+
'capped-rel',
|
|
1971
|
+
'digits',
|
|
1972
|
+
'5',
|
|
1973
|
+
True,
|
|
1974
|
+
'|',
|
|
1975
|
+
('0', '1', '2', '3', '4'),
|
|
1976
|
+
-1,
|
|
1977
|
+
'dots',
|
|
1978
|
+
None)
|
|
1979
|
+
"""
|
|
1980
|
+
if isinstance(names, (int, Integer)):
|
|
1981
|
+
# old pickle; names is what used to be halt.
|
|
1982
|
+
names = ram_name
|
|
1983
|
+
ram_name = print_pos
|
|
1984
|
+
print_pos = print_sep
|
|
1985
|
+
print_alphabet = print_max_terms
|
|
1986
|
+
print_max_terms = check
|
|
1987
|
+
check = True
|
|
1988
|
+
if label is not None and type not in ['lattice-cap','lattice-float']:
|
|
1989
|
+
raise ValueError("label keyword only supported for lattice precision")
|
|
1990
|
+
return get_key_base(p, prec, type, print_mode, names, ram_name, print_pos, print_sep, print_alphabet,
|
|
1991
|
+
print_max_terms, show_prec, check,
|
|
1992
|
+
['capped-rel', 'fixed-mod', 'capped-abs', 'floating-point', 'lattice-cap', 'lattice-float', 'relaxed'],
|
|
1993
|
+
label=label)
|
|
1994
|
+
|
|
1995
|
+
def create_object(self, version, key):
|
|
1996
|
+
r"""
|
|
1997
|
+
Create an object using a given key.
|
|
1998
|
+
|
|
1999
|
+
See the documentation for :func:`Zp` for more information.
|
|
2000
|
+
|
|
2001
|
+
TESTS::
|
|
2002
|
+
|
|
2003
|
+
sage: Zp.create_object((3,4,2),(5, 41, 'capped-rel', 'series', '5', True, '|', (), -1))
|
|
2004
|
+
5-adic Ring with capped relative precision 41
|
|
2005
|
+
"""
|
|
2006
|
+
if (version[0] < 3 or (len(version) > 1 and version[0] == 3 and version[1] < 2) or
|
|
2007
|
+
(len(version) > 2 and version[0] == 3 and version[1] == 2 and version[2] < 3)):
|
|
2008
|
+
p, prec, type, print_mode, name = key
|
|
2009
|
+
print_pos, print_sep, print_alphabet, print_max_terms = None, None, None, None
|
|
2010
|
+
elif version[0] < 8:
|
|
2011
|
+
p, prec, type, print_mode, name, print_pos, print_sep, print_alphabet, print_max_terms = key
|
|
2012
|
+
show_prec = None
|
|
2013
|
+
label = None
|
|
2014
|
+
else:
|
|
2015
|
+
p, prec, type, print_mode, name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, label = key
|
|
2016
|
+
if (version[0] < 4 or (len(version) > 1 and version[0] == 4 and version[1] < 5) or
|
|
2017
|
+
(len(version) > 2 and version[0] == 4 and version[1] == 5 and version[2] < 3)):
|
|
2018
|
+
# keys changed in order to reduce irrelevant duplications: e.g. two Zps with print_mode 'series'
|
|
2019
|
+
# that are identical except for different 'print_alphabet' now return the same object.
|
|
2020
|
+
key = get_key_base(p, prec, type, print_mode, name, None, print_pos, print_sep, print_alphabet,
|
|
2021
|
+
print_max_terms, None, False, ['capped-rel', 'fixed-mod', 'capped-abs', 'lattice-cap', 'lattice-float', 'relaxed'])
|
|
2022
|
+
try:
|
|
2023
|
+
obj = self._cache[version, key]()
|
|
2024
|
+
if obj is not None:
|
|
2025
|
+
return obj
|
|
2026
|
+
except KeyError:
|
|
2027
|
+
pass
|
|
2028
|
+
p, prec, type, print_mode, name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, label = key
|
|
2029
|
+
if type == 'capped-rel':
|
|
2030
|
+
return pAdicRingCappedRelative(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
2031
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name)
|
|
2032
|
+
elif type == 'fixed-mod':
|
|
2033
|
+
return pAdicRingFixedMod(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
2034
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name)
|
|
2035
|
+
elif type == 'capped-abs':
|
|
2036
|
+
return pAdicRingCappedAbsolute(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
2037
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name)
|
|
2038
|
+
elif type == 'floating-point':
|
|
2039
|
+
return pAdicRingFloatingPoint(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
2040
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name)
|
|
2041
|
+
elif type == 'relaxed':
|
|
2042
|
+
return pAdicRingRelaxed(p, prec, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
2043
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name)
|
|
2044
|
+
elif type[:8] == 'lattice-':
|
|
2045
|
+
subtype = type[8:]
|
|
2046
|
+
return pAdicRingLattice(p, prec, subtype, {'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
2047
|
+
'ram_name': name, 'max_ram_terms': print_max_terms, 'show_prec': show_prec}, name, label)
|
|
2048
|
+
else:
|
|
2049
|
+
raise ValueError("unexpected type")
|
|
2050
|
+
|
|
2051
|
+
|
|
2052
|
+
Zp = Zp_class("Zp")
|
|
2053
|
+
|
|
2054
|
+
|
|
2055
|
+
######################################################
|
|
2056
|
+
# Zq -- unramified extensions
|
|
2057
|
+
######################################################
|
|
2058
|
+
|
|
2059
|
+
def Zq(q, prec=None, type='capped-rel', modulus=None, names=None,
|
|
2060
|
+
print_mode=None, ram_name=None, res_name=None, print_pos=None,
|
|
2061
|
+
print_sep=None, print_max_ram_terms=None,
|
|
2062
|
+
print_max_unram_terms=None, print_max_terse_terms=None, show_prec=None, check=True, implementation='FLINT'):
|
|
2063
|
+
r"""
|
|
2064
|
+
Given a prime power `q = p^n`, return the unique unramified
|
|
2065
|
+
extension of `\ZZ_p` of degree `n`.
|
|
2066
|
+
|
|
2067
|
+
INPUT:
|
|
2068
|
+
|
|
2069
|
+
- ``q`` -- integer, list or tuple: the prime power in `\QQ_q`. Or a
|
|
2070
|
+
:class:`Factorization` object, single element list ``[(p, n)]`` where ``p`` is
|
|
2071
|
+
a prime and ``n`` a positive integer, or the pair ``(p, n)``.
|
|
2072
|
+
|
|
2073
|
+
- ``prec`` -- integer (default: 20); the precision cap of the
|
|
2074
|
+
field. Individual elements keep track of their own precision.
|
|
2075
|
+
See TYPES and PRECISION below.
|
|
2076
|
+
|
|
2077
|
+
- ``type`` -- string (default: ``'capped-rel'``); valid types are
|
|
2078
|
+
``'capped-abs'``, ``'capped-rel'``, ``'fixed-mod'``, and
|
|
2079
|
+
``'floating-point'``. See TYPES and PRECISION below.
|
|
2080
|
+
|
|
2081
|
+
- ``modulus`` -- polynomial (default: ``None``); a polynomial defining an
|
|
2082
|
+
unramified extension of `\ZZ_p`. See MODULUS below.
|
|
2083
|
+
|
|
2084
|
+
- ``names`` -- string or tuple (``None`` is only allowed when
|
|
2085
|
+
`q=p`); the name of the generator, reducing to a generator of
|
|
2086
|
+
the residue field
|
|
2087
|
+
|
|
2088
|
+
- ``print_mode`` -- string (default: ``None``); valid modes are ``'series'``,
|
|
2089
|
+
``'val-unit'``, ``'terse'``, and ``'bars'``. See PRINTING below.
|
|
2090
|
+
|
|
2091
|
+
- ``ram_name`` -- string (defaults to string representation of `p` if
|
|
2092
|
+
``None``); ``ram_name`` controls how the prime is printed. See PRINTING
|
|
2093
|
+
below.
|
|
2094
|
+
|
|
2095
|
+
- ``res_name`` -- string (defaults to ``None``, which corresponds
|
|
2096
|
+
to adding a ``'0'`` to the end of the name); controls how
|
|
2097
|
+
elements of the residue field print.
|
|
2098
|
+
|
|
2099
|
+
- ``print_pos`` -- boolean (default: ``None``); whether to only use
|
|
2100
|
+
positive integers in the representations of elements. See
|
|
2101
|
+
PRINTING below.
|
|
2102
|
+
|
|
2103
|
+
- ``print_sep`` -- string (default: ``None``); the separator
|
|
2104
|
+
character used in the ``'bars'`` mode. See PRINTING below.
|
|
2105
|
+
|
|
2106
|
+
- ``print_max_ram_terms`` -- integer (default: ``None``); the maximum
|
|
2107
|
+
number of powers of `p` shown. See PRINTING below.
|
|
2108
|
+
|
|
2109
|
+
- ``print_max_unram_terms`` -- integer (default: ``None``) the
|
|
2110
|
+
maximum number of entries shown in a coefficient of `p`. See
|
|
2111
|
+
PRINTING below.
|
|
2112
|
+
|
|
2113
|
+
- ``print_max_terse_terms`` -- integer (default: ``None``); the maximum
|
|
2114
|
+
number of terms in the polynomial representation of an element
|
|
2115
|
+
(using ``'terse'``). See PRINTING below.
|
|
2116
|
+
|
|
2117
|
+
- ``show_prec`` -- boolean (default: ``None``); whether to show the
|
|
2118
|
+
precision for elements. See PRINTING below.
|
|
2119
|
+
|
|
2120
|
+
- ``check`` -- boolean (default: ``True``) whether to check inputs
|
|
2121
|
+
|
|
2122
|
+
- ``implementation`` -- string (default: ``'FLINT'``); which
|
|
2123
|
+
implementation to use. ``'NTL'`` is the other option.
|
|
2124
|
+
|
|
2125
|
+
OUTPUT: the corresponding unramified `p`-adic ring
|
|
2126
|
+
|
|
2127
|
+
TYPES AND PRECISION:
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
There are two types of precision for a `p`-adic element. The first
|
|
2131
|
+
is relative precision (default), which gives the number of known `p`-adic
|
|
2132
|
+
digits::
|
|
2133
|
+
|
|
2134
|
+
sage: R.<a> = Zq(25, 20, 'capped-rel', print_mode='series'); b = 25*a; b # needs sage.libs.ntl
|
|
2135
|
+
a*5^2 + O(5^22)
|
|
2136
|
+
sage: b.precision_relative() # needs sage.libs.ntl
|
|
2137
|
+
20
|
|
2138
|
+
|
|
2139
|
+
The second type of precision is absolute precision, which gives
|
|
2140
|
+
the power of `p` that this element is defined modulo::
|
|
2141
|
+
|
|
2142
|
+
sage: b.precision_absolute() # needs sage.libs.ntl
|
|
2143
|
+
22
|
|
2144
|
+
|
|
2145
|
+
There are many types of `p`-adic rings: capped relative rings
|
|
2146
|
+
(``type='capped-rel'``), capped absolute rings
|
|
2147
|
+
(``type='capped-abs'``), fixed modulus rings (``type='fixed-mod'``),
|
|
2148
|
+
and floating point rings (``type='floating-point'``).
|
|
2149
|
+
|
|
2150
|
+
In the capped relative case, the relative precision of an element
|
|
2151
|
+
is restricted to be at most a certain value, specified at the
|
|
2152
|
+
creation of the field. Individual elements also store their own
|
|
2153
|
+
precision, so the effect of various arithmetic operations on
|
|
2154
|
+
precision is tracked. When you cast an exact element into a
|
|
2155
|
+
capped relative field, it truncates it to the precision cap of the
|
|
2156
|
+
field. ::
|
|
2157
|
+
|
|
2158
|
+
sage: R.<a> = Zq(9, 5, 'capped-rel', print_mode='series'); b = (1+2*a)^4; b # needs sage.libs.ntl
|
|
2159
|
+
2 + (2*a + 2)*3 + (2*a + 1)*3^2 + O(3^5)
|
|
2160
|
+
sage: c = R(3249); c # needs sage.libs.ntl
|
|
2161
|
+
3^2 + 3^4 + 3^5 + 3^6 + O(3^7)
|
|
2162
|
+
sage: b + c # needs sage.libs.ntl
|
|
2163
|
+
2 + (2*a + 2)*3 + (2*a + 2)*3^2 + 3^4 + O(3^5)
|
|
2164
|
+
|
|
2165
|
+
One can invert non-units: the result is in the fraction field. ::
|
|
2166
|
+
|
|
2167
|
+
sage: d = ~(3*b+c); d # needs sage.libs.ntl
|
|
2168
|
+
2*3^-1 + (a + 1) + (a + 1)*3 + a*3^3 + O(3^4)
|
|
2169
|
+
sage: d.parent() # needs sage.libs.ntl
|
|
2170
|
+
3-adic Unramified Extension Field in a defined by x^2 + 2*x + 2
|
|
2171
|
+
|
|
2172
|
+
The capped absolute case is the same as the capped relative case,
|
|
2173
|
+
except that the cap is on the absolute precision rather than the
|
|
2174
|
+
relative precision. ::
|
|
2175
|
+
|
|
2176
|
+
sage: # needs sage.libs.flint
|
|
2177
|
+
sage: R.<a> = Zq(9, 5, 'capped-abs', print_mode='series'); b = 3*(1+2*a)^4; b
|
|
2178
|
+
2*3 + (2*a + 2)*3^2 + (2*a + 1)*3^3 + O(3^5)
|
|
2179
|
+
sage: c = R(3249); c # needs sage.libs.ntl
|
|
2180
|
+
3^2 + 3^4 + O(3^5)
|
|
2181
|
+
sage: b*c # needs sage.libs.ntl
|
|
2182
|
+
2*3^3 + (2*a + 2)*3^4 + O(3^5)
|
|
2183
|
+
sage: b*c >> 1 # needs sage.libs.ntl
|
|
2184
|
+
2*3^2 + (2*a + 2)*3^3 + O(3^4)
|
|
2185
|
+
|
|
2186
|
+
The fixed modulus case is like the capped absolute, except that
|
|
2187
|
+
individual elements don't track their precision. ::
|
|
2188
|
+
|
|
2189
|
+
sage: # needs sage.libs.flint
|
|
2190
|
+
sage: R.<a> = Zq(9, 5, 'fixed-mod', print_mode='series'); b = 3*(1+2*a)^4; b
|
|
2191
|
+
2*3 + (2*a + 2)*3^2 + (2*a + 1)*3^3
|
|
2192
|
+
sage: c = R(3249); c # needs sage.libs.ntl
|
|
2193
|
+
3^2 + 3^4
|
|
2194
|
+
sage: b*c # needs sage.libs.ntl
|
|
2195
|
+
2*3^3 + (2*a + 2)*3^4
|
|
2196
|
+
sage: b*c >> 1 # needs sage.libs.ntl
|
|
2197
|
+
2*3^2 + (2*a + 2)*3^3
|
|
2198
|
+
|
|
2199
|
+
The floating point case is similar to the fixed modulus type
|
|
2200
|
+
in that elements do not track their own precision. However, relative
|
|
2201
|
+
precision is truncated with each operation rather than absolute precision.
|
|
2202
|
+
|
|
2203
|
+
MODULUS:
|
|
2204
|
+
|
|
2205
|
+
The modulus needs to define an unramified extension of `\ZZ_p`: when it
|
|
2206
|
+
is reduced to a polynomial over `\GF{p}` it should be irreducible.
|
|
2207
|
+
|
|
2208
|
+
The modulus can be given in a number of forms.
|
|
2209
|
+
|
|
2210
|
+
1. A **polynomial**.
|
|
2211
|
+
|
|
2212
|
+
The base ring can be `\ZZ`, `\QQ`, `\ZZ_p`, `\GF{p}`, or anything that can
|
|
2213
|
+
be converted to `\ZZ_p`. ::
|
|
2214
|
+
|
|
2215
|
+
sage: # needs sage.libs.ntl
|
|
2216
|
+
sage: P.<x> = ZZ[]
|
|
2217
|
+
sage: R.<a> = Zq(27, modulus = x^3 + 2*x + 1); R.modulus()
|
|
2218
|
+
(1 + O(3^20))*x^3 + O(3^20)*x^2 + (2 + O(3^20))*x + 1 + O(3^20)
|
|
2219
|
+
sage: P.<x> = QQ[]
|
|
2220
|
+
sage: S.<a> = Zq(27, modulus = x^3 + 2/7*x + 1)
|
|
2221
|
+
sage: P.<x> = Zp(3)[]
|
|
2222
|
+
sage: T.<a> = Zq(27, modulus = x^3 + 2*x + 1)
|
|
2223
|
+
sage: P.<x> = Qp(3)[]
|
|
2224
|
+
sage: U.<a> = Zq(27, modulus = x^3 + 2*x + 1)
|
|
2225
|
+
sage: P.<x> = GF(3)[] # needs sage.rings.finite_rings
|
|
2226
|
+
sage: V.<a> = Zq(27, modulus = x^3 + 2*x + 1)
|
|
2227
|
+
|
|
2228
|
+
Which form the modulus is given in has no effect on the unramified
|
|
2229
|
+
extension produced::
|
|
2230
|
+
|
|
2231
|
+
sage: R == S, R == T, T == U, U == V # needs sage.libs.ntl
|
|
2232
|
+
(False, True, True, False)
|
|
2233
|
+
|
|
2234
|
+
unless the modulus is different, or the precision of the modulus
|
|
2235
|
+
differs. In the case of ``V``, the modulus is only given to precision
|
|
2236
|
+
``1``, so the resulting field has a precision cap of ``1``. ::
|
|
2237
|
+
|
|
2238
|
+
sage: # needs sage.libs.ntl
|
|
2239
|
+
sage: V.precision_cap()
|
|
2240
|
+
1
|
|
2241
|
+
sage: U.precision_cap()
|
|
2242
|
+
20
|
|
2243
|
+
sage: P.<x> = Zp(3)[]
|
|
2244
|
+
sage: modulus = x^3 + (2 + O(3^7))*x + (1 + O(3^10))
|
|
2245
|
+
sage: modulus
|
|
2246
|
+
(1 + O(3^20))*x^3 + (2 + O(3^7))*x + 1 + O(3^10)
|
|
2247
|
+
sage: W.<a> = Zq(27, modulus = modulus); W.precision_cap()
|
|
2248
|
+
7
|
|
2249
|
+
|
|
2250
|
+
2. The modulus can also be given as a **symbolic expression**. ::
|
|
2251
|
+
|
|
2252
|
+
sage: x = var('x') # needs sage.symbolic
|
|
2253
|
+
sage: X.<a> = Zq(27, modulus = x^3 + 2*x + 1); X.modulus() # needs sage.symbolic
|
|
2254
|
+
(1 + O(3^20))*x^3 + O(3^20)*x^2 + (2 + O(3^20))*x + 1 + O(3^20)
|
|
2255
|
+
sage: X == R # needs sage.libs.ntl sage.symbolic
|
|
2256
|
+
True
|
|
2257
|
+
|
|
2258
|
+
By default, the polynomial chosen is the standard lift of the
|
|
2259
|
+
generator chosen for `\GF{q}`. ::
|
|
2260
|
+
|
|
2261
|
+
sage: GF(125, 'a').modulus() # needs sage.rings.finite_rings
|
|
2262
|
+
x^3 + 3*x + 3
|
|
2263
|
+
sage: Y.<a> = Zq(125); Y.modulus() # needs sage.libs.ntl
|
|
2264
|
+
(1 + O(5^20))*x^3 + O(5^20)*x^2 + (3 + O(5^20))*x + 3 + O(5^20)
|
|
2265
|
+
|
|
2266
|
+
However, you can choose another polynomial if desired (as long as
|
|
2267
|
+
the reduction to `\GF{p}[x]` is irreducible). ::
|
|
2268
|
+
|
|
2269
|
+
sage: P.<x> = ZZ[]
|
|
2270
|
+
sage: Z.<a> = Zq(125, modulus = x^3 + 3*x^2 + x + 1); Z.modulus() # needs sage.libs.ntl
|
|
2271
|
+
(1 + O(5^20))*x^3 + (3 + O(5^20))*x^2 + (1 + O(5^20))*x + 1 + O(5^20)
|
|
2272
|
+
sage: Y == Z # needs sage.libs.ntl
|
|
2273
|
+
False
|
|
2274
|
+
|
|
2275
|
+
PRINTING:
|
|
2276
|
+
|
|
2277
|
+
There are many different ways to print `p`-adic elements. The way
|
|
2278
|
+
elements of a given field print is controlled by options passed in
|
|
2279
|
+
at the creation of the field. There are four basic printing modes
|
|
2280
|
+
(``'series'``, ``'val-unit'``, ``'terse'`` and ``'bars'``; ``'digits'`` is not available), as
|
|
2281
|
+
well as various options that either hide some information in the
|
|
2282
|
+
print representation or sometimes make print representations more
|
|
2283
|
+
compact. Note that the printing options affect whether different
|
|
2284
|
+
`p`-adic fields are considered equal.
|
|
2285
|
+
|
|
2286
|
+
1. **series**: elements are displayed as series in `p`. ::
|
|
2287
|
+
|
|
2288
|
+
sage: # needs sage.libs.ntl
|
|
2289
|
+
sage: R.<a> = Zq(9, 20, 'capped-rel', print_mode='series'); (1+2*a)^4
|
|
2290
|
+
2 + (2*a + 2)*3 + (2*a + 1)*3^2 + O(3^20)
|
|
2291
|
+
sage: -3*(1+2*a)^4
|
|
2292
|
+
3 + a*3^2 + 3^3 + (2*a + 2)*3^4 + (2*a + 2)*3^5 + (2*a + 2)*3^6 + (2*a + 2)*3^7
|
|
2293
|
+
+ (2*a + 2)*3^8 + (2*a + 2)*3^9 + (2*a + 2)*3^10 + (2*a + 2)*3^11 + (2*a + 2)*3^12
|
|
2294
|
+
+ (2*a + 2)*3^13 + (2*a + 2)*3^14 + (2*a + 2)*3^15 + (2*a + 2)*3^16
|
|
2295
|
+
+ (2*a + 2)*3^17 + (2*a + 2)*3^18 + (2*a + 2)*3^19 + (2*a + 2)*3^20 + O(3^21)
|
|
2296
|
+
sage: b = ~(3*a+18); b
|
|
2297
|
+
(a + 2)*3^-1 + 1 + 2*3 + (a + 1)*3^2 + 3^3 + 2*3^4 + (a + 1)*3^5 + 3^6 + 2*3^7
|
|
2298
|
+
+ (a + 1)*3^8 + 3^9 + 2*3^10 + (a + 1)*3^11 + 3^12 + 2*3^13 + (a + 1)*3^14
|
|
2299
|
+
+ 3^15 + 2*3^16 + (a + 1)*3^17 + 3^18 + O(3^19)
|
|
2300
|
+
sage: b.parent() is R.fraction_field()
|
|
2301
|
+
True
|
|
2302
|
+
|
|
2303
|
+
*print_pos* controls whether negatives can be used in the
|
|
2304
|
+
coefficients of powers of `p`. ::
|
|
2305
|
+
|
|
2306
|
+
sage: S.<b> = Zq(9, print_mode='series', print_pos=False); (1+2*b)^4 # needs sage.libs.ntl
|
|
2307
|
+
-1 - b*3 - 3^2 + (b + 1)*3^3 + O(3^20)
|
|
2308
|
+
sage: -3*(1+2*b)^4 # needs sage.libs.ntl
|
|
2309
|
+
3 + b*3^2 + 3^3 + (-b - 1)*3^4 + O(3^21)
|
|
2310
|
+
|
|
2311
|
+
*ram_name* controls how the prime is printed. ::
|
|
2312
|
+
|
|
2313
|
+
sage: T.<d> = Zq(9, print_mode='series', ram_name='p'); 3*(1+2*d)^4 # needs sage.libs.ntl
|
|
2314
|
+
2*p + (2*d + 2)*p^2 + (2*d + 1)*p^3 + O(p^21)
|
|
2315
|
+
|
|
2316
|
+
*print_max_ram_terms* limits the number of powers of `p` that
|
|
2317
|
+
appear. ::
|
|
2318
|
+
|
|
2319
|
+
sage: U.<e> = Zq(9, print_mode='series', print_max_ram_terms=4); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
2320
|
+
'3 + e*3^2 + 3^3 + (2*e + 2)*3^4 + ... + O(3^21)'
|
|
2321
|
+
|
|
2322
|
+
*print_max_unram_terms* limits the number of terms that appear in a
|
|
2323
|
+
coefficient of a power of `p`. ::
|
|
2324
|
+
|
|
2325
|
+
sage: # needs sage.libs.ntl
|
|
2326
|
+
sage: V.<f> = Zq(128, prec = 8, print_mode='series'); repr((1+f)^9)
|
|
2327
|
+
'(f^3 + 1) + (f^5 + f^4 + f^3 + f^2)*2 + (f^6 + f^5 + f^4 + f + 1)*2^2 + (f^5 + f^4 + f^2 + f + 1)*2^3 + (f^6 + f^5 + f^4 + f^3 + f^2 + f + 1)*2^4 + (f^5 + f^4)*2^5 + (f^6 + f^5 + f^4 + f^3 + f + 1)*2^6 + (f + 1)*2^7 + O(2^8)'
|
|
2328
|
+
sage: V.<f> = Zq(128, prec = 8, print_mode='series', print_max_unram_terms = 3); repr((1+f)^9)
|
|
2329
|
+
'(f^3 + 1) + (f^5 + f^4 + ... + f^2)*2 + (f^6 + f^5 + ... + 1)*2^2 + (f^5 + f^4 + ... + 1)*2^3 + (f^6 + f^5 + ... + 1)*2^4 + (f^5 + f^4)*2^5 + (f^6 + f^5 + ... + 1)*2^6 + (f + 1)*2^7 + O(2^8)'
|
|
2330
|
+
sage: V.<f> = Zq(128, prec = 8, print_mode='series', print_max_unram_terms = 2); repr((1+f)^9)
|
|
2331
|
+
'(f^3 + 1) + (f^5 + ... + f^2)*2 + (f^6 + ... + 1)*2^2 + (f^5 + ... + 1)*2^3 + (f^6 + ... + 1)*2^4 + (f^5 + f^4)*2^5 + (f^6 + ... + 1)*2^6 + (f + 1)*2^7 + O(2^8)'
|
|
2332
|
+
sage: V.<f> = Zq(128, prec = 8, print_mode='series', print_max_unram_terms = 1); repr((1+f)^9)
|
|
2333
|
+
'(f^3 + ...) + (f^5 + ...)*2 + (f^6 + ...)*2^2 + (f^5 + ...)*2^3 + (f^6 + ...)*2^4 + (f^5 + ...)*2^5 + (f^6 + ...)*2^6 + (f + ...)*2^7 + O(2^8)'
|
|
2334
|
+
sage: V.<f> = Zq(128, prec = 8, print_mode='series', print_max_unram_terms = 0); repr((1+f)^9 - 1 - f^3)
|
|
2335
|
+
'(...)*2 + (...)*2^2 + (...)*2^3 + (...)*2^4 + (...)*2^5 + (...)*2^6 + (...)*2^7 + O(2^8)'
|
|
2336
|
+
|
|
2337
|
+
*show_prec* determines how the precision is printed.
|
|
2338
|
+
It can be either ``'none'`` (or equivalently ``False``), ``'bigoh'``
|
|
2339
|
+
(or equivalently ``True``).
|
|
2340
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
2341
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
2342
|
+
|
|
2343
|
+
sage: U.<e> = Zq(9, 2, show_prec=False); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
2344
|
+
'3 + e*3^2'
|
|
2345
|
+
|
|
2346
|
+
*print_sep* and *print_max_terse_terms* have no effect.
|
|
2347
|
+
|
|
2348
|
+
Note that print options affect equality::
|
|
2349
|
+
|
|
2350
|
+
sage: R == S, R == T, R == U, R == V, S == T, S == U, S == V, T == U, T == V, U == V # needs sage.libs.ntl
|
|
2351
|
+
(False, False, False, False, False, False, False, False, False, False)
|
|
2352
|
+
|
|
2353
|
+
2. **val-unit**: elements are displayed as `p^k u`::
|
|
2354
|
+
|
|
2355
|
+
sage: R.<a> = Zq(9, 7, print_mode='val-unit'); b = (1+3*a)^9 - 1; b # needs sage.libs.ntl
|
|
2356
|
+
3^3 * (15 + 64*a) + O(3^7)
|
|
2357
|
+
sage: ~b # needs sage.libs.ntl
|
|
2358
|
+
3^-3 * (41 + a) + O(3)
|
|
2359
|
+
|
|
2360
|
+
*print_pos* controls whether to use a balanced representation or
|
|
2361
|
+
not. ::
|
|
2362
|
+
|
|
2363
|
+
sage: S.<a> = Zq(9, 7, print_mode='val-unit', print_pos=False); b = (1+3*a)^9 - 1; b # needs sage.libs.ntl
|
|
2364
|
+
3^3 * (15 - 17*a) + O(3^7)
|
|
2365
|
+
sage: ~b # needs sage.libs.ntl
|
|
2366
|
+
3^-3 * (-40 + a) + O(3)
|
|
2367
|
+
|
|
2368
|
+
*ram_name* affects how the prime is printed. ::
|
|
2369
|
+
|
|
2370
|
+
sage: # needs sage.libs.ntl
|
|
2371
|
+
sage: A.<x> = Zp(next_prime(10^6), print_mode='val-unit')[]
|
|
2372
|
+
sage: T.<a> = Zq(next_prime(10^6)^3, 4, print_mode='val-unit', ram_name='p',
|
|
2373
|
+
....: modulus=x^3+385831*x^2+106556*x+321036)
|
|
2374
|
+
sage: b = next_prime(10^6)^2*(a^2 + a - 4)^4; b
|
|
2375
|
+
p^2 * (87996187118837557387483 + 246348888344392418464080*a + 1353538653775332610349*a^2)
|
|
2376
|
+
+ O(p^6)
|
|
2377
|
+
sage: b * (a^2 + a - 4)^-4
|
|
2378
|
+
p^2 * 1 + O(p^6)
|
|
2379
|
+
|
|
2380
|
+
*print_max_terse_terms* controls how many terms of the polynomial
|
|
2381
|
+
appear in the unit part. ::
|
|
2382
|
+
|
|
2383
|
+
sage: # needs sage.libs.ntl
|
|
2384
|
+
sage: U.<a> = Zq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3)
|
|
2385
|
+
sage: b = 17*(a^3-a+14)^6; b
|
|
2386
|
+
17 * (12131797 + 12076378*a + 10809706*a^2 + ...) + O(17^7)
|
|
2387
|
+
|
|
2388
|
+
*show_prec* determines how the precision is printed.
|
|
2389
|
+
It can be either ``'none'`` (or equivalently ``False``), ``'bigoh'``
|
|
2390
|
+
(or equivalently ``True``).
|
|
2391
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
2392
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
2393
|
+
|
|
2394
|
+
sage: U.<e> = Zq(9, 2, print_mode='val-unit', show_prec=False); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
2395
|
+
'3 * (1 + 3*e)'
|
|
2396
|
+
|
|
2397
|
+
*print_sep*, *print_max_ram_terms* and *print_max_unram_terms* have no effect.
|
|
2398
|
+
|
|
2399
|
+
Equality again depends on the printing options::
|
|
2400
|
+
|
|
2401
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U # needs sage.libs.ntl
|
|
2402
|
+
(False, False, False, False, False, False)
|
|
2403
|
+
|
|
2404
|
+
3. **terse**: elements are displayed as a polynomial of degree less
|
|
2405
|
+
than the degree of the extension. ::
|
|
2406
|
+
|
|
2407
|
+
sage: # needs sage.libs.ntl
|
|
2408
|
+
sage: R.<a> = Zq(125, print_mode='terse')
|
|
2409
|
+
sage: (a+5)^177
|
|
2410
|
+
68210977979428 + 90313850704069*a + 73948093055069*a^2 + O(5^20)
|
|
2411
|
+
sage: (a/5+1)^177
|
|
2412
|
+
68210977979428/5^177 + 90313850704069/5^177*a + 73948093055069/5^177*a^2 + O(5^-157)
|
|
2413
|
+
|
|
2414
|
+
Note that in this last computation, you get one fewer `p`-adic digit
|
|
2415
|
+
than one might expect. This is because ``R`` is capped absolute, and
|
|
2416
|
+
thus 5 is cast in with relative precision 19.
|
|
2417
|
+
|
|
2418
|
+
As of version 3.3, if coefficients of the polynomial are
|
|
2419
|
+
non-integral, they are always printed with an explicit power of `p`
|
|
2420
|
+
in the denominator. ::
|
|
2421
|
+
|
|
2422
|
+
sage: # needs sage.libs.ntl
|
|
2423
|
+
sage: 5*a + a^2/25
|
|
2424
|
+
5*a + 1/5^2*a^2 + O(5^18)
|
|
2425
|
+
|
|
2426
|
+
*print_pos* controls whether to use a balanced representation or
|
|
2427
|
+
not. ::
|
|
2428
|
+
|
|
2429
|
+
sage: # needs sage.libs.ntl
|
|
2430
|
+
sage: (a-5)^6
|
|
2431
|
+
22864 + 95367431627998*a + 8349*a^2 + O(5^20)
|
|
2432
|
+
sage: S.<a> = Zq(125, print_mode='terse', print_pos=False); b = (a-5)^6; b
|
|
2433
|
+
22864 - 12627*a + 8349*a^2 + O(5^20)
|
|
2434
|
+
sage: (a - 1/5)^6
|
|
2435
|
+
-20624/5^6 + 18369/5^5*a + 1353/5^3*a^2 + O(5^14)
|
|
2436
|
+
|
|
2437
|
+
*ram_name* affects how the prime is printed. ::
|
|
2438
|
+
|
|
2439
|
+
sage: T.<a> = Zq(125, print_mode='terse', ram_name='p'); (a - 1/5)^6 # needs sage.libs.ntl
|
|
2440
|
+
95367431620001/p^6 + 18369/p^5*a + 1353/p^3*a^2 + O(p^14)
|
|
2441
|
+
|
|
2442
|
+
*print_max_terse_terms* controls how many terms of the polynomial
|
|
2443
|
+
are shown. ::
|
|
2444
|
+
|
|
2445
|
+
sage: U.<a> = Zq(625, print_mode='terse', print_max_terse_terms=2); (a-1/5)^6 # needs sage.libs.ntl
|
|
2446
|
+
106251/5^6 + 49994/5^5*a + ... + O(5^14)
|
|
2447
|
+
|
|
2448
|
+
*show_prec* determines how the precision is printed.
|
|
2449
|
+
It can be either ``'none'`` (or equivalently ``False``), ``'bigoh'``
|
|
2450
|
+
(or equivalently ``True``).
|
|
2451
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
2452
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
2453
|
+
|
|
2454
|
+
sage: U.<e> = Zq(9, 2, print_mode='terse', show_prec=False); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
2455
|
+
'3 + 9*e'
|
|
2456
|
+
|
|
2457
|
+
*print_sep*, *print_max_ram_terms* and *print_max_unram_terms* have no
|
|
2458
|
+
effect.
|
|
2459
|
+
|
|
2460
|
+
Equality again depends on the printing options::
|
|
2461
|
+
|
|
2462
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U # needs sage.libs.ntl
|
|
2463
|
+
(False, False, False, False, False, False)
|
|
2464
|
+
|
|
2465
|
+
4. **digits**: This print mode is not available when the residue
|
|
2466
|
+
field is not prime. It might make sense to have a dictionary
|
|
2467
|
+
for small fields, but this isn't implemented.
|
|
2468
|
+
|
|
2469
|
+
5. **bars**: elements are displayed in a similar fashion to series,
|
|
2470
|
+
but more compactly. ::
|
|
2471
|
+
|
|
2472
|
+
sage: # needs sage.libs.ntl
|
|
2473
|
+
sage: R.<a> = Zq(125); (a+5)^6
|
|
2474
|
+
(4*a^2 + 3*a + 4) + (3*a^2 + 2*a)*5 + (a^2 + a + 1)*5^2 + (3*a + 2)*5^3
|
|
2475
|
+
+ (3*a^2 + a + 3)*5^4 + (2*a^2 + 3*a + 2)*5^5 + O(5^20)
|
|
2476
|
+
sage: R.<a> = Zq(125, print_mode='bars', prec=8); repr((a+5)^6)
|
|
2477
|
+
'...[2, 3, 2]|[3, 1, 3]|[2, 3]|[1, 1, 1]|[0, 2, 3]|[4, 3, 4]'
|
|
2478
|
+
sage: repr((a-5)^6)
|
|
2479
|
+
'...[0, 4]|[1, 4]|[2, 0, 2]|[1, 4, 3]|[2, 3, 1]|[4, 4, 3]|[2, 4, 4]|[4, 3, 4]'
|
|
2480
|
+
|
|
2481
|
+
Note that it's not possible to read off the precision from the
|
|
2482
|
+
representation in this mode. ::
|
|
2483
|
+
|
|
2484
|
+
sage: # needs sage.libs.ntl
|
|
2485
|
+
sage: b = a + 3; repr(b)
|
|
2486
|
+
'...[3, 1]'
|
|
2487
|
+
sage: c = a + R(3, 4); repr(c)
|
|
2488
|
+
'...[3, 1]'
|
|
2489
|
+
sage: b.precision_absolute()
|
|
2490
|
+
8
|
|
2491
|
+
sage: c.precision_absolute()
|
|
2492
|
+
4
|
|
2493
|
+
|
|
2494
|
+
*print_pos* controls whether the digits can be negative. ::
|
|
2495
|
+
|
|
2496
|
+
sage: # needs sage.libs.ntl
|
|
2497
|
+
sage: S.<a> = Zq(125, print_mode='bars', print_pos=False); repr((a-5)^6)
|
|
2498
|
+
'...[1, -1, 1]|[2, 1, -2]|[2, 0, -2]|[-2, -1, 2]|[0, 0, -1]|[-2]|[-1, -2, -1]'
|
|
2499
|
+
sage: repr((a-1/5)^6)
|
|
2500
|
+
'...[0, 1, 2]|[-1, 1, 1]|.|[-2, -1, -1]|[2, 2, 1]|[0, 0, -2]|[0, -1]|[0, -1]|[1]'
|
|
2501
|
+
|
|
2502
|
+
*print_max_ram_terms* controls the maximum number of "digits" shown.
|
|
2503
|
+
Note that this puts a cap on the relative precision, not the
|
|
2504
|
+
absolute precision. ::
|
|
2505
|
+
|
|
2506
|
+
sage: # needs sage.libs.ntl
|
|
2507
|
+
sage: T.<a> = Zq(125, print_max_ram_terms=3, print_pos=False); (a-5)^6
|
|
2508
|
+
(-a^2 - 2*a - 1) - 2*5 - a^2*5^2 + ... + O(5^20)
|
|
2509
|
+
sage: 5*(a-5)^6 + 50
|
|
2510
|
+
(-a^2 - 2*a - 1)*5 - a^2*5^3 + (2*a^2 - a - 2)*5^4 + ... + O(5^21)
|
|
2511
|
+
sage: (a-1/5)^6
|
|
2512
|
+
5^-6 - a*5^-5 - a*5^-4 + ... + O(5^14)
|
|
2513
|
+
|
|
2514
|
+
*print_sep* controls the separating character (``'|'`` by default). ::
|
|
2515
|
+
|
|
2516
|
+
sage: U.<a> = Zq(625, print_mode='bars', print_sep=''); b = (a+5)^6; repr(b) # needs sage.libs.ntl
|
|
2517
|
+
'...[0, 1][4, 0, 2][3, 2, 2, 3][4, 2, 2, 4][0, 3][1, 1, 3][3, 1, 4, 1]'
|
|
2518
|
+
|
|
2519
|
+
*print_max_unram_terms* controls how many terms are shown in each
|
|
2520
|
+
``'digit'``::
|
|
2521
|
+
|
|
2522
|
+
sage: # needs sage.libs.ntl
|
|
2523
|
+
sage: with local_print_mode(U, {'max_unram_terms': 3}): repr(b)
|
|
2524
|
+
'...[0, 1][4,..., 0, 2][3,..., 2, 3][4,..., 2, 4][0, 3][1,..., 1, 3][3,..., 4, 1]'
|
|
2525
|
+
sage: with local_print_mode(U, {'max_unram_terms': 2}): repr(b)
|
|
2526
|
+
'...[0, 1][4,..., 2][3,..., 3][4,..., 4][0, 3][1,..., 3][3,..., 1]'
|
|
2527
|
+
sage: with local_print_mode(U, {'max_unram_terms': 1}): repr(b)
|
|
2528
|
+
'...[..., 1][..., 2][..., 3][..., 4][..., 3][..., 3][..., 1]'
|
|
2529
|
+
sage: with local_print_mode(U, {'max_unram_terms':0}): repr(b-75*a)
|
|
2530
|
+
'...[...][...][...][...][][...][...]'
|
|
2531
|
+
|
|
2532
|
+
*show_prec* determines how the precision is printed.
|
|
2533
|
+
It can be either ``'none'`` (or equivalently ``False``), ``'dots'``
|
|
2534
|
+
(or equivalently ``True``) or ``'bigoh'``.
|
|
2535
|
+
The default is ``False`` for the ``'floating-point'`` and
|
|
2536
|
+
``'fixed-mod'`` types and ``True`` for all other types. ::
|
|
2537
|
+
|
|
2538
|
+
sage: U.<e> = Zq(9, 2, print_mode='bars', show_prec='bigoh'); repr(-3*(1+2*e)^4) # needs sage.libs.ntl
|
|
2539
|
+
'[0, 1]|[1]|[] + O(3^3)'
|
|
2540
|
+
|
|
2541
|
+
*ram_name* and *print_max_terse_terms* have no effect.
|
|
2542
|
+
|
|
2543
|
+
Equality depends on printing options::
|
|
2544
|
+
|
|
2545
|
+
sage: R == S, R == T, R == U, S == T, S == U, T == U # needs sage.libs.ntl
|
|
2546
|
+
(False, False, False, False, False, False)
|
|
2547
|
+
|
|
2548
|
+
EXAMPLES:
|
|
2549
|
+
|
|
2550
|
+
Unlike for :func:`Zp`, you can't create ``Zq(N)`` when ``N`` is not a prime power.
|
|
2551
|
+
|
|
2552
|
+
However, you can use ``check=False`` to pass in a pair in order to not
|
|
2553
|
+
have to factor. If you do so, you need to use names explicitly
|
|
2554
|
+
rather than the ``R.<a>`` syntax. ::
|
|
2555
|
+
|
|
2556
|
+
sage: # needs sage.libs.ntl
|
|
2557
|
+
sage: p = next_prime(2^123)
|
|
2558
|
+
sage: k = Zp(p)
|
|
2559
|
+
sage: R.<x> = k[]
|
|
2560
|
+
sage: K = Zq([(p, 5)], modulus=x^5+x+4, names='a', ram_name='p',
|
|
2561
|
+
....: print_pos=False, check=False)
|
|
2562
|
+
sage: K.0^5
|
|
2563
|
+
(-a - 4) + O(p^20)
|
|
2564
|
+
|
|
2565
|
+
In tests on sage.math, the creation of ``K`` as above took an average
|
|
2566
|
+
of 1.58ms, while::
|
|
2567
|
+
|
|
2568
|
+
sage: K = Zq(p^5, modulus=x^5+x+4, names='a', ram_name='p', # needs sage.libs.ntl
|
|
2569
|
+
....: print_pos=False, check=True)
|
|
2570
|
+
|
|
2571
|
+
took an average of 24.5ms. Of course, with smaller primes these
|
|
2572
|
+
savings disappear.
|
|
2573
|
+
|
|
2574
|
+
TESTS::
|
|
2575
|
+
|
|
2576
|
+
sage: # needs sage.libs.ntl
|
|
2577
|
+
sage: R = Zq([(5,3)], names='alpha'); R
|
|
2578
|
+
5-adic Unramified Extension Ring in alpha defined by x^3 + 3*x + 3
|
|
2579
|
+
sage: Zq((5, 3), names='alpha') is R
|
|
2580
|
+
True
|
|
2581
|
+
sage: Zq(125.factor(), names='alpha') is R
|
|
2582
|
+
True
|
|
2583
|
+
"""
|
|
2584
|
+
if check:
|
|
2585
|
+
if isinstance(q, (Factorization, list, tuple)):
|
|
2586
|
+
if not isinstance(q, Factorization) and len(q) == 2:
|
|
2587
|
+
F = [(Integer(q[0]), Integer(q[1]))]
|
|
2588
|
+
else:
|
|
2589
|
+
if len(q) != 1:
|
|
2590
|
+
raise ValueError("q must be a prime power")
|
|
2591
|
+
if len(q[0]) != 2:
|
|
2592
|
+
raise ValueError("q must have shape [(p, k)]")
|
|
2593
|
+
F = [(Integer(q[0][0]), Integer(q[0][1]))]
|
|
2594
|
+
if not F[0][0].is_prime() or F[0][1] <= 0:
|
|
2595
|
+
raise ValueError("q must be a prime power")
|
|
2596
|
+
q = F[0][0]**F[0][1]
|
|
2597
|
+
else:
|
|
2598
|
+
q = Integer(q)
|
|
2599
|
+
F = q.factor()
|
|
2600
|
+
if len(F) != 1:
|
|
2601
|
+
raise ValueError("q must be a prime power")
|
|
2602
|
+
if prec is not None and not isinstance(prec, Integer):
|
|
2603
|
+
prec = Integer(prec)
|
|
2604
|
+
if isinstance(names, (list, tuple)):
|
|
2605
|
+
names = names[0]
|
|
2606
|
+
from sage.structure.element import Expression
|
|
2607
|
+
if not (modulus is None or isinstance(modulus, (Polynomial,
|
|
2608
|
+
Expression))):
|
|
2609
|
+
raise TypeError("modulus must be a polynomial")
|
|
2610
|
+
if names is not None and not isinstance(names, str):
|
|
2611
|
+
names = str(names)
|
|
2612
|
+
# raise TypeError("names must be a string")
|
|
2613
|
+
q = Integer(q)
|
|
2614
|
+
F = q.factor()
|
|
2615
|
+
if len(F) != 1:
|
|
2616
|
+
raise ValueError("q must be a prime power")
|
|
2617
|
+
else:
|
|
2618
|
+
F = q
|
|
2619
|
+
q = F[0][0]**F[0][1]
|
|
2620
|
+
base = Zp(p=F[0][0], prec=prec, type=type, print_mode=print_mode, names=ram_name,
|
|
2621
|
+
print_pos=print_pos, print_sep=print_sep, print_max_terms=print_max_ram_terms,
|
|
2622
|
+
show_prec=show_prec, check=False)
|
|
2623
|
+
if F[0][1] == 1:
|
|
2624
|
+
return base
|
|
2625
|
+
elif names is None:
|
|
2626
|
+
raise TypeError("You must specify the name of the generator.")
|
|
2627
|
+
if res_name is None:
|
|
2628
|
+
res_name = names + '0'
|
|
2629
|
+
if modulus is None:
|
|
2630
|
+
from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
|
|
2631
|
+
if ram_name is None:
|
|
2632
|
+
ram_name = str(F[0][0])
|
|
2633
|
+
modulus = GF(q, res_name).modulus().change_ring(ZZ)
|
|
2634
|
+
return ExtensionFactory(base=base, modulus=modulus, prec=prec, print_mode=print_mode,
|
|
2635
|
+
names=names, res_name=res_name, ram_name=ram_name, print_pos=print_pos,
|
|
2636
|
+
print_sep=print_sep, print_max_ram_terms=print_max_ram_terms,
|
|
2637
|
+
print_max_unram_terms=print_max_unram_terms,
|
|
2638
|
+
print_max_terse_terms=print_max_terse_terms, show_prec=show_prec, check=check,
|
|
2639
|
+
unram=True, implementation=implementation)
|
|
2640
|
+
|
|
2641
|
+
######################################################
|
|
2642
|
+
# Short constructor names for different types
|
|
2643
|
+
######################################################
|
|
2644
|
+
|
|
2645
|
+
|
|
2646
|
+
def ZpCR(p, prec=None, *args, **kwds):
|
|
2647
|
+
r"""
|
|
2648
|
+
A shortcut function to create capped relative `p`-adic rings.
|
|
2649
|
+
|
|
2650
|
+
Same functionality as :func:`Zp`. See documentation for :func:`Zp` for a
|
|
2651
|
+
description of the input parameters.
|
|
2652
|
+
|
|
2653
|
+
EXAMPLES::
|
|
2654
|
+
|
|
2655
|
+
sage: ZpCR(5, 40)
|
|
2656
|
+
5-adic Ring with capped relative precision 40
|
|
2657
|
+
"""
|
|
2658
|
+
return Zp(p, prec, 'capped-rel', *args, **kwds)
|
|
2659
|
+
|
|
2660
|
+
|
|
2661
|
+
def ZpCA(p, prec=None, *args, **kwds):
|
|
2662
|
+
r"""
|
|
2663
|
+
A shortcut function to create capped absolute `p`-adic rings.
|
|
2664
|
+
|
|
2665
|
+
See documentation for :func:`Zp` for a description of the input parameters.
|
|
2666
|
+
|
|
2667
|
+
EXAMPLES::
|
|
2668
|
+
|
|
2669
|
+
sage: ZpCA(5, 40)
|
|
2670
|
+
5-adic Ring with capped absolute precision 40
|
|
2671
|
+
"""
|
|
2672
|
+
return Zp(p, prec, 'capped-abs', *args, **kwds)
|
|
2673
|
+
|
|
2674
|
+
|
|
2675
|
+
def ZpFM(p, prec=None, *args, **kwds):
|
|
2676
|
+
r"""
|
|
2677
|
+
A shortcut function to create fixed modulus `p`-adic rings.
|
|
2678
|
+
|
|
2679
|
+
See documentation for :func:`Zp` for a description of the input parameters.
|
|
2680
|
+
|
|
2681
|
+
EXAMPLES::
|
|
2682
|
+
|
|
2683
|
+
sage: ZpFM(5, 40)
|
|
2684
|
+
5-adic Ring of fixed modulus 5^40
|
|
2685
|
+
"""
|
|
2686
|
+
return Zp(p, prec, 'fixed-mod', *args, **kwds)
|
|
2687
|
+
|
|
2688
|
+
|
|
2689
|
+
def ZpFP(p, prec=None, *args, **kwds):
|
|
2690
|
+
r"""
|
|
2691
|
+
A shortcut function to create floating point `p`-adic rings.
|
|
2692
|
+
|
|
2693
|
+
Same functionality as :func:`Zp`. See documentation for :func:`Zp` for a
|
|
2694
|
+
description of the input parameters.
|
|
2695
|
+
|
|
2696
|
+
EXAMPLES::
|
|
2697
|
+
|
|
2698
|
+
sage: ZpFP(5, 40)
|
|
2699
|
+
5-adic Ring with floating precision 40
|
|
2700
|
+
"""
|
|
2701
|
+
return Zp(p, prec, 'floating-point', *args, **kwds)
|
|
2702
|
+
|
|
2703
|
+
|
|
2704
|
+
def ZqCR(q, prec=None, *args, **kwds):
|
|
2705
|
+
r"""
|
|
2706
|
+
A shortcut function to create capped relative unramified `p`-adic rings.
|
|
2707
|
+
|
|
2708
|
+
Same functionality as :func:`Zq`. See documentation for :func:`Zq` for a
|
|
2709
|
+
description of the input parameters.
|
|
2710
|
+
|
|
2711
|
+
EXAMPLES::
|
|
2712
|
+
|
|
2713
|
+
sage: R.<a> = ZqCR(25, 40); R # needs sage.libs.ntl
|
|
2714
|
+
5-adic Unramified Extension Ring in a defined by x^2 + 4*x + 2
|
|
2715
|
+
"""
|
|
2716
|
+
return Zq(q, prec, 'capped-rel', *args, **kwds)
|
|
2717
|
+
|
|
2718
|
+
|
|
2719
|
+
def ZqCA(q, prec=None, *args, **kwds):
|
|
2720
|
+
r"""
|
|
2721
|
+
A shortcut function to create capped absolute unramified `p`-adic rings.
|
|
2722
|
+
|
|
2723
|
+
See documentation for :func:`Zq` for a description of the input parameters.
|
|
2724
|
+
|
|
2725
|
+
EXAMPLES::
|
|
2726
|
+
|
|
2727
|
+
sage: R.<a> = ZqCA(25, 40); R # needs sage.libs.flint
|
|
2728
|
+
5-adic Unramified Extension Ring in a defined by x^2 + 4*x + 2
|
|
2729
|
+
"""
|
|
2730
|
+
return Zq(q, prec, 'capped-abs', *args, **kwds)
|
|
2731
|
+
|
|
2732
|
+
|
|
2733
|
+
def ZqFM(q, prec=None, *args, **kwds):
|
|
2734
|
+
r"""
|
|
2735
|
+
A shortcut function to create fixed modulus unramified `p`-adic rings.
|
|
2736
|
+
|
|
2737
|
+
See documentation for :func:`Zq` for a description of the input parameters.
|
|
2738
|
+
|
|
2739
|
+
EXAMPLES::
|
|
2740
|
+
|
|
2741
|
+
sage: R.<a> = ZqFM(25, 40); R # needs sage.libs.flint
|
|
2742
|
+
5-adic Unramified Extension Ring in a defined by x^2 + 4*x + 2
|
|
2743
|
+
"""
|
|
2744
|
+
return Zq(q, prec, 'fixed-mod', *args, **kwds)
|
|
2745
|
+
|
|
2746
|
+
|
|
2747
|
+
def ZqFP(q, prec=None, *args, **kwds):
|
|
2748
|
+
r"""
|
|
2749
|
+
A shortcut function to create floating point unramified `p`-adic rings.
|
|
2750
|
+
|
|
2751
|
+
Same functionality as :func:`Zq`. See documentation for :func:`Zq` for a
|
|
2752
|
+
description of the input parameters.
|
|
2753
|
+
|
|
2754
|
+
EXAMPLES::
|
|
2755
|
+
|
|
2756
|
+
sage: R.<a> = ZqFP(25, 40); R # needs sage.libs.flint
|
|
2757
|
+
5-adic Unramified Extension Ring in a defined by x^2 + 4*x + 2
|
|
2758
|
+
"""
|
|
2759
|
+
return Zq(q, prec, 'floating-point', *args, **kwds)
|
|
2760
|
+
|
|
2761
|
+
|
|
2762
|
+
@experimental(23505)
|
|
2763
|
+
def ZpLC(p, prec=None, *args, **kwds):
|
|
2764
|
+
r"""
|
|
2765
|
+
A shortcut function to create `p`-adic rings with lattice precision
|
|
2766
|
+
(precision is encoded by a lattice in a large vector space and tracked
|
|
2767
|
+
using automatic differentiation).
|
|
2768
|
+
|
|
2769
|
+
See documentation for :func:`Zp` for a description of the input parameters.
|
|
2770
|
+
|
|
2771
|
+
EXAMPLES:
|
|
2772
|
+
|
|
2773
|
+
Below is a small demo of the features by this model of precision::
|
|
2774
|
+
|
|
2775
|
+
sage: R = ZpLC(3, print_mode='terse')
|
|
2776
|
+
sage: R
|
|
2777
|
+
3-adic Ring with lattice-cap precision
|
|
2778
|
+
|
|
2779
|
+
sage: x = R(1,10)
|
|
2780
|
+
|
|
2781
|
+
Of course, when we multiply by 3, we gain one digit of absolute
|
|
2782
|
+
precision::
|
|
2783
|
+
|
|
2784
|
+
sage: 3*x
|
|
2785
|
+
3 + O(3^11)
|
|
2786
|
+
|
|
2787
|
+
The lattice precision machinery sees this even if we decompose
|
|
2788
|
+
the computation into several steps::
|
|
2789
|
+
|
|
2790
|
+
sage: y = x+x
|
|
2791
|
+
sage: y
|
|
2792
|
+
2 + O(3^10)
|
|
2793
|
+
sage: x + y
|
|
2794
|
+
3 + O(3^11)
|
|
2795
|
+
|
|
2796
|
+
The same works for the multiplication::
|
|
2797
|
+
|
|
2798
|
+
sage: z = x^2
|
|
2799
|
+
sage: z
|
|
2800
|
+
1 + O(3^10)
|
|
2801
|
+
sage: x*z
|
|
2802
|
+
1 + O(3^11)
|
|
2803
|
+
|
|
2804
|
+
This can be more surprising when we are working with elements given
|
|
2805
|
+
at different precisions::
|
|
2806
|
+
|
|
2807
|
+
sage: R = ZpLC(2, print_mode='terse')
|
|
2808
|
+
sage: x = R(1,10)
|
|
2809
|
+
sage: y = R(1,5)
|
|
2810
|
+
sage: z = x+y; z
|
|
2811
|
+
2 + O(2^5)
|
|
2812
|
+
sage: t = x-y; t
|
|
2813
|
+
O(2^5)
|
|
2814
|
+
sage: z+t # observe that z+t = 2*x
|
|
2815
|
+
2 + O(2^11)
|
|
2816
|
+
sage: z-t # observe that z-t = 2*y
|
|
2817
|
+
2 + O(2^6)
|
|
2818
|
+
|
|
2819
|
+
sage: x = R(28888,15)
|
|
2820
|
+
sage: y = R(204,10)
|
|
2821
|
+
sage: z = x/y; z
|
|
2822
|
+
242 + O(2^9)
|
|
2823
|
+
sage: z*y # which is x
|
|
2824
|
+
28888 + O(2^15)
|
|
2825
|
+
|
|
2826
|
+
The SOMOS sequence is the sequence defined by the recurrence:
|
|
2827
|
+
|
|
2828
|
+
.. MATH::
|
|
2829
|
+
|
|
2830
|
+
u_n = \frac {u_{n-1} u_{n-3} + u_{n-2}^2} {u_{n-4}}
|
|
2831
|
+
|
|
2832
|
+
It is known for its numerical instability.
|
|
2833
|
+
On the one hand, one can show that if the initial values are
|
|
2834
|
+
invertible in `\ZZ_p` and known at precision `O(p^N)`
|
|
2835
|
+
then all the next terms of the SOMOS sequence will be known
|
|
2836
|
+
at the same precision as well.
|
|
2837
|
+
On the other hand, because of the division, when we unroll
|
|
2838
|
+
the recurrence, we loose a lot of precision. Observe::
|
|
2839
|
+
|
|
2840
|
+
sage: R = Zp(2, 30, print_mode='terse')
|
|
2841
|
+
sage: a,b,c,d = R(1,15), R(1,15), R(1,15), R(3,15)
|
|
2842
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2843
|
+
4 + O(2^15)
|
|
2844
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2845
|
+
13 + O(2^15)
|
|
2846
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2847
|
+
55 + O(2^15)
|
|
2848
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2849
|
+
21975 + O(2^15)
|
|
2850
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2851
|
+
6639 + O(2^13)
|
|
2852
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2853
|
+
7186 + O(2^13)
|
|
2854
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2855
|
+
569 + O(2^13)
|
|
2856
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2857
|
+
253 + O(2^13)
|
|
2858
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2859
|
+
4149 + O(2^13)
|
|
2860
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2861
|
+
2899 + O(2^12)
|
|
2862
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2863
|
+
3072 + O(2^12)
|
|
2864
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2865
|
+
349 + O(2^12)
|
|
2866
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2867
|
+
619 + O(2^12)
|
|
2868
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2869
|
+
243 + O(2^12)
|
|
2870
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2871
|
+
3 + O(2^2)
|
|
2872
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2873
|
+
2 + O(2^2)
|
|
2874
|
+
|
|
2875
|
+
If instead, we use the lattice precision, everything goes well::
|
|
2876
|
+
|
|
2877
|
+
sage: R = ZpLC(2, 30, print_mode='terse')
|
|
2878
|
+
sage: a,b,c,d = R(1,15), R(1,15), R(1,15), R(3,15)
|
|
2879
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2880
|
+
4 + O(2^15)
|
|
2881
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2882
|
+
13 + O(2^15)
|
|
2883
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2884
|
+
55 + O(2^15)
|
|
2885
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2886
|
+
21975 + O(2^15)
|
|
2887
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2888
|
+
23023 + O(2^15)
|
|
2889
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2890
|
+
31762 + O(2^15)
|
|
2891
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2892
|
+
16953 + O(2^15)
|
|
2893
|
+
sage: a,b,c,d = b,c,d,(b*d+c*c)/a; print(d)
|
|
2894
|
+
16637 + O(2^15)
|
|
2895
|
+
|
|
2896
|
+
sage: for _ in range(100):
|
|
2897
|
+
....: a,b,c,d = b,c,d,(b*d+c*c)/a
|
|
2898
|
+
sage: a
|
|
2899
|
+
15519 + O(2^15)
|
|
2900
|
+
sage: b
|
|
2901
|
+
32042 + O(2^15)
|
|
2902
|
+
sage: c
|
|
2903
|
+
17769 + O(2^15)
|
|
2904
|
+
sage: d
|
|
2905
|
+
20949 + O(2^15)
|
|
2906
|
+
|
|
2907
|
+
ALGORITHM:
|
|
2908
|
+
|
|
2909
|
+
The precision is global.
|
|
2910
|
+
It is encoded by a lattice in a huge vector space whose dimension
|
|
2911
|
+
is the number of elements having this parent. Precision is tracked
|
|
2912
|
+
using automatic differentiation techniques (see [CRV2014]_ and
|
|
2913
|
+
[CRV2018]_).
|
|
2914
|
+
|
|
2915
|
+
Concretely, this precision datum is an instance of the class
|
|
2916
|
+
:class:`sage.rings.padic.lattice_precision.PrecisionLattice`.
|
|
2917
|
+
It is attached to the parent and is created at the same time
|
|
2918
|
+
as the parent.
|
|
2919
|
+
(It is actually a bit more subtle because two different parents
|
|
2920
|
+
may share the same instance; this happens for instance for a
|
|
2921
|
+
`p`-adic ring and its field of fractions.)
|
|
2922
|
+
|
|
2923
|
+
This precision datum is accessible through the method :meth:`precision`::
|
|
2924
|
+
|
|
2925
|
+
sage: R = ZpLC(5, print_mode='terse')
|
|
2926
|
+
sage: prec = R.precision()
|
|
2927
|
+
sage: prec
|
|
2928
|
+
Precision lattice on 0 objects
|
|
2929
|
+
|
|
2930
|
+
This instance knows about all elements of the parent. It is
|
|
2931
|
+
automatically updated when a new element (of this parent) is
|
|
2932
|
+
created::
|
|
2933
|
+
|
|
2934
|
+
sage: x = R(3513,10)
|
|
2935
|
+
sage: prec
|
|
2936
|
+
Precision lattice on 1 object
|
|
2937
|
+
sage: y = R(176,5)
|
|
2938
|
+
sage: prec
|
|
2939
|
+
Precision lattice on 2 objects
|
|
2940
|
+
sage: z = R.random_element()
|
|
2941
|
+
sage: prec
|
|
2942
|
+
Precision lattice on 3 objects
|
|
2943
|
+
|
|
2944
|
+
The method :meth:`tracked_elements` provides the list of all
|
|
2945
|
+
tracked elements::
|
|
2946
|
+
|
|
2947
|
+
sage: prec.tracked_elements()
|
|
2948
|
+
[3513 + O(5^10), 176 + O(5^5), ...]
|
|
2949
|
+
|
|
2950
|
+
Similarly, when a variable is collected by the garbage collector,
|
|
2951
|
+
the precision lattice is updated. Note however that the update
|
|
2952
|
+
might be delayed. We can force it with the method :meth:`del_elements`::
|
|
2953
|
+
|
|
2954
|
+
sage: z = 0
|
|
2955
|
+
sage: prec # random output, could be 2 objects if the garbage collector is fast
|
|
2956
|
+
Precision lattice on 3 objects
|
|
2957
|
+
sage: prec.del_elements()
|
|
2958
|
+
sage: prec
|
|
2959
|
+
Precision lattice on 2 objects
|
|
2960
|
+
|
|
2961
|
+
The method :meth:`precision_lattice` returns (a matrix defining)
|
|
2962
|
+
the lattice that models the precision. Here we have::
|
|
2963
|
+
|
|
2964
|
+
sage: prec.precision_lattice() # needs sage.geometry.polyhedron
|
|
2965
|
+
[9765625 0]
|
|
2966
|
+
[ 0 3125]
|
|
2967
|
+
|
|
2968
|
+
Observe that `5^10 = 9765625` and `5^5 = 3125`.
|
|
2969
|
+
The above matrix then reflects the precision on `x` and `y`.
|
|
2970
|
+
|
|
2971
|
+
Now, observe how the precision lattice changes while performing
|
|
2972
|
+
computations::
|
|
2973
|
+
|
|
2974
|
+
sage: x, y = 3*x+2*y, 2*(x-y)
|
|
2975
|
+
sage: prec.del_elements()
|
|
2976
|
+
sage: prec.precision_lattice() # needs sage.geometry.polyhedron
|
|
2977
|
+
[ 3125 48825000]
|
|
2978
|
+
[ 0 48828125]
|
|
2979
|
+
|
|
2980
|
+
The matrix we get is no longer diagonal, meaning that some digits
|
|
2981
|
+
of precision are diffused among the two new elements `x` and `y`.
|
|
2982
|
+
They nevertheless show up when we compute for instance `x+y`::
|
|
2983
|
+
|
|
2984
|
+
sage: x
|
|
2985
|
+
1516 + O(5^5)
|
|
2986
|
+
sage: y
|
|
2987
|
+
424 + O(5^5)
|
|
2988
|
+
sage: x+y
|
|
2989
|
+
17565 + O(5^11)
|
|
2990
|
+
|
|
2991
|
+
These diffused digits of precision (which are tracked but
|
|
2992
|
+
do not appear on the printing) allow to be always sharp on
|
|
2993
|
+
precision.
|
|
2994
|
+
|
|
2995
|
+
NOTE:
|
|
2996
|
+
|
|
2997
|
+
Each elementary operation requires significant manipulations
|
|
2998
|
+
on the precision lattice and therefore is costly. Precisely:
|
|
2999
|
+
|
|
3000
|
+
- The creation of a new element has a cost `O(n)` where `n`
|
|
3001
|
+
is the number of tracked elements.
|
|
3002
|
+
|
|
3003
|
+
- The destruction of one element has a cost `O(m^2)` where
|
|
3004
|
+
`m` is the distance between the destroyed element and
|
|
3005
|
+
the last one. Fortunately, it seems that `m` tends to
|
|
3006
|
+
be small in general (the dynamics of the list of tracked
|
|
3007
|
+
elements is rather close to that of a stack).
|
|
3008
|
+
|
|
3009
|
+
It is nevertheless still possible to manipulate several
|
|
3010
|
+
hundred variables (e.g. square matrices of size 5 or
|
|
3011
|
+
polynomials of degree 20).
|
|
3012
|
+
|
|
3013
|
+
The class :class:`PrecisionLattice` provides several
|
|
3014
|
+
features for introspection, especially concerning timings.
|
|
3015
|
+
See :meth:`history` and :meth:`timings` for details.
|
|
3016
|
+
|
|
3017
|
+
.. SEEALSO::
|
|
3018
|
+
|
|
3019
|
+
:func:`ZpLF`
|
|
3020
|
+
"""
|
|
3021
|
+
return Zp(p, prec, 'lattice-cap', *args, **kwds)
|
|
3022
|
+
|
|
3023
|
+
|
|
3024
|
+
@experimental(23505)
|
|
3025
|
+
def ZpLF(p, prec=None, *args, **kwds):
|
|
3026
|
+
r"""
|
|
3027
|
+
A shortcut function to create `p`-adic rings where precision
|
|
3028
|
+
is encoded by a module in a large vector space.
|
|
3029
|
+
|
|
3030
|
+
See documentation for :func:`Zp` for a description of the input parameters.
|
|
3031
|
+
|
|
3032
|
+
.. NOTE::
|
|
3033
|
+
|
|
3034
|
+
The precision is tracked using automatic differentiation
|
|
3035
|
+
techniques (see [CRV2018]_ and [CRV2014]_).
|
|
3036
|
+
Floating point `p`-adic numbers are used for the computation
|
|
3037
|
+
of the differential (which is then not exact).
|
|
3038
|
+
|
|
3039
|
+
EXAMPLES::
|
|
3040
|
+
|
|
3041
|
+
sage: R = ZpLF(5, 40)
|
|
3042
|
+
sage: R
|
|
3043
|
+
5-adic Ring with lattice-float precision
|
|
3044
|
+
|
|
3045
|
+
.. SEEALSO::
|
|
3046
|
+
|
|
3047
|
+
:func:`ZpLC`
|
|
3048
|
+
"""
|
|
3049
|
+
return Zp(p, prec, 'lattice-float', *args, **kwds)
|
|
3050
|
+
|
|
3051
|
+
|
|
3052
|
+
def ZpER(p, prec=None, halt=None, secure=False, *args, **kwds):
|
|
3053
|
+
r"""
|
|
3054
|
+
A shortcut function to create relaxed `p`-adic rings.
|
|
3055
|
+
|
|
3056
|
+
INPUT:
|
|
3057
|
+
|
|
3058
|
+
- ``prec`` -- integer (default: 20); the default precision
|
|
3059
|
+
|
|
3060
|
+
- ``halt`` -- integer (default: twice ``prec``); the halting precision
|
|
3061
|
+
|
|
3062
|
+
- ``secure`` -- boolean (default: ``False``); if ``False``,
|
|
3063
|
+
consider indistinguishable elements at the working precision
|
|
3064
|
+
as equal. Otherwise, raise an error.
|
|
3065
|
+
|
|
3066
|
+
See documentation for :func:`Zp` for a description of the other
|
|
3067
|
+
input parameters.
|
|
3068
|
+
|
|
3069
|
+
A SHORT INTRODUCTION TO RELAXED `p`-ADICS:
|
|
3070
|
+
|
|
3071
|
+
The model for relaxed `p`-adics is quite different from any of the
|
|
3072
|
+
other types of `p`-adics. In addition to storing a finite
|
|
3073
|
+
approximation, one also stores a method for increasing the
|
|
3074
|
+
precision.
|
|
3075
|
+
|
|
3076
|
+
Relaxed `p`-adic rings are created by the constructor :func:`ZpER`::
|
|
3077
|
+
|
|
3078
|
+
sage: R = ZpER(5, print_mode='digits'); R # needs sage.libs.flint
|
|
3079
|
+
5-adic Ring handled with relaxed arithmetics
|
|
3080
|
+
|
|
3081
|
+
The precision is not capped in `R`::
|
|
3082
|
+
|
|
3083
|
+
sage: R.precision_cap() # needs sage.libs.flint
|
|
3084
|
+
+Infinity
|
|
3085
|
+
|
|
3086
|
+
However, a default precision is fixed. This is the precision
|
|
3087
|
+
at which the elements will be printed::
|
|
3088
|
+
|
|
3089
|
+
sage: R.default_prec() # needs sage.libs.flint
|
|
3090
|
+
20
|
|
3091
|
+
|
|
3092
|
+
A default halting precision is also set. It is the default absolute
|
|
3093
|
+
precision at which the elements will be compared. By default, it is
|
|
3094
|
+
twice the default precision::
|
|
3095
|
+
|
|
3096
|
+
sage: R.halting_prec() # needs sage.libs.flint
|
|
3097
|
+
40
|
|
3098
|
+
|
|
3099
|
+
However, both the default precision and the halting precision can be
|
|
3100
|
+
customized at the creation of the parent as follows::
|
|
3101
|
+
|
|
3102
|
+
sage: S = ZpER(5, prec=10, halt=100) # needs sage.libs.flint
|
|
3103
|
+
sage: S.default_prec() # needs sage.libs.flint
|
|
3104
|
+
10
|
|
3105
|
+
sage: S.halting_prec() # needs sage.libs.flint
|
|
3106
|
+
100
|
|
3107
|
+
|
|
3108
|
+
One creates elements as usual::
|
|
3109
|
+
|
|
3110
|
+
sage: a = R(17/42); a # needs sage.libs.flint
|
|
3111
|
+
...00244200244200244201
|
|
3112
|
+
|
|
3113
|
+
sage: R.random_element() # random # needs sage.libs.flint
|
|
3114
|
+
...21013213133412431402
|
|
3115
|
+
|
|
3116
|
+
Here we notice that 20 digits (that is the default precision) are printed.
|
|
3117
|
+
However, the computation model is designed in order to guarantee that more
|
|
3118
|
+
digits of `a` will be available on demand.
|
|
3119
|
+
This feature is reflected by the fact that, when we ask for the precision
|
|
3120
|
+
of `a`, the software answers `+\infty`::
|
|
3121
|
+
|
|
3122
|
+
sage: a.precision_absolute() # needs sage.libs.flint
|
|
3123
|
+
+Infinity
|
|
3124
|
+
|
|
3125
|
+
Asking for more digits is achieved by the methods :meth:`at_precision_absolute`
|
|
3126
|
+
and :meth:`at_precision_relative`::
|
|
3127
|
+
|
|
3128
|
+
sage: a.at_precision_absolute(30) # needs sage.libs.flint
|
|
3129
|
+
...?244200244200244200244200244201
|
|
3130
|
+
|
|
3131
|
+
As a shortcut, one can use the bracket operator::
|
|
3132
|
+
|
|
3133
|
+
sage: a[:30] # needs sage.libs.flint
|
|
3134
|
+
...?244200244200244200244200244201
|
|
3135
|
+
|
|
3136
|
+
Of course, standard operations are supported::
|
|
3137
|
+
|
|
3138
|
+
sage: # needs sage.libs.flint
|
|
3139
|
+
sage: b = R(42/17)
|
|
3140
|
+
sage: a + b
|
|
3141
|
+
...03232011214322140002
|
|
3142
|
+
sage: a - b
|
|
3143
|
+
...42311334324023403400
|
|
3144
|
+
sage: a * b
|
|
3145
|
+
...00000000000000000001
|
|
3146
|
+
sage: a / b
|
|
3147
|
+
...12442142113021233401
|
|
3148
|
+
sage: sqrt(a)
|
|
3149
|
+
...20042333114021142101
|
|
3150
|
+
|
|
3151
|
+
We observe again that only 20 digits are printed but, as before,
|
|
3152
|
+
more digits are available on demand::
|
|
3153
|
+
|
|
3154
|
+
sage: sqrt(a)[:30] # needs sage.libs.flint
|
|
3155
|
+
...?142443342120042333114021142101
|
|
3156
|
+
|
|
3157
|
+
.. RUBRIC:: Equality tests
|
|
3158
|
+
|
|
3159
|
+
Checking equalities between relaxed `p`-adics is a bit subtle and can
|
|
3160
|
+
sometimes be puzzling at first glance.
|
|
3161
|
+
|
|
3162
|
+
When the parent is created with ``secure=False`` (which is the
|
|
3163
|
+
default), elements are compared at the current precision, or at the
|
|
3164
|
+
default halting precision if it is higher::
|
|
3165
|
+
|
|
3166
|
+
sage: a == b # needs sage.libs.flint
|
|
3167
|
+
False
|
|
3168
|
+
|
|
3169
|
+
sage: a == sqrt(a)^2 # needs sage.libs.flint
|
|
3170
|
+
True
|
|
3171
|
+
sage: a == sqrt(a)^2 + 5^50 # needs sage.libs.flint
|
|
3172
|
+
True
|
|
3173
|
+
|
|
3174
|
+
In the above example, the halting precision is `40`; it is the
|
|
3175
|
+
reason why a congruence modulo `5^50` is considered as an equality.
|
|
3176
|
+
However, if both sides of the equalities have been previously
|
|
3177
|
+
computed with more digits, those digits are taken into account.
|
|
3178
|
+
Hence comparing two elements at different times can produce
|
|
3179
|
+
different results::
|
|
3180
|
+
|
|
3181
|
+
sage: # needs sage.libs.flint
|
|
3182
|
+
sage: aa = sqrt(a)^2 + 5^50
|
|
3183
|
+
sage: a == aa
|
|
3184
|
+
True
|
|
3185
|
+
sage: a[:60]
|
|
3186
|
+
...?244200244200244200244200244200244200244200244200244200244201
|
|
3187
|
+
sage: aa[:60]
|
|
3188
|
+
...?244200244300244200244200244200244200244200244200244200244201
|
|
3189
|
+
sage: a == aa
|
|
3190
|
+
False
|
|
3191
|
+
|
|
3192
|
+
This annoying situation, where the output of ``a == aa`` may change
|
|
3193
|
+
depending on previous computations, cannot occur when the parent is
|
|
3194
|
+
created with ``secure=True``.
|
|
3195
|
+
Indeed, in this case, if the equality cannot be decided, an error
|
|
3196
|
+
is raised::
|
|
3197
|
+
|
|
3198
|
+
sage: # needs sage.libs.flint
|
|
3199
|
+
sage: S = ZpER(5, secure=True)
|
|
3200
|
+
sage: u = S.random_element()
|
|
3201
|
+
sage: uu = u + 5^50
|
|
3202
|
+
sage: u == uu
|
|
3203
|
+
Traceback (most recent call last):
|
|
3204
|
+
...
|
|
3205
|
+
PrecisionError: unable to decide equality; try to bound precision
|
|
3206
|
+
|
|
3207
|
+
sage: u[:60] == uu # needs sage.libs.flint
|
|
3208
|
+
False
|
|
3209
|
+
|
|
3210
|
+
.. RUBRIC:: Self-referent numbers
|
|
3211
|
+
|
|
3212
|
+
A quite interesting feature with relaxed `p`-adics is the possibility to
|
|
3213
|
+
create (in some cases) self-referent numbers. Here is an example.
|
|
3214
|
+
We first declare a new variable as follows::
|
|
3215
|
+
|
|
3216
|
+
sage: x = R.unknown(); x # needs sage.libs.flint
|
|
3217
|
+
...?.0
|
|
3218
|
+
|
|
3219
|
+
We then use the method :meth:`set` to define `x` by writing down an equation
|
|
3220
|
+
it satisfies::
|
|
3221
|
+
|
|
3222
|
+
sage: x.set(1 + 5*x^2) # needs sage.libs.flint
|
|
3223
|
+
True
|
|
3224
|
+
|
|
3225
|
+
The variable `x` now contains the unique solution of the equation
|
|
3226
|
+
`x = 1 + 5 x^2`::
|
|
3227
|
+
|
|
3228
|
+
sage: x # needs sage.libs.flint
|
|
3229
|
+
...04222412141121000211
|
|
3230
|
+
|
|
3231
|
+
This works because the `n`-th digit of the right hand size of the
|
|
3232
|
+
defining equation only involves the `i`-th digits of `x` with `i < n`
|
|
3233
|
+
(this is due to the factor `5`).
|
|
3234
|
+
|
|
3235
|
+
As a comparison, the following does not work::
|
|
3236
|
+
|
|
3237
|
+
sage: # needs sage.libs.flint
|
|
3238
|
+
sage: y = R.unknown()
|
|
3239
|
+
sage: y.set(1 + 3*y^2)
|
|
3240
|
+
True
|
|
3241
|
+
sage: y
|
|
3242
|
+
...?.0
|
|
3243
|
+
sage: y[:20]
|
|
3244
|
+
Traceback (most recent call last):
|
|
3245
|
+
...
|
|
3246
|
+
RecursionError: definition looks circular
|
|
3247
|
+
|
|
3248
|
+
Self-referent definitions also work with systems of equations::
|
|
3249
|
+
|
|
3250
|
+
sage: # needs sage.libs.flint
|
|
3251
|
+
sage: u = R.unknown()
|
|
3252
|
+
sage: v = R.unknown()
|
|
3253
|
+
sage: w = R.unknown()
|
|
3254
|
+
sage: u.set(1 + 2*v + 3*w^2 + 5*u*v*w)
|
|
3255
|
+
True
|
|
3256
|
+
sage: v.set(2 + 4*w + sqrt(1 + 5*u + 10*v + 15*w))
|
|
3257
|
+
True
|
|
3258
|
+
sage: w.set(3 + 25*(u*v + v*w + u*w))
|
|
3259
|
+
True
|
|
3260
|
+
sage: u
|
|
3261
|
+
...31203130103131131433
|
|
3262
|
+
sage: v
|
|
3263
|
+
...33441043031103114240
|
|
3264
|
+
sage: w
|
|
3265
|
+
...30212422041102444403
|
|
3266
|
+
"""
|
|
3267
|
+
return Zp(p, (prec, halt, secure), 'relaxed', *args, **kwds)
|
|
3268
|
+
|
|
3269
|
+
|
|
3270
|
+
#######################################################################################################
|
|
3271
|
+
#
|
|
3272
|
+
# The Extension Factory -- creates extensions of p-adic rings and fields
|
|
3273
|
+
#
|
|
3274
|
+
#######################################################################################################
|
|
3275
|
+
|
|
3276
|
+
class pAdicExtension_class(UniqueFactory):
|
|
3277
|
+
r"""
|
|
3278
|
+
A class for creating extensions of `p`-adic rings and fields.
|
|
3279
|
+
|
|
3280
|
+
EXAMPLES::
|
|
3281
|
+
|
|
3282
|
+
sage: R = Zp(5,3)
|
|
3283
|
+
sage: S.<x> = ZZ[]
|
|
3284
|
+
sage: W.<w> = pAdicExtension(R, x^4 - 15); W # needs sage.libs.ntl
|
|
3285
|
+
5-adic Eisenstein Extension Ring in w defined by x^4 - 15
|
|
3286
|
+
sage: W.precision_cap() # needs sage.libs.ntl
|
|
3287
|
+
12
|
|
3288
|
+
"""
|
|
3289
|
+
def create_key_and_extra_args(self, base, modulus, prec=None, print_mode=None,
|
|
3290
|
+
names=None, var_name=None, res_name=None,
|
|
3291
|
+
unram_name=None, ram_name=None, print_pos=None,
|
|
3292
|
+
print_sep=None, print_alphabet=None, print_max_ram_terms=None,
|
|
3293
|
+
print_max_unram_terms=None, print_max_terse_terms=None,
|
|
3294
|
+
show_prec=None, check=True, unram=False, implementation='FLINT'):
|
|
3295
|
+
r"""
|
|
3296
|
+
Create a key from input parameters for :class:`pAdicExtension`.
|
|
3297
|
+
|
|
3298
|
+
See the documentation for :func:`Qq` for more information.
|
|
3299
|
+
|
|
3300
|
+
TESTS::
|
|
3301
|
+
|
|
3302
|
+
sage: R = Zp(5,3)
|
|
3303
|
+
sage: S.<x> = ZZ[]
|
|
3304
|
+
sage: pAdicExtension.create_key_and_extra_args(R, x^4-15,names='w') # needs sage.libs.ntl
|
|
3305
|
+
(('e',
|
|
3306
|
+
5-adic Ring with capped relative precision 3,
|
|
3307
|
+
x^4 - 15,
|
|
3308
|
+
('w', None, None, 'w'),
|
|
3309
|
+
12,
|
|
3310
|
+
'series',
|
|
3311
|
+
True,
|
|
3312
|
+
'|',
|
|
3313
|
+
(),
|
|
3314
|
+
-1,
|
|
3315
|
+
-1,
|
|
3316
|
+
-1,
|
|
3317
|
+
'bigoh',
|
|
3318
|
+
'NTL'),
|
|
3319
|
+
{'approx_modulus': (1 + O(5^3))*x^4 + O(5^4)*x^3 + O(5^4)*x^2 + O(5^4)*x + 2*5 + 4*5^2 + 4*5^3 + O(5^4)})
|
|
3320
|
+
|
|
3321
|
+
sage: # needs sage.libs.ntl
|
|
3322
|
+
sage: A = Qp(3,5)
|
|
3323
|
+
sage: Po.<X> = A[]
|
|
3324
|
+
sage: f = Po([3,0,-1])
|
|
3325
|
+
sage: K.<a> = A.ext(f)
|
|
3326
|
+
sage: -a^2+3
|
|
3327
|
+
O(a^12)
|
|
3328
|
+
sage: K.defining_polynomial() == f/f.leading_coefficient()
|
|
3329
|
+
True
|
|
3330
|
+
|
|
3331
|
+
sage: # needs sage.libs.ntl
|
|
3332
|
+
sage: g = Po([6,3,2])
|
|
3333
|
+
sage: H.<b> = A.ext(g)
|
|
3334
|
+
sage: 2*b^2+3*b+6
|
|
3335
|
+
O(b^12)
|
|
3336
|
+
sage: H.defining_polynomial() == g/g.leading_coefficient()
|
|
3337
|
+
True
|
|
3338
|
+
"""
|
|
3339
|
+
if print_mode is None:
|
|
3340
|
+
print_mode = base.print_mode()
|
|
3341
|
+
if print_pos is None:
|
|
3342
|
+
print_pos = base._printer._pos()
|
|
3343
|
+
if print_sep is None:
|
|
3344
|
+
print_sep = base._printer._sep()
|
|
3345
|
+
if print_alphabet is None:
|
|
3346
|
+
print_alphabet = base._printer._alphabet()
|
|
3347
|
+
if print_max_ram_terms is None:
|
|
3348
|
+
print_max_ram_terms = base._printer._max_ram_terms()
|
|
3349
|
+
if print_max_unram_terms is None:
|
|
3350
|
+
print_max_unram_terms = base._printer._max_unram_terms()
|
|
3351
|
+
if print_max_terse_terms is None:
|
|
3352
|
+
print_max_terse_terms = base._printer._max_terse_terms()
|
|
3353
|
+
show_prec = _canonicalize_show_prec(base._prec_type(), print_mode, show_prec)
|
|
3354
|
+
from sage.structure.element import Expression
|
|
3355
|
+
if check:
|
|
3356
|
+
if isinstance(modulus, Expression):
|
|
3357
|
+
if len(modulus.variables()) != 1:
|
|
3358
|
+
raise ValueError("symbolic expression must be in only one variable")
|
|
3359
|
+
exact_modulus = modulus.polynomial(base.exact_field())
|
|
3360
|
+
approx_modulus = modulus.polynomial(base)
|
|
3361
|
+
elif isinstance(modulus, Polynomial):
|
|
3362
|
+
if modulus.parent().ngens() != 1:
|
|
3363
|
+
raise ValueError("must use univariate polynomial")
|
|
3364
|
+
exact_modulus = modulus.change_ring(base.exact_field())
|
|
3365
|
+
approx_modulus = modulus.change_ring(base)
|
|
3366
|
+
else:
|
|
3367
|
+
raise ValueError("modulus must be a polynomial")
|
|
3368
|
+
if exact_modulus.degree() <= 1:
|
|
3369
|
+
raise NotImplementedError("degree of modulus must be at least 2")
|
|
3370
|
+
# need to add more checking here.
|
|
3371
|
+
if not unram and not exact_modulus.is_monic():
|
|
3372
|
+
exact_modulus = exact_modulus / exact_modulus.leading_coefficient()
|
|
3373
|
+
approx_modulus = approx_modulus / approx_modulus.leading_coefficient()
|
|
3374
|
+
if names is None:
|
|
3375
|
+
if var_name is not None:
|
|
3376
|
+
names = var_name
|
|
3377
|
+
else:
|
|
3378
|
+
raise ValueError("must specify name of generator of extension")
|
|
3379
|
+
if isinstance(names, tuple):
|
|
3380
|
+
names = names[0]
|
|
3381
|
+
if not isinstance(names, str):
|
|
3382
|
+
names = str(names)
|
|
3383
|
+
else:
|
|
3384
|
+
exact_modulus = modulus
|
|
3385
|
+
approx_modulus = modulus.change_ring(base)
|
|
3386
|
+
|
|
3387
|
+
# We now decide on the extension class: unramified, Eisenstein, two-step or general
|
|
3388
|
+
if unram or is_unramified(approx_modulus):
|
|
3389
|
+
if unram_name is None:
|
|
3390
|
+
unram_name = names
|
|
3391
|
+
if res_name is None:
|
|
3392
|
+
res_name = unram_name + '0'
|
|
3393
|
+
if ram_name is None:
|
|
3394
|
+
ram_name = base._printer._uniformizer_name()
|
|
3395
|
+
names = (names, res_name, unram_name, ram_name)
|
|
3396
|
+
if base.absolute_degree() == 1:
|
|
3397
|
+
polytype = 'u'
|
|
3398
|
+
else:
|
|
3399
|
+
polytype = 'ru'
|
|
3400
|
+
if prec is None:
|
|
3401
|
+
prec = min([c.precision_absolute() for c in approx_modulus.list()] + [base.precision_cap()])
|
|
3402
|
+
elif prec > base.precision_cap():
|
|
3403
|
+
raise ValueError("Precision cannot be larger than that of base ring; you may want to call the change method on the base ring.")
|
|
3404
|
+
approx_modulus = truncate_to_prec(exact_modulus, base, prec)
|
|
3405
|
+
|
|
3406
|
+
elif is_eisenstein(approx_modulus):
|
|
3407
|
+
unram_name = None
|
|
3408
|
+
res_name = None
|
|
3409
|
+
if ram_name is None:
|
|
3410
|
+
ram_name = names
|
|
3411
|
+
if base.absolute_degree() == 1:
|
|
3412
|
+
unram_name = None
|
|
3413
|
+
polytype = 'e'
|
|
3414
|
+
else:
|
|
3415
|
+
unram_name = base.variable_name()
|
|
3416
|
+
polytype = 're'
|
|
3417
|
+
implementation = 'Polynomial'
|
|
3418
|
+
names = (names, res_name, unram_name, ram_name)
|
|
3419
|
+
e = approx_modulus.degree()
|
|
3420
|
+
if prec is None:
|
|
3421
|
+
prec = min([c.precision_absolute() for c in approx_modulus.list() if not c._is_exact_zero()] + [base.precision_cap()]) * e
|
|
3422
|
+
elif prec > base.precision_cap() * e:
|
|
3423
|
+
raise ValueError("Precision cannot be larger than that of base ring; you may want to call the change method on the base ring.")
|
|
3424
|
+
approx_modulus = truncate_to_prec(exact_modulus, base, (prec/e).ceil() + 1)
|
|
3425
|
+
else:
|
|
3426
|
+
if unram_name is None:
|
|
3427
|
+
unram_name = names + '_u'
|
|
3428
|
+
if res_name is None:
|
|
3429
|
+
res_name = names + '0'
|
|
3430
|
+
if ram_name is None:
|
|
3431
|
+
ram_name = names + '_p'
|
|
3432
|
+
names = (names, res_name, unram_name, ram_name)
|
|
3433
|
+
polytype = 'p'
|
|
3434
|
+
if polytype == 'e':
|
|
3435
|
+
implementation = "NTL" # for testing - FLINT ramified extensions not implemented yet
|
|
3436
|
+
key = (polytype, base, exact_modulus, names, prec, print_mode, print_pos,
|
|
3437
|
+
print_sep, tuple(print_alphabet), print_max_ram_terms, print_max_unram_terms,
|
|
3438
|
+
print_max_terse_terms, show_prec, implementation)
|
|
3439
|
+
return key, {'approx_modulus': approx_modulus}
|
|
3440
|
+
|
|
3441
|
+
def create_object(self, version, key, approx_modulus=None, shift_seed=None):
|
|
3442
|
+
r"""
|
|
3443
|
+
Create an object using a given key.
|
|
3444
|
+
|
|
3445
|
+
See the documentation for :class:`pAdicExtension` for more information.
|
|
3446
|
+
|
|
3447
|
+
TESTS::
|
|
3448
|
+
|
|
3449
|
+
sage: R = Zp(5,3)
|
|
3450
|
+
sage: S.<x> = R[] # needs sage.libs.ntl
|
|
3451
|
+
sage: pAdicExtension.create_object(version = (6,4,2), key = ('e', R, x^4 - 15, x^4 - 15, ('w', None, None, 'w'), 12, None, 'series', True, '|', (),-1,-1,-1,'NTL'), shift_seed = S(3 + O(5^3))) # needs sage.libs.ntl
|
|
3452
|
+
5-adic Eisenstein Extension Ring in w defined by x^4 - 15
|
|
3453
|
+
"""
|
|
3454
|
+
polytype = key[0]
|
|
3455
|
+
if version[0] < 6 or version[0] == 6 and version[1] < 1:
|
|
3456
|
+
key = list(key)
|
|
3457
|
+
key.append('NTL')
|
|
3458
|
+
if version[0] < 8:
|
|
3459
|
+
(polytype, base, premodulus, approx_modulus, names, prec, halt, print_mode, print_pos, print_sep,
|
|
3460
|
+
print_alphabet, print_max_ram_terms, print_max_unram_terms, print_max_terse_terms, implementation) = key
|
|
3461
|
+
from sage.structure.element import Expression
|
|
3462
|
+
if isinstance(premodulus, Expression):
|
|
3463
|
+
exact_modulus = premodulus.polynomial(base.exact_field())
|
|
3464
|
+
elif isinstance(premodulus, Polynomial):
|
|
3465
|
+
exact_modulus = premodulus.change_ring(base.exact_field())
|
|
3466
|
+
show_prec = None
|
|
3467
|
+
else:
|
|
3468
|
+
(polytype, base, exact_modulus, names, prec, print_mode, print_pos,
|
|
3469
|
+
print_sep, print_alphabet, print_max_ram_terms, print_max_unram_terms,
|
|
3470
|
+
print_max_terse_terms, show_prec, implementation) = key
|
|
3471
|
+
if polytype in ('e', 're'):
|
|
3472
|
+
unif = exact_modulus.base_ring()(base.uniformizer())
|
|
3473
|
+
shift_seed = (-exact_modulus[:exact_modulus.degree()] / unif).change_ring(base)
|
|
3474
|
+
if not krasner_check(exact_modulus, prec):
|
|
3475
|
+
raise ValueError("polynomial does not determine a unique extension. Please specify more precision or use parameter check=False.")
|
|
3476
|
+
|
|
3477
|
+
if show_prec is None:
|
|
3478
|
+
show_prec = base._printer._show_prec()
|
|
3479
|
+
if polytype == 'p':
|
|
3480
|
+
raise NotImplementedError("Extensions by general polynomials not yet supported. Please use an unramified or Eisenstein polynomial.")
|
|
3481
|
+
T = ext_table[polytype, type(base.ground_ring_of_tower()).__base__]
|
|
3482
|
+
return T(exact_modulus, approx_modulus, prec,
|
|
3483
|
+
{'mode': print_mode, 'pos': print_pos, 'sep': print_sep, 'alphabet': print_alphabet,
|
|
3484
|
+
'max_ram_terms': print_max_ram_terms, 'max_unram_terms': print_max_unram_terms, 'max_terse_terms': print_max_terse_terms, 'show_prec': show_prec},
|
|
3485
|
+
shift_seed, names, implementation)
|
|
3486
|
+
|
|
3487
|
+
|
|
3488
|
+
ExtensionFactory = pAdicExtension = pAdicExtension_class("pAdicExtension")
|
|
3489
|
+
|
|
3490
|
+
|
|
3491
|
+
######################################################
|
|
3492
|
+
# Helper functions for the Extension Factory
|
|
3493
|
+
######################################################
|
|
3494
|
+
|
|
3495
|
+
def split(poly, prec):
|
|
3496
|
+
r"""
|
|
3497
|
+
Given a polynomial ``poly`` and a desired precision ``prec``, computes
|
|
3498
|
+
``upoly`` and epoly so that the extension defined by ``poly`` is isomorphic
|
|
3499
|
+
to the extension defined by first taking an extension by the unramified
|
|
3500
|
+
polynomial ``upoly``, and then an extension by the Eisenstein polynomial
|
|
3501
|
+
``epoly``.
|
|
3502
|
+
|
|
3503
|
+
We need better `p`-adic factoring in Sage before this function can be
|
|
3504
|
+
implemented.
|
|
3505
|
+
|
|
3506
|
+
EXAMPLES::
|
|
3507
|
+
|
|
3508
|
+
sage: k = Qp(13)
|
|
3509
|
+
sage: x = polygen(k) # needs sage.libs.ntl
|
|
3510
|
+
sage: f = x^2 + 1 # needs sage.libs.ntl
|
|
3511
|
+
sage: sage.rings.padics.factory.split(f, 10) # needs sage.libs.ntl sage.rings.real_double
|
|
3512
|
+
Traceback (most recent call last):
|
|
3513
|
+
...
|
|
3514
|
+
NotImplementedError: Extensions by general polynomials not yet supported.
|
|
3515
|
+
Please use an unramified or Eisenstein polynomial.
|
|
3516
|
+
|
|
3517
|
+
TESTS:
|
|
3518
|
+
|
|
3519
|
+
This checks that :issue:`6186` is still fixed::
|
|
3520
|
+
|
|
3521
|
+
sage: k = Qp(13)
|
|
3522
|
+
sage: x = polygen(k) # needs sage.libs.ntl
|
|
3523
|
+
sage: f = x^2+1 # needs sage.libs.ntl
|
|
3524
|
+
sage: L.<a> = k.extension(f) # needs sage.libs.ntl
|
|
3525
|
+
Traceback (most recent call last):
|
|
3526
|
+
...
|
|
3527
|
+
NotImplementedError: Extensions by general polynomials not yet supported. Please use an unramified or Eisenstein polynomial.
|
|
3528
|
+
"""
|
|
3529
|
+
raise NotImplementedError("Extensions by general polynomials not yet supported. Please use an unramified or Eisenstein polynomial.")
|
|
3530
|
+
|
|
3531
|
+
|
|
3532
|
+
def truncate_to_prec(poly, R, absprec):
|
|
3533
|
+
r"""
|
|
3534
|
+
Truncates the unused precision off of a polynomial.
|
|
3535
|
+
|
|
3536
|
+
EXAMPLES::
|
|
3537
|
+
|
|
3538
|
+
sage: R = Zp(5)
|
|
3539
|
+
sage: S.<x> = R[] # needs sage.libs.ntl
|
|
3540
|
+
sage: from sage.rings.padics.factory import truncate_to_prec
|
|
3541
|
+
sage: f = x^4 + (3+O(5^6))*x^3 + O(5^4) # needs sage.libs.ntl
|
|
3542
|
+
sage: truncate_to_prec(f, R, 5) # needs sage.libs.ntl
|
|
3543
|
+
(1 + O(5^5))*x^4 + (3 + O(5^5))*x^3 + O(5^5)*x^2 + O(5^5)*x + O(5^4)
|
|
3544
|
+
"""
|
|
3545
|
+
return R[poly.variable_name()]([R(a, absprec=absprec) for a in poly.list()]) # Is this quite right? We don't want flat necessarily...
|
|
3546
|
+
|
|
3547
|
+
|
|
3548
|
+
def krasner_check(poly, prec):
|
|
3549
|
+
r"""
|
|
3550
|
+
Return ``True`` iff ``poly`` determines a unique isomorphism class of
|
|
3551
|
+
extensions at precision ``prec``.
|
|
3552
|
+
|
|
3553
|
+
Currently just returns ``True`` (thus allowing extensions that are not
|
|
3554
|
+
defined to high enough precision in order to specify them up to
|
|
3555
|
+
isomorphism). This will change in the future.
|
|
3556
|
+
|
|
3557
|
+
EXAMPLES::
|
|
3558
|
+
|
|
3559
|
+
sage: from sage.rings.padics.factory import krasner_check
|
|
3560
|
+
sage: krasner_check(1,2) # this is a stupid example.
|
|
3561
|
+
True
|
|
3562
|
+
"""
|
|
3563
|
+
return True # This needs to be implemented
|
|
3564
|
+
|
|
3565
|
+
|
|
3566
|
+
def is_eisenstein(poly):
|
|
3567
|
+
r"""
|
|
3568
|
+
Return ``True`` iff this monic polynomial is Eisenstein.
|
|
3569
|
+
|
|
3570
|
+
A polynomial is Eisenstein if it is monic, the constant term has
|
|
3571
|
+
valuation 1 and all other terms have positive valuation.
|
|
3572
|
+
|
|
3573
|
+
EXAMPLES::
|
|
3574
|
+
|
|
3575
|
+
sage: # needs sage.libs.ntl
|
|
3576
|
+
sage: R = Zp(5)
|
|
3577
|
+
sage: S.<x> = R[]
|
|
3578
|
+
sage: from sage.rings.padics.factory import is_eisenstein
|
|
3579
|
+
sage: f = x^4 - 75*x + 15
|
|
3580
|
+
sage: is_eisenstein(f)
|
|
3581
|
+
True
|
|
3582
|
+
sage: g = x^4 + 75
|
|
3583
|
+
sage: is_eisenstein(g)
|
|
3584
|
+
False
|
|
3585
|
+
sage: h = x^7 + 27*x -15
|
|
3586
|
+
sage: is_eisenstein(h)
|
|
3587
|
+
False
|
|
3588
|
+
"""
|
|
3589
|
+
if poly[0].valuation() != 1:
|
|
3590
|
+
return False
|
|
3591
|
+
if reduce(lambda a, b: a or b, [(c.valuation() < 1) for c in poly.list()[1:poly.degree()]]):
|
|
3592
|
+
return False
|
|
3593
|
+
return True
|
|
3594
|
+
|
|
3595
|
+
|
|
3596
|
+
def is_unramified(poly):
|
|
3597
|
+
r"""
|
|
3598
|
+
Return ``True`` iff this monic polynomial is unramified.
|
|
3599
|
+
|
|
3600
|
+
A polynomial is unramified if its reduction modulo the maximal
|
|
3601
|
+
ideal is irreducible.
|
|
3602
|
+
|
|
3603
|
+
EXAMPLES::
|
|
3604
|
+
|
|
3605
|
+
sage: # needs sage.libs.ntl
|
|
3606
|
+
sage: R = Zp(5)
|
|
3607
|
+
sage: S.<x> = R[]
|
|
3608
|
+
sage: from sage.rings.padics.factory import is_unramified
|
|
3609
|
+
sage: f = x^4 + 14*x + 9
|
|
3610
|
+
sage: is_unramified(f)
|
|
3611
|
+
True
|
|
3612
|
+
sage: g = x^6 + 17*x + 6
|
|
3613
|
+
sage: is_unramified(g)
|
|
3614
|
+
False
|
|
3615
|
+
"""
|
|
3616
|
+
if poly[0].valuation() > 0:
|
|
3617
|
+
return False
|
|
3618
|
+
if reduce(lambda a, b: a or b, [(c.valuation() < 0) for c in poly.list()[1:poly.degree()]]):
|
|
3619
|
+
return False
|
|
3620
|
+
F = poly.parent().change_ring(poly.base_ring().residue_class_field())(poly).factor()
|
|
3621
|
+
if len(F) != 1 or F[0][1] != 1:
|
|
3622
|
+
return False
|
|
3623
|
+
return True
|