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,1423 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
r"""
|
|
3
|
+
`p`-adic Valuations on Number Fields and Their Subrings and Completions
|
|
4
|
+
|
|
5
|
+
EXAMPLES::
|
|
6
|
+
|
|
7
|
+
sage: ZZ.valuation(2)
|
|
8
|
+
2-adic valuation
|
|
9
|
+
sage: QQ.valuation(3)
|
|
10
|
+
3-adic valuation
|
|
11
|
+
sage: CyclotomicField(5).valuation(5) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
12
|
+
5-adic valuation
|
|
13
|
+
sage: GaussianIntegers().valuation(7) # needs sage.rings.number_field
|
|
14
|
+
7-adic valuation
|
|
15
|
+
sage: Zp(11).valuation()
|
|
16
|
+
11-adic valuation
|
|
17
|
+
|
|
18
|
+
These valuations can then, e.g., be used to compute approximate factorizations
|
|
19
|
+
in the completion of a ring::
|
|
20
|
+
|
|
21
|
+
sage: v = ZZ.valuation(2)
|
|
22
|
+
sage: R.<x> = ZZ[]
|
|
23
|
+
sage: f = x^5 + x^4 + x^3 + x^2 + x - 1
|
|
24
|
+
sage: v.montes_factorization(f, required_precision=20) # needs sage.geometry.polyhedron
|
|
25
|
+
(x + 676027) * (x^4 + 372550*x^3 + 464863*x^2 + 385052*x + 297869)
|
|
26
|
+
|
|
27
|
+
AUTHORS:
|
|
28
|
+
|
|
29
|
+
- Julian Rüth (2013-03-16): initial version
|
|
30
|
+
|
|
31
|
+
REFERENCES:
|
|
32
|
+
|
|
33
|
+
The theory used here was originally developed in [Mac1936I]_ and [Mac1936II]_. An
|
|
34
|
+
overview can also be found in Chapter 4 of [Rüt2014]_.
|
|
35
|
+
"""
|
|
36
|
+
#*****************************************************************************
|
|
37
|
+
# Copyright (C) 2013-2020 Julian Rüth <julian.rueth@fsfe.org>
|
|
38
|
+
#
|
|
39
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
40
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
41
|
+
# the License, or (at your option) any later version.
|
|
42
|
+
# http://www.gnu.org/licenses/
|
|
43
|
+
#*****************************************************************************
|
|
44
|
+
from sage.rings.valuation.valuation import DiscreteValuation
|
|
45
|
+
from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
46
|
+
from sage.rings.valuation.mapped_valuation import FiniteExtensionFromLimitValuation
|
|
47
|
+
from sage.structure.factory import UniqueFactory
|
|
48
|
+
from sage.misc.cachefunc import cached_method
|
|
49
|
+
|
|
50
|
+
from sage.rings.infinity import infinity
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class PadicValuationFactory(UniqueFactory):
|
|
54
|
+
r"""
|
|
55
|
+
Create a ``prime``-adic valuation on ``R``.
|
|
56
|
+
|
|
57
|
+
INPUT:
|
|
58
|
+
|
|
59
|
+
- ``R`` -- a subring of a number field or a subring of a local field in
|
|
60
|
+
characteristic zero
|
|
61
|
+
|
|
62
|
+
- ``prime`` -- a prime that does not split, a discrete (pseudo-)valuation,
|
|
63
|
+
a fractional ideal, or ``None`` (default: ``None``)
|
|
64
|
+
|
|
65
|
+
EXAMPLES:
|
|
66
|
+
|
|
67
|
+
For integers and rational numbers, ``prime`` is just a prime of the
|
|
68
|
+
integers::
|
|
69
|
+
|
|
70
|
+
sage: valuations.pAdicValuation(ZZ, 3)
|
|
71
|
+
3-adic valuation
|
|
72
|
+
|
|
73
|
+
sage: valuations.pAdicValuation(QQ, 3)
|
|
74
|
+
3-adic valuation
|
|
75
|
+
|
|
76
|
+
``prime`` may be ``None`` for local rings::
|
|
77
|
+
|
|
78
|
+
sage: valuations.pAdicValuation(Qp(2))
|
|
79
|
+
2-adic valuation
|
|
80
|
+
|
|
81
|
+
sage: valuations.pAdicValuation(Zp(2))
|
|
82
|
+
2-adic valuation
|
|
83
|
+
|
|
84
|
+
But it must be specified in all other cases::
|
|
85
|
+
|
|
86
|
+
sage: valuations.pAdicValuation(ZZ)
|
|
87
|
+
Traceback (most recent call last):
|
|
88
|
+
...
|
|
89
|
+
ValueError: prime must be specified for this ring
|
|
90
|
+
|
|
91
|
+
It can sometimes be beneficial to define a number field extension as a
|
|
92
|
+
quotient of a polynomial ring (since number field extensions always compute
|
|
93
|
+
an absolute polynomial defining the extension which can be very costly)::
|
|
94
|
+
|
|
95
|
+
sage: # needs sage.rings.number_field
|
|
96
|
+
sage: R.<x> = QQ[]
|
|
97
|
+
sage: K.<a> = NumberField(x^2 + 1)
|
|
98
|
+
sage: R.<x> = K[]
|
|
99
|
+
sage: L.<b> = R.quo(x^2 + a)
|
|
100
|
+
sage: valuations.pAdicValuation(L, 2) # needs sage.geometry.polyhedron
|
|
101
|
+
2-adic valuation
|
|
102
|
+
|
|
103
|
+
.. SEEALSO::
|
|
104
|
+
|
|
105
|
+
:meth:`NumberField_generic.valuation() <sage.rings.number_field.number_field.NumberField_generic.valuation>`,
|
|
106
|
+
:meth:`Order.valuation() <sage.rings.number_field.order.Order.valuation>`,
|
|
107
|
+
:meth:`pAdicGeneric.valuation() <sage.rings.padics.padic_generic.pAdicGeneric.valuation>`,
|
|
108
|
+
:meth:`RationalField.valuation() <sage.rings.rational_field.RationalField.valuation>`,
|
|
109
|
+
:meth:`IntegerRing_class.valuation() <sage.rings.integer_ring.IntegerRing_class.valuation>`.
|
|
110
|
+
"""
|
|
111
|
+
def create_key_and_extra_args(self, R, prime=None, approximants=None):
|
|
112
|
+
r"""
|
|
113
|
+
Create a unique key identifying the valuation of ``R`` with respect to
|
|
114
|
+
``prime``.
|
|
115
|
+
|
|
116
|
+
EXAMPLES::
|
|
117
|
+
|
|
118
|
+
sage: QQ.valuation(2) # indirect doctest
|
|
119
|
+
2-adic valuation
|
|
120
|
+
"""
|
|
121
|
+
from sage.rings.integer_ring import ZZ
|
|
122
|
+
from sage.rings.rational_field import QQ
|
|
123
|
+
from sage.rings.padics.padic_generic import pAdicGeneric
|
|
124
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
125
|
+
from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
|
|
126
|
+
|
|
127
|
+
if R.characteristic() != 0:
|
|
128
|
+
# We do not support equal characteristic yet
|
|
129
|
+
raise ValueError("R must be a ring of characteristic zero.")
|
|
130
|
+
|
|
131
|
+
if R is ZZ or R is QQ:
|
|
132
|
+
return self.create_key_for_integers(R, prime), {}
|
|
133
|
+
elif isinstance(R, pAdicGeneric):
|
|
134
|
+
return self.create_key_for_local_ring(R, prime), {}
|
|
135
|
+
elif isinstance(R.fraction_field(), NumberField) or isinstance(R, PolynomialQuotientRing_generic):
|
|
136
|
+
return self.create_key_and_extra_args_for_number_field(R, prime, approximants=approximants)
|
|
137
|
+
else:
|
|
138
|
+
raise NotImplementedError("p-adic valuations not implemented for %r" % (R,))
|
|
139
|
+
|
|
140
|
+
def create_key_for_integers(self, R, prime):
|
|
141
|
+
r"""
|
|
142
|
+
Create a unique key identifying the valuation of ``R`` with respect to
|
|
143
|
+
``prime``.
|
|
144
|
+
|
|
145
|
+
EXAMPLES::
|
|
146
|
+
|
|
147
|
+
sage: QQ.valuation(2) # indirect doctest
|
|
148
|
+
2-adic valuation
|
|
149
|
+
"""
|
|
150
|
+
from sage.rings.integer_ring import ZZ
|
|
151
|
+
if prime is None:
|
|
152
|
+
raise ValueError("prime must be specified for this ring")
|
|
153
|
+
from sage.rings.valuation.valuation import DiscretePseudoValuation
|
|
154
|
+
if isinstance(prime, DiscretePseudoValuation):
|
|
155
|
+
prime = prime.uniformizer()
|
|
156
|
+
if prime not in ZZ or not ZZ(prime).is_prime():
|
|
157
|
+
raise ValueError("prime must be a prime in the integers but %s is not" % (prime,))
|
|
158
|
+
return R, prime
|
|
159
|
+
|
|
160
|
+
def create_key_for_local_ring(self, R, prime):
|
|
161
|
+
r"""
|
|
162
|
+
Create a unique key identifying the valuation of ``R`` with respect to
|
|
163
|
+
``prime``.
|
|
164
|
+
|
|
165
|
+
EXAMPLES::
|
|
166
|
+
|
|
167
|
+
sage: Qp(2).valuation() # indirect doctest
|
|
168
|
+
2-adic valuation
|
|
169
|
+
"""
|
|
170
|
+
# We do not care much about the value of prime since there is only one
|
|
171
|
+
# reasonable p-adic valuation here
|
|
172
|
+
if prime is not None:
|
|
173
|
+
if prime in R:
|
|
174
|
+
if R(prime).valuation() <= 0:
|
|
175
|
+
raise ValueError("prime must be an element of positive valuation")
|
|
176
|
+
elif prime(R.prime()) <= 0:
|
|
177
|
+
raise ValueError("prime must be an element of positive valuation")
|
|
178
|
+
|
|
179
|
+
return (R,)
|
|
180
|
+
|
|
181
|
+
def create_key_and_extra_args_for_number_field(self, R, prime, approximants):
|
|
182
|
+
r"""
|
|
183
|
+
Create a unique key identifying the valuation of ``R`` with respect to
|
|
184
|
+
``prime``.
|
|
185
|
+
|
|
186
|
+
EXAMPLES::
|
|
187
|
+
|
|
188
|
+
sage: GaussianIntegers().valuation(2) # indirect doctest # needs sage.geometry.polyhedron sage.rings.number_field
|
|
189
|
+
2-adic valuation
|
|
190
|
+
"""
|
|
191
|
+
K, L, G = self._normalize_number_field_data(R)
|
|
192
|
+
|
|
193
|
+
from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal
|
|
194
|
+
from sage.rings.valuation.valuation import DiscretePseudoValuation
|
|
195
|
+
if isinstance(prime, DiscretePseudoValuation):
|
|
196
|
+
return self.create_key_and_extra_args_for_number_field_from_valuation(R, prime, prime, approximants=approximants)
|
|
197
|
+
elif prime in K:
|
|
198
|
+
return self.create_key_and_extra_args_for_number_field_from_valuation(R, K.valuation(prime), prime, approximants=approximants)
|
|
199
|
+
elif prime in L or isinstance(prime, NumberFieldFractionalIdeal):
|
|
200
|
+
return self.create_key_and_extra_args_for_number_field_from_ideal(R, L.fractional_ideal(prime), prime)
|
|
201
|
+
else:
|
|
202
|
+
raise ValueError("prime must be a discrete pseudo-valuation, a prime in the base ring, or a fractional ideal")
|
|
203
|
+
|
|
204
|
+
def create_key_and_extra_args_for_number_field_from_valuation(self, R, v, prime, approximants):
|
|
205
|
+
r"""
|
|
206
|
+
Create a unique key identifying the valuation of ``R`` with respect to
|
|
207
|
+
``v``.
|
|
208
|
+
|
|
209
|
+
.. NOTE::
|
|
210
|
+
|
|
211
|
+
``prime``, the original parameter that was passed to
|
|
212
|
+
:meth:`create_key_and_extra_args`, is only used to provide more
|
|
213
|
+
meaningful error messages
|
|
214
|
+
|
|
215
|
+
EXAMPLES::
|
|
216
|
+
|
|
217
|
+
sage: GaussianIntegers().valuation(ZZ.valuation(2)) # indirect doctest # needs sage.geometry.polyhedron sage.rings.number_field
|
|
218
|
+
2-adic valuation
|
|
219
|
+
|
|
220
|
+
TESTS:
|
|
221
|
+
|
|
222
|
+
We can extend to the field of fractions of a quotient ring::
|
|
223
|
+
|
|
224
|
+
sage: R.<x> = ZZ[]
|
|
225
|
+
sage: S = R.quo(x^2 + 1)
|
|
226
|
+
sage: v = valuations.pAdicValuation(S, 2) # needs sage.geometry.polyhedron
|
|
227
|
+
sage: R.<x> = QQ[]
|
|
228
|
+
sage: S = R.quo(x^2 + 1)
|
|
229
|
+
sage: v = valuations.pAdicValuation(S, v) # needs sage.geometry.polyhedron
|
|
230
|
+
"""
|
|
231
|
+
K, L, G = self._normalize_number_field_data(R)
|
|
232
|
+
|
|
233
|
+
if v.domain().is_subring(G.parent()):
|
|
234
|
+
# v is defined on a subring of K[x].
|
|
235
|
+
# We try to lift v to a pseudo-valuation on K[x].
|
|
236
|
+
if _fraction_field(v.domain()) is not _fraction_field(G.parent()):
|
|
237
|
+
# First, we lift valuations defined on subrings of K to
|
|
238
|
+
# valuations on K[x].
|
|
239
|
+
if v.domain().is_subring(K):
|
|
240
|
+
if v.domain() is not K:
|
|
241
|
+
v = K.valuation(v)
|
|
242
|
+
from sage.rings.valuation.gauss_valuation import GaussValuation
|
|
243
|
+
v = GaussValuation(G.parent(), v)
|
|
244
|
+
if v.domain() != G.parent():
|
|
245
|
+
# Then, we lift valuations defined on polynomial rings which are
|
|
246
|
+
# subrings of K[x] to K[x]
|
|
247
|
+
v = v.extension(G.parent())
|
|
248
|
+
elif _fraction_field(v.domain()) == L:
|
|
249
|
+
# v is defined on a ring whose field of fractions is L
|
|
250
|
+
v = v._base_valuation._initial_approximation.change_domain(G.parent())
|
|
251
|
+
else:
|
|
252
|
+
raise NotImplementedError("cannot rewrite %r which is defined on %r as a pseudo-valuation on %r" % (v, v.domain(), G.parent()))
|
|
253
|
+
|
|
254
|
+
assert (v.domain() is G.parent())
|
|
255
|
+
|
|
256
|
+
# To obtain uniqueness of p-adic valuations, we need a canonical
|
|
257
|
+
# description of v. We consider all extensions of vK to L and select
|
|
258
|
+
# the one approximated by v.
|
|
259
|
+
vK = v.restriction(v.domain().base_ring()).extension(K)
|
|
260
|
+
if approximants is None:
|
|
261
|
+
approximants = vK.mac_lane_approximants(G, require_incomparability=True)
|
|
262
|
+
approximants = [approximant.extension(v.domain()) for approximant in approximants]
|
|
263
|
+
approximant = vK.mac_lane_approximant(G, v, approximants=tuple(approximants))
|
|
264
|
+
|
|
265
|
+
return (R, approximant), {'approximants': approximants}
|
|
266
|
+
|
|
267
|
+
def create_key_and_extra_args_for_number_field_from_ideal(self, R, I, prime):
|
|
268
|
+
r"""
|
|
269
|
+
Create a unique key identifying the valuation of ``R`` with respect to
|
|
270
|
+
``I``.
|
|
271
|
+
|
|
272
|
+
.. NOTE::
|
|
273
|
+
|
|
274
|
+
``prime``, the original parameter that was passed to
|
|
275
|
+
:meth:`create_key_and_extra_args`, is only used to provide more
|
|
276
|
+
meaningful error messages
|
|
277
|
+
|
|
278
|
+
EXAMPLES::
|
|
279
|
+
|
|
280
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
281
|
+
sage: GaussianIntegers().valuation(GaussianIntegers().number_field().fractional_ideal(2)) # indirect doctest
|
|
282
|
+
2-adic valuation
|
|
283
|
+
|
|
284
|
+
TESTS:
|
|
285
|
+
|
|
286
|
+
Verify that :issue:`28976` has been resolved::
|
|
287
|
+
|
|
288
|
+
sage: # needs sage.rings.number_field
|
|
289
|
+
sage: R.<x> = QQ[]
|
|
290
|
+
sage: K.<a> = NumberField(x^6 - 18*x^4 - 24*x^3 + 27*x^2 + 36*x - 6)
|
|
291
|
+
sage: I = K.fractional_ideal((2, -7/44*a^5 + 19/44*a^4 + 87/44*a^3 - 87/44*a^2 - 5/2*a + 39/22))
|
|
292
|
+
sage: I.norm()
|
|
293
|
+
2
|
|
294
|
+
sage: I in K.primes_above(2)
|
|
295
|
+
True
|
|
296
|
+
sage: K.valuation(I) # needs sage.geometry.polyhedron
|
|
297
|
+
[ 2-adic valuation, v(x + 1) = 1/2 ]-adic valuation
|
|
298
|
+
|
|
299
|
+
::
|
|
300
|
+
|
|
301
|
+
sage: # needs sage.rings.number_field
|
|
302
|
+
sage: K.<a, b> = NumberField([x^2 - 2, x^2 + x + 1])
|
|
303
|
+
sage: K.valuation(2) # needs sage.geometry.polyhedron
|
|
304
|
+
2-adic valuation
|
|
305
|
+
"""
|
|
306
|
+
K, L, G = self._normalize_number_field_data(R)
|
|
307
|
+
|
|
308
|
+
# To obtain uniqueness of p-adic valuations, we need a canonical
|
|
309
|
+
# description of v. We consider all extensions of vK to L and select
|
|
310
|
+
# the one approximated by v.
|
|
311
|
+
# Of course, this only works if I comes from a single prime downstairs.
|
|
312
|
+
p = I.relative_norm()
|
|
313
|
+
F = p.factor()
|
|
314
|
+
if len(F) != 1:
|
|
315
|
+
raise ValueError("%r does not lie over a single prime of %r" % (I, K))
|
|
316
|
+
vK = K.valuation(F[0][0])
|
|
317
|
+
approximants = vK.mac_lane_approximants(G, require_incomparability=True)
|
|
318
|
+
|
|
319
|
+
candidates = approximants[:]
|
|
320
|
+
|
|
321
|
+
# The correct approximant has v(g) > 0 for all g in the ideal.
|
|
322
|
+
# Unfortunately, the generators of I, even though defined over K have
|
|
323
|
+
# their polynomial() defined over the rationals so we need to turn them
|
|
324
|
+
# into polynomials over K[x] explicitly.
|
|
325
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
326
|
+
gens = I.gens()
|
|
327
|
+
gens = [PolynomialRing(K, 'x')(list(g.vector())) for g in gens]
|
|
328
|
+
|
|
329
|
+
# Refine candidates until we can detect which valuation corresponds to the ideal I
|
|
330
|
+
while True:
|
|
331
|
+
assert any(candidates), "the defining polynomial of the extension factored but we still could not figure out which valuation corresponds to the given ideal"
|
|
332
|
+
|
|
333
|
+
match = [i for (i, v) in enumerate(candidates) if v and all(v(g) > 0 for g in gens)]
|
|
334
|
+
|
|
335
|
+
if len(match) > 1:
|
|
336
|
+
raise ValueError("%s does not single out a unique extension of %s to %s" % (prime, vK, L))
|
|
337
|
+
if len(match) == 1:
|
|
338
|
+
return (R, approximants[match[0]]), {'approximants': approximants}
|
|
339
|
+
|
|
340
|
+
# We refine candidates which increases v(g) for all g in I;
|
|
341
|
+
# however, we cannot augment the valuations which are already at
|
|
342
|
+
# v(G) = +∞ which we ignore by setting them to None.
|
|
343
|
+
candidates = [v.mac_lane_step(G)[0] if v and v.is_discrete_valuation() else None for v in candidates]
|
|
344
|
+
|
|
345
|
+
def _normalize_number_field_data(self, R):
|
|
346
|
+
r"""
|
|
347
|
+
Helper method which returns the defining data of the number field
|
|
348
|
+
``R``.
|
|
349
|
+
|
|
350
|
+
EXAMPLES::
|
|
351
|
+
|
|
352
|
+
sage: R.<x> = QQ[]
|
|
353
|
+
sage: K = R.quo(x^2 + 1)
|
|
354
|
+
sage: valuations.pAdicValuation._normalize_number_field_data(K)
|
|
355
|
+
(Rational Field,
|
|
356
|
+
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1,
|
|
357
|
+
x^2 + 1)
|
|
358
|
+
"""
|
|
359
|
+
from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
|
|
360
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
361
|
+
if isinstance(R.fraction_field(), NumberField):
|
|
362
|
+
L = R.fraction_field()
|
|
363
|
+
G = L.relative_polynomial()
|
|
364
|
+
K = L.base_ring()
|
|
365
|
+
elif isinstance(R, PolynomialQuotientRing_generic):
|
|
366
|
+
from sage.categories.number_fields import NumberFields
|
|
367
|
+
if R.base_ring().fraction_field() not in NumberFields():
|
|
368
|
+
raise NotImplementedError("cannot normalize quotients over %r" % (R.base_ring(),))
|
|
369
|
+
L = R.fraction_field()
|
|
370
|
+
K = R.base_ring().fraction_field()
|
|
371
|
+
G = R.modulus().change_ring(K)
|
|
372
|
+
else:
|
|
373
|
+
raise NotImplementedError("cannot normalize %r" % (R,))
|
|
374
|
+
|
|
375
|
+
return K, L, G
|
|
376
|
+
|
|
377
|
+
def create_object(self, version, key, **extra_args):
|
|
378
|
+
r"""
|
|
379
|
+
Create a `p`-adic valuation from ``key``.
|
|
380
|
+
|
|
381
|
+
EXAMPLES::
|
|
382
|
+
|
|
383
|
+
sage: ZZ.valuation(5) # indirect doctest
|
|
384
|
+
5-adic valuation
|
|
385
|
+
"""
|
|
386
|
+
from sage.rings.integer_ring import ZZ
|
|
387
|
+
from sage.rings.rational_field import QQ
|
|
388
|
+
from sage.rings.padics.padic_generic import pAdicGeneric
|
|
389
|
+
from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
|
|
390
|
+
from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
|
|
391
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
392
|
+
R = key[0]
|
|
393
|
+
parent = DiscretePseudoValuationSpace(R)
|
|
394
|
+
if isinstance(R, pAdicGeneric):
|
|
395
|
+
assert (len(key) == 1)
|
|
396
|
+
return parent.__make_element_class__(pAdicValuation_padic)(parent)
|
|
397
|
+
elif R is ZZ or R is QQ:
|
|
398
|
+
prime = key[1]
|
|
399
|
+
assert (len(key) == 2)
|
|
400
|
+
return parent.__make_element_class__(pAdicValuation_int)(parent, prime)
|
|
401
|
+
else:
|
|
402
|
+
v = key[1]
|
|
403
|
+
approximants = extra_args['approximants']
|
|
404
|
+
parent = DiscretePseudoValuationSpace(R)
|
|
405
|
+
K = R.fraction_field()
|
|
406
|
+
if isinstance(K, NumberField):
|
|
407
|
+
G = K.relative_polynomial()
|
|
408
|
+
elif isinstance(R, PolynomialQuotientRing_generic):
|
|
409
|
+
G = R.modulus()
|
|
410
|
+
else:
|
|
411
|
+
raise NotImplementedError
|
|
412
|
+
return parent.__make_element_class__(pAdicFromLimitValuation)(parent, v, G.change_ring(R.base_ring()), approximants)
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
pAdicValuation = PadicValuationFactory("sage.rings.padics.padic_valuation.pAdicValuation")
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
class pAdicValuation_base(DiscreteValuation):
|
|
419
|
+
r"""
|
|
420
|
+
Abstract base class for `p`-adic valuations.
|
|
421
|
+
|
|
422
|
+
INPUT:
|
|
423
|
+
|
|
424
|
+
- ``ring`` -- an integral domain
|
|
425
|
+
|
|
426
|
+
- ``p`` -- a rational prime over which this valuation lies, not
|
|
427
|
+
necessarily a uniformizer for the valuation
|
|
428
|
+
|
|
429
|
+
EXAMPLES::
|
|
430
|
+
|
|
431
|
+
sage: ZZ.valuation(3)
|
|
432
|
+
3-adic valuation
|
|
433
|
+
|
|
434
|
+
sage: QQ.valuation(5)
|
|
435
|
+
5-adic valuation
|
|
436
|
+
|
|
437
|
+
For `p`-adic rings, ``p`` has to match the `p` of the ring. ::
|
|
438
|
+
|
|
439
|
+
sage: v = valuations.pAdicValuation(Zp(3), 2); v
|
|
440
|
+
Traceback (most recent call last):
|
|
441
|
+
...
|
|
442
|
+
ValueError: prime must be an element of positive valuation
|
|
443
|
+
|
|
444
|
+
TESTS::
|
|
445
|
+
|
|
446
|
+
sage: TestSuite(ZZ.valuation(3)).run() # long time # needs sage.geometry.polyhedron
|
|
447
|
+
sage: TestSuite(QQ.valuation(5)).run() # long time # needs sage.geometry.polyhedron
|
|
448
|
+
sage: TestSuite(Zp(5).valuation()).run() # long time # needs sage.geometry.polyhedron
|
|
449
|
+
"""
|
|
450
|
+
def __init__(self, parent, p):
|
|
451
|
+
r"""
|
|
452
|
+
TESTS::
|
|
453
|
+
|
|
454
|
+
sage: from sage.rings.padics.padic_valuation import pAdicValuation_base
|
|
455
|
+
sage: isinstance(ZZ.valuation(3), pAdicValuation_base)
|
|
456
|
+
True
|
|
457
|
+
"""
|
|
458
|
+
DiscreteValuation.__init__(self, parent)
|
|
459
|
+
|
|
460
|
+
from sage.rings.integer_ring import ZZ
|
|
461
|
+
self._p = ZZ(p)
|
|
462
|
+
|
|
463
|
+
def p(self):
|
|
464
|
+
r"""
|
|
465
|
+
Return the `p` of this `p`-adic valuation.
|
|
466
|
+
|
|
467
|
+
EXAMPLES::
|
|
468
|
+
|
|
469
|
+
sage: GaussianIntegers().valuation(2).p() # needs sage.geometry.polyhedron sage.rings.number_field
|
|
470
|
+
2
|
|
471
|
+
"""
|
|
472
|
+
return self._p
|
|
473
|
+
|
|
474
|
+
def reduce(self, x):
|
|
475
|
+
r"""
|
|
476
|
+
Reduce ``x`` modulo the ideal of elements of positive valuation.
|
|
477
|
+
|
|
478
|
+
INPUT:
|
|
479
|
+
|
|
480
|
+
- ``x`` -- an element in the domain of this valuation
|
|
481
|
+
|
|
482
|
+
OUTPUT: an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`
|
|
483
|
+
|
|
484
|
+
EXAMPLES::
|
|
485
|
+
|
|
486
|
+
sage: v = ZZ.valuation(3)
|
|
487
|
+
sage: v.reduce(4)
|
|
488
|
+
1
|
|
489
|
+
"""
|
|
490
|
+
x = self.domain().coerce(x)
|
|
491
|
+
|
|
492
|
+
if self(x) < 0:
|
|
493
|
+
raise ValueError("reduction is only defined for elements of nonnegative valuation")
|
|
494
|
+
|
|
495
|
+
return self.residue_field()(x)
|
|
496
|
+
|
|
497
|
+
def lift(self, x):
|
|
498
|
+
r"""
|
|
499
|
+
Lift ``x`` from the residue field to the domain of this valuation.
|
|
500
|
+
|
|
501
|
+
INPUT:
|
|
502
|
+
|
|
503
|
+
- ``x`` -- an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`
|
|
504
|
+
|
|
505
|
+
EXAMPLES::
|
|
506
|
+
|
|
507
|
+
sage: v = ZZ.valuation(3)
|
|
508
|
+
sage: xbar = v.reduce(4)
|
|
509
|
+
sage: v.lift(xbar)
|
|
510
|
+
1
|
|
511
|
+
"""
|
|
512
|
+
x = self.residue_field().coerce(x)
|
|
513
|
+
|
|
514
|
+
return self.domain()(x)
|
|
515
|
+
|
|
516
|
+
def is_unramified(self, G, include_steps=False, assume_squarefree=False):
|
|
517
|
+
r"""
|
|
518
|
+
Return whether ``G`` defines a single unramified extension of the
|
|
519
|
+
completion of the domain of this valuation.
|
|
520
|
+
|
|
521
|
+
INPUT:
|
|
522
|
+
|
|
523
|
+
- ``G`` -- a monic squarefree polynomial over the domain of this valuation
|
|
524
|
+
|
|
525
|
+
- ``include_steps`` -- boolean (default: ``False``); whether to
|
|
526
|
+
include the approximate valuations that were used to determine the
|
|
527
|
+
result in the return value
|
|
528
|
+
|
|
529
|
+
- ``assume_squarefree`` -- boolean (default: ``False``); whether to
|
|
530
|
+
assume that ``G`` is square-free over the completion of the domain of
|
|
531
|
+
this valuation. Setting this to ``True`` can significantly improve
|
|
532
|
+
the performance.
|
|
533
|
+
|
|
534
|
+
EXAMPLES:
|
|
535
|
+
|
|
536
|
+
We consider an extension as unramified if its ramification index is 1.
|
|
537
|
+
Hence, a trivial extension is unramified::
|
|
538
|
+
|
|
539
|
+
sage: R.<x> = QQ[]
|
|
540
|
+
sage: v = QQ.valuation(2)
|
|
541
|
+
sage: v.is_unramified(x)
|
|
542
|
+
True
|
|
543
|
+
|
|
544
|
+
If ``G`` remains irreducible in reduction, then it defines an
|
|
545
|
+
unramified extension::
|
|
546
|
+
|
|
547
|
+
sage: v.is_unramified(x^2 + x + 1)
|
|
548
|
+
True
|
|
549
|
+
|
|
550
|
+
However, even if ``G`` factors, it might define an unramified
|
|
551
|
+
extension::
|
|
552
|
+
|
|
553
|
+
sage: v.is_unramified(x^2 + 2*x + 4) # needs sage.geometry.polyhedron
|
|
554
|
+
True
|
|
555
|
+
"""
|
|
556
|
+
R = G.parent()
|
|
557
|
+
|
|
558
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
559
|
+
if not isinstance(R, PolynomialRing_generic) or R.base_ring() is not self.domain() or not G.is_monic():
|
|
560
|
+
raise ValueError("G must be a monic univariate polynomial over the domain of this valuation")
|
|
561
|
+
if not assume_squarefree and not G.is_squarefree():
|
|
562
|
+
raise ValueError("G must be squarefree")
|
|
563
|
+
|
|
564
|
+
from sage.rings.valuation.gauss_valuation import GaussValuation
|
|
565
|
+
|
|
566
|
+
steps = [ GaussValuation(R, self) ]
|
|
567
|
+
while True:
|
|
568
|
+
v = steps[-1]
|
|
569
|
+
if v.E() > 1:
|
|
570
|
+
ret = False
|
|
571
|
+
break
|
|
572
|
+
if v.F() == G.degree():
|
|
573
|
+
ret = True
|
|
574
|
+
break
|
|
575
|
+
|
|
576
|
+
assert v(G) is not infinity
|
|
577
|
+
if v.is_key(G):
|
|
578
|
+
ret = True
|
|
579
|
+
break
|
|
580
|
+
|
|
581
|
+
next = v.mac_lane_step(G, assume_squarefree=True)
|
|
582
|
+
if len(next) > 1:
|
|
583
|
+
ret = False
|
|
584
|
+
break
|
|
585
|
+
steps.append(next[0])
|
|
586
|
+
|
|
587
|
+
if include_steps:
|
|
588
|
+
return ret, steps
|
|
589
|
+
else:
|
|
590
|
+
return ret
|
|
591
|
+
|
|
592
|
+
def is_totally_ramified(self, G, include_steps=False, assume_squarefree=False):
|
|
593
|
+
r"""
|
|
594
|
+
Return whether ``G`` defines a single totally ramified extension of the
|
|
595
|
+
completion of the domain of this valuation.
|
|
596
|
+
|
|
597
|
+
INPUT:
|
|
598
|
+
|
|
599
|
+
- ``G`` -- a monic squarefree polynomial over the domain of this valuation
|
|
600
|
+
|
|
601
|
+
- ``include_steps`` -- boolean (default: ``False``); where to include
|
|
602
|
+
the valuations produced during the process of checking whether ``G``
|
|
603
|
+
is totally ramified in the return value
|
|
604
|
+
|
|
605
|
+
- ``assume_squarefree`` -- boolean (default: ``False``); whether to
|
|
606
|
+
assume that ``G`` is square-free over the completion of the domain of
|
|
607
|
+
this valuation. Setting this to ``True`` can significantly improve
|
|
608
|
+
the performance.
|
|
609
|
+
|
|
610
|
+
ALGORITHM:
|
|
611
|
+
|
|
612
|
+
This is a simplified version of :meth:`sage.rings.valuation.valuation.DiscreteValuation.mac_lane_approximants`.
|
|
613
|
+
|
|
614
|
+
EXAMPLES::
|
|
615
|
+
|
|
616
|
+
sage: # needs sage.libs.ntl
|
|
617
|
+
sage: k = Qp(5,4)
|
|
618
|
+
sage: v = k.valuation()
|
|
619
|
+
sage: R.<x> = k[]
|
|
620
|
+
sage: G = x^2 + 1
|
|
621
|
+
sage: v.is_totally_ramified(G) # needs sage.geometry.polyhedron
|
|
622
|
+
False
|
|
623
|
+
sage: G = x + 1
|
|
624
|
+
sage: v.is_totally_ramified(G)
|
|
625
|
+
True
|
|
626
|
+
sage: G = x^2 + 2
|
|
627
|
+
sage: v.is_totally_ramified(G)
|
|
628
|
+
False
|
|
629
|
+
sage: G = x^2 + 5
|
|
630
|
+
sage: v.is_totally_ramified(G) # needs sage.geometry.polyhedron
|
|
631
|
+
True
|
|
632
|
+
sage: v.is_totally_ramified(G, include_steps=True) # needs sage.geometry.polyhedron
|
|
633
|
+
(True, [Gauss valuation induced by 5-adic valuation, [ Gauss valuation induced by 5-adic valuation, v((1 + O(5^4))*x) = 1/2 ]])
|
|
634
|
+
|
|
635
|
+
We consider an extension as totally ramified if its ramification index
|
|
636
|
+
matches the degree. Hence, a trivial extension is totally ramified::
|
|
637
|
+
|
|
638
|
+
sage: R.<x> = QQ[]
|
|
639
|
+
sage: v = QQ.valuation(2)
|
|
640
|
+
sage: v.is_totally_ramified(x)
|
|
641
|
+
True
|
|
642
|
+
|
|
643
|
+
TESTS:
|
|
644
|
+
|
|
645
|
+
An example that Sebastian Pauli used at Sage Days 87::
|
|
646
|
+
|
|
647
|
+
sage: R = ZpFM(3, 20)
|
|
648
|
+
sage: S.<x> = R[]
|
|
649
|
+
sage: f = x^9 + 9*x^2 + 3
|
|
650
|
+
sage: R.valuation().is_totally_ramified(f) # needs sage.geometry.polyhedron
|
|
651
|
+
True
|
|
652
|
+
"""
|
|
653
|
+
R = G.parent()
|
|
654
|
+
|
|
655
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
656
|
+
if not isinstance(R, PolynomialRing_generic) or R.base_ring() is not self.domain() or not G.is_monic():
|
|
657
|
+
raise ValueError("G must be a monic univariate polynomial over the domain of this valuation")
|
|
658
|
+
if not assume_squarefree and not G.is_squarefree():
|
|
659
|
+
raise ValueError("G must be squarefree")
|
|
660
|
+
|
|
661
|
+
from sage.rings.valuation.gauss_valuation import GaussValuation
|
|
662
|
+
|
|
663
|
+
steps = [ GaussValuation(R, self) ]
|
|
664
|
+
while True:
|
|
665
|
+
v = steps[-1]
|
|
666
|
+
if v.F() > 1:
|
|
667
|
+
ret = False
|
|
668
|
+
break
|
|
669
|
+
if v.E() == G.degree():
|
|
670
|
+
ret = True
|
|
671
|
+
break
|
|
672
|
+
|
|
673
|
+
assert v(G) is not infinity
|
|
674
|
+
if v.is_key(G):
|
|
675
|
+
ret = False
|
|
676
|
+
break
|
|
677
|
+
|
|
678
|
+
next = v.mac_lane_step(G, assume_squarefree=True)
|
|
679
|
+
if len(next) > 1:
|
|
680
|
+
ret = False
|
|
681
|
+
break
|
|
682
|
+
steps.append(next[0])
|
|
683
|
+
|
|
684
|
+
if include_steps:
|
|
685
|
+
return ret, steps
|
|
686
|
+
else:
|
|
687
|
+
return ret
|
|
688
|
+
|
|
689
|
+
def change_domain(self, ring):
|
|
690
|
+
r"""
|
|
691
|
+
Change the domain of this valuation to ``ring`` if possible.
|
|
692
|
+
|
|
693
|
+
EXAMPLES::
|
|
694
|
+
|
|
695
|
+
sage: v = ZZ.valuation(2)
|
|
696
|
+
sage: v.change_domain(QQ).domain()
|
|
697
|
+
Rational Field
|
|
698
|
+
"""
|
|
699
|
+
return pAdicValuation(ring, self.p())
|
|
700
|
+
|
|
701
|
+
def _extensions_to_quotient(self, ring, approximants=None):
|
|
702
|
+
r"""
|
|
703
|
+
Return the extensions of this valuation to an integral quotient over
|
|
704
|
+
the domain of this valuation.
|
|
705
|
+
|
|
706
|
+
EXAMPLES::
|
|
707
|
+
|
|
708
|
+
sage: R.<x> = QQ[]
|
|
709
|
+
sage: QQ.valuation(2)._extensions_to_quotient(R.quo(x^2 + x + 1))
|
|
710
|
+
[2-adic valuation]
|
|
711
|
+
"""
|
|
712
|
+
approximants = approximants or self.mac_lane_approximants(ring.modulus().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True)
|
|
713
|
+
return [pAdicValuation(ring, approximant, approximants) for approximant in approximants]
|
|
714
|
+
|
|
715
|
+
def extensions(self, ring):
|
|
716
|
+
r"""
|
|
717
|
+
Return the extensions of this valuation to ``ring``.
|
|
718
|
+
|
|
719
|
+
EXAMPLES::
|
|
720
|
+
|
|
721
|
+
sage: v = ZZ.valuation(2)
|
|
722
|
+
sage: v.extensions(GaussianIntegers()) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
723
|
+
[2-adic valuation]
|
|
724
|
+
|
|
725
|
+
TESTS::
|
|
726
|
+
|
|
727
|
+
sage: # needs sage.rings.number_field
|
|
728
|
+
sage: R.<a> = QQ[]
|
|
729
|
+
sage: x = polygen(ZZ, 'x')
|
|
730
|
+
sage: L.<a> = QQ.extension(x^3 - 2)
|
|
731
|
+
sage: R.<b> = L[]
|
|
732
|
+
sage: M.<b> = L.extension(b^2 + 2*b + a)
|
|
733
|
+
sage: M.valuation(2) # needs sage.geometry.polyhedron
|
|
734
|
+
2-adic valuation
|
|
735
|
+
|
|
736
|
+
Check that we can extend to a field written as a quotient::
|
|
737
|
+
|
|
738
|
+
sage: # needs sage.rings.number_field
|
|
739
|
+
sage: R.<x> = QQ[]
|
|
740
|
+
sage: K.<a> = QQ.extension(x^2 + 1)
|
|
741
|
+
sage: R.<y> = K[]
|
|
742
|
+
sage: L.<b> = R.quo(x^2 + a)
|
|
743
|
+
sage: QQ.valuation(2).extensions(L) # needs sage.geometry.polyhedron
|
|
744
|
+
[2-adic valuation]
|
|
745
|
+
|
|
746
|
+
A case where there was at some point an internal error in the
|
|
747
|
+
approximants code::
|
|
748
|
+
|
|
749
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
750
|
+
sage: R.<x> = QQ[]
|
|
751
|
+
sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8)
|
|
752
|
+
sage: QQ.valuation(2).extensions(L)
|
|
753
|
+
[[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation,
|
|
754
|
+
[ 2-adic valuation, v(x) = 1/2 ]-adic valuation]
|
|
755
|
+
|
|
756
|
+
A case where the extension was incorrect at some point::
|
|
757
|
+
|
|
758
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
759
|
+
sage: v = QQ.valuation(2)
|
|
760
|
+
sage: L.<a> = NumberField(x^2 + 2)
|
|
761
|
+
sage: M.<b> = L.extension(x^2 + 1)
|
|
762
|
+
sage: w = v.extension(L).extension(M)
|
|
763
|
+
sage: w(w.uniformizer())
|
|
764
|
+
1/4
|
|
765
|
+
|
|
766
|
+
A case where the extensions could not be separated at some point::
|
|
767
|
+
|
|
768
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
769
|
+
sage: v = QQ.valuation(2)
|
|
770
|
+
sage: R.<x> = QQ[]
|
|
771
|
+
sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68
|
|
772
|
+
sage: L.<a> = QQ.extension(F)
|
|
773
|
+
sage: v.extensions(L)
|
|
774
|
+
[[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation,
|
|
775
|
+
[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation]
|
|
776
|
+
"""
|
|
777
|
+
if self.domain() is ring:
|
|
778
|
+
return [self]
|
|
779
|
+
domain_fraction_field = _fraction_field(self.domain())
|
|
780
|
+
if domain_fraction_field is not self.domain():
|
|
781
|
+
if domain_fraction_field.is_subring(ring):
|
|
782
|
+
return pAdicValuation(domain_fraction_field, self).extensions(ring)
|
|
783
|
+
if self.domain().is_subring(ring):
|
|
784
|
+
from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
|
|
785
|
+
if isinstance(ring, PolynomialQuotientRing_generic):
|
|
786
|
+
if isinstance(self.domain(), PolynomialQuotientRing_generic):
|
|
787
|
+
if self.domain().modulus() == ring.modulus():
|
|
788
|
+
base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field()))
|
|
789
|
+
return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions]
|
|
790
|
+
if ring.base_ring() is self.domain():
|
|
791
|
+
from sage.categories.integral_domains import IntegralDomains
|
|
792
|
+
if ring in IntegralDomains():
|
|
793
|
+
return self._extensions_to_quotient(ring)
|
|
794
|
+
elif self.domain().is_subring(ring.base_ring()):
|
|
795
|
+
return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
|
|
796
|
+
from sage.rings.number_field.number_field_base import NumberField
|
|
797
|
+
if isinstance(ring.fraction_field(), NumberField):
|
|
798
|
+
if ring.base_ring().fraction_field() is self.domain().fraction_field():
|
|
799
|
+
approximants = self.mac_lane_approximants(ring.fraction_field().relative_polynomial().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True)
|
|
800
|
+
return [pAdicValuation(ring, approximant, approximants) for approximant in approximants]
|
|
801
|
+
if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()):
|
|
802
|
+
return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
|
|
803
|
+
return super().extensions(ring)
|
|
804
|
+
|
|
805
|
+
def restriction(self, ring):
|
|
806
|
+
r"""
|
|
807
|
+
Return the restriction of this valuation to ``ring``.
|
|
808
|
+
|
|
809
|
+
EXAMPLES::
|
|
810
|
+
|
|
811
|
+
sage: v = GaussianIntegers().valuation(2) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
812
|
+
sage: v.restriction(ZZ) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
813
|
+
2-adic valuation
|
|
814
|
+
"""
|
|
815
|
+
if ring is self.domain():
|
|
816
|
+
return self
|
|
817
|
+
|
|
818
|
+
if not ring.is_subring(self.domain()):
|
|
819
|
+
raise ValueError("ring must be a subring of the domain of this valuation but %r is not a subring of %r" % (ring, self.domain()))
|
|
820
|
+
|
|
821
|
+
return pAdicValuation(ring, self.p())
|
|
822
|
+
|
|
823
|
+
@cached_method
|
|
824
|
+
def value_semigroup(self):
|
|
825
|
+
r"""
|
|
826
|
+
Return the value semigroup of this valuation.
|
|
827
|
+
|
|
828
|
+
EXAMPLES::
|
|
829
|
+
|
|
830
|
+
sage: v = GaussianIntegers().valuation(2) # needs sage.geometry.polyhedron sage.rings.number_field
|
|
831
|
+
sage: v.value_semigroup() # needs sage.geometry.polyhedron sage.rings.number_field
|
|
832
|
+
Additive Abelian Semigroup generated by 1/2
|
|
833
|
+
"""
|
|
834
|
+
from sage.categories.fields import Fields
|
|
835
|
+
v = self(self.uniformizer())
|
|
836
|
+
if self.domain() in Fields():
|
|
837
|
+
return DiscreteValueSemigroup([-v,v])
|
|
838
|
+
else:
|
|
839
|
+
return DiscreteValueSemigroup([v])
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
class pAdicValuation_padic(pAdicValuation_base):
|
|
843
|
+
"""
|
|
844
|
+
The `p`-adic valuation of a complete `p`-adic ring.
|
|
845
|
+
|
|
846
|
+
INPUT:
|
|
847
|
+
|
|
848
|
+
- ``R`` -- a `p`-adic ring
|
|
849
|
+
|
|
850
|
+
EXAMPLES::
|
|
851
|
+
|
|
852
|
+
sage: v = Qp(2).valuation(); v # indirect doctest
|
|
853
|
+
2-adic valuation
|
|
854
|
+
|
|
855
|
+
TESTS::
|
|
856
|
+
|
|
857
|
+
sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron
|
|
858
|
+
"""
|
|
859
|
+
def __init__(self, parent):
|
|
860
|
+
"""
|
|
861
|
+
TESTS::
|
|
862
|
+
|
|
863
|
+
sage: from sage.rings.padics.padic_valuation import pAdicValuation_padic
|
|
864
|
+
sage: isinstance(Qp(2).valuation(), pAdicValuation_padic)
|
|
865
|
+
True
|
|
866
|
+
"""
|
|
867
|
+
pAdicValuation_base.__init__(self, parent, parent.domain().prime())
|
|
868
|
+
|
|
869
|
+
def reduce(self, x):
|
|
870
|
+
"""
|
|
871
|
+
Reduce ``x`` modulo the ideal of elements of positive valuation.
|
|
872
|
+
|
|
873
|
+
INPUT:
|
|
874
|
+
|
|
875
|
+
- ``x`` -- an element of the domain of this valuation
|
|
876
|
+
|
|
877
|
+
OUTPUT: an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`
|
|
878
|
+
|
|
879
|
+
EXAMPLES::
|
|
880
|
+
|
|
881
|
+
sage: R = Zp(3)
|
|
882
|
+
sage: Zp(3).valuation().reduce(R(4))
|
|
883
|
+
1
|
|
884
|
+
"""
|
|
885
|
+
x = self.domain().coerce(x)
|
|
886
|
+
return self.residue_field()(x.residue())
|
|
887
|
+
|
|
888
|
+
def lift(self, x):
|
|
889
|
+
"""
|
|
890
|
+
Lift ``x`` from the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field` to the domain of this
|
|
891
|
+
valuation.
|
|
892
|
+
|
|
893
|
+
INPUT:
|
|
894
|
+
|
|
895
|
+
- ``x`` -- an element of the residue field of this valuation
|
|
896
|
+
|
|
897
|
+
EXAMPLES::
|
|
898
|
+
|
|
899
|
+
sage: R = Zp(3)
|
|
900
|
+
sage: v = R.valuation()
|
|
901
|
+
sage: xbar = v.reduce(R(4))
|
|
902
|
+
sage: v.lift(xbar)
|
|
903
|
+
1 + O(3^20)
|
|
904
|
+
"""
|
|
905
|
+
x = self.residue_field().coerce(x)
|
|
906
|
+
return self.domain()(x).lift_to_precision()
|
|
907
|
+
|
|
908
|
+
def uniformizer(self):
|
|
909
|
+
"""
|
|
910
|
+
Return a uniformizer of this valuation.
|
|
911
|
+
|
|
912
|
+
EXAMPLES::
|
|
913
|
+
|
|
914
|
+
sage: v = Zp(3).valuation()
|
|
915
|
+
sage: v.uniformizer()
|
|
916
|
+
3 + O(3^21)
|
|
917
|
+
"""
|
|
918
|
+
return self.domain().uniformizer()
|
|
919
|
+
|
|
920
|
+
def element_with_valuation(self, v):
|
|
921
|
+
"""
|
|
922
|
+
Return an element of valuation ``v``.
|
|
923
|
+
|
|
924
|
+
INPUT:
|
|
925
|
+
|
|
926
|
+
- ``v`` -- an element of the :meth:`pAdicValuation_base.value_semigroup` of this valuation
|
|
927
|
+
|
|
928
|
+
EXAMPLES::
|
|
929
|
+
|
|
930
|
+
sage: R = Zp(3)
|
|
931
|
+
sage: v = R.valuation()
|
|
932
|
+
sage: v.element_with_valuation(3)
|
|
933
|
+
3^3 + O(3^23)
|
|
934
|
+
|
|
935
|
+
sage: # needs sage.libs.ntl
|
|
936
|
+
sage: K = Qp(3)
|
|
937
|
+
sage: R.<y> = K[]
|
|
938
|
+
sage: L.<y> = K.extension(y^2 + 3*y + 3)
|
|
939
|
+
sage: L.valuation().element_with_valuation(3/2)
|
|
940
|
+
y^3 + O(y^43)
|
|
941
|
+
"""
|
|
942
|
+
from sage.rings.integer_ring import ZZ
|
|
943
|
+
from sage.rings.rational_field import QQ
|
|
944
|
+
v = QQ(v)
|
|
945
|
+
if v not in self.value_semigroup():
|
|
946
|
+
raise ValueError("%r is not in the value semigroup of %r" % (v, self))
|
|
947
|
+
v = ZZ(v * self.domain().absolute_e())
|
|
948
|
+
return self.domain().one() << v
|
|
949
|
+
|
|
950
|
+
def _repr_(self):
|
|
951
|
+
"""
|
|
952
|
+
Return a printable representation of this valuation.
|
|
953
|
+
|
|
954
|
+
EXAMPLES::
|
|
955
|
+
|
|
956
|
+
sage: ZZ.valuation(3)._repr_()
|
|
957
|
+
'3-adic valuation'
|
|
958
|
+
"""
|
|
959
|
+
return "%s-adic valuation" % (self.p())
|
|
960
|
+
|
|
961
|
+
def _call_(self, x):
|
|
962
|
+
r"""
|
|
963
|
+
Evaluate this valuation at ``x``.
|
|
964
|
+
|
|
965
|
+
EXAMPLES::
|
|
966
|
+
|
|
967
|
+
sage: K = Qp(3)
|
|
968
|
+
sage: R.<y> = K[] # needs sage.libs.ntl
|
|
969
|
+
sage: L.<y> = K.extension(y^2 - 3) # needs sage.libs.ntl
|
|
970
|
+
sage: L.valuation()(3) # needs sage.libs.ntl
|
|
971
|
+
1
|
|
972
|
+
"""
|
|
973
|
+
return x.ordp()
|
|
974
|
+
|
|
975
|
+
def residue_ring(self):
|
|
976
|
+
r"""
|
|
977
|
+
Return the residue field of this valuation.
|
|
978
|
+
|
|
979
|
+
EXAMPLES::
|
|
980
|
+
|
|
981
|
+
sage: Qq(9, names='a').valuation().residue_ring() # needs sage.libs.ntl
|
|
982
|
+
Finite Field in a0 of size 3^2
|
|
983
|
+
"""
|
|
984
|
+
return self.domain().residue_field()
|
|
985
|
+
|
|
986
|
+
def shift(self, x, s):
|
|
987
|
+
r"""
|
|
988
|
+
Shift ``x`` in its expansion with respect to :meth:`uniformizer` by
|
|
989
|
+
``s`` "digits".
|
|
990
|
+
|
|
991
|
+
For nonnegative ``s``, this just returns ``x`` multiplied by a
|
|
992
|
+
power of the uniformizer `\pi`.
|
|
993
|
+
|
|
994
|
+
For negative ``s``, it does the same but when not over a field, it
|
|
995
|
+
drops coefficients in the `\pi`-adic expansion which have negative
|
|
996
|
+
valuation.
|
|
997
|
+
|
|
998
|
+
EXAMPLES::
|
|
999
|
+
|
|
1000
|
+
sage: R = ZpCA(2)
|
|
1001
|
+
sage: v = R.valuation()
|
|
1002
|
+
sage: v.shift(R.one(), 1)
|
|
1003
|
+
2 + O(2^20)
|
|
1004
|
+
sage: v.shift(R.one(), -1)
|
|
1005
|
+
O(2^19)
|
|
1006
|
+
|
|
1007
|
+
sage: # needs sage.libs.ntl sage.rings.padics
|
|
1008
|
+
sage: S.<y> = R[]
|
|
1009
|
+
sage: S.<y> = R.extension(y^3 - 2)
|
|
1010
|
+
sage: v = S.valuation()
|
|
1011
|
+
sage: v.shift(1, 5)
|
|
1012
|
+
y^5 + O(y^60)
|
|
1013
|
+
"""
|
|
1014
|
+
x = self.domain().coerce(x)
|
|
1015
|
+
s = self.value_group()(s)
|
|
1016
|
+
return x << s
|
|
1017
|
+
|
|
1018
|
+
def simplify(self, x, error=None, force=False):
|
|
1019
|
+
r"""
|
|
1020
|
+
Return a simplified version of ``x``.
|
|
1021
|
+
|
|
1022
|
+
Produce an element which differs from ``x`` by an element of
|
|
1023
|
+
valuation strictly greater than the valuation of ``x`` (or strictly
|
|
1024
|
+
greater than ``error`` if set.)
|
|
1025
|
+
|
|
1026
|
+
INPUT:
|
|
1027
|
+
|
|
1028
|
+
- ``x`` -- an element in the domain of this valuation
|
|
1029
|
+
|
|
1030
|
+
- ``error`` -- a rational, infinity, or ``None`` (default: ``None``),
|
|
1031
|
+
the error allowed to introduce through the simplification
|
|
1032
|
+
|
|
1033
|
+
- ``force`` -- ignored
|
|
1034
|
+
|
|
1035
|
+
EXAMPLES::
|
|
1036
|
+
|
|
1037
|
+
sage: R = Zp(2)
|
|
1038
|
+
sage: v = R.valuation()
|
|
1039
|
+
sage: v.simplify(6)
|
|
1040
|
+
2 + O(2^21)
|
|
1041
|
+
sage: v.simplify(6, error=0)
|
|
1042
|
+
0
|
|
1043
|
+
"""
|
|
1044
|
+
x = self.domain().coerce(x)
|
|
1045
|
+
|
|
1046
|
+
if error is None:
|
|
1047
|
+
error = self(x)
|
|
1048
|
+
from sage.rings.infinity import infinity
|
|
1049
|
+
if error is infinity:
|
|
1050
|
+
return x
|
|
1051
|
+
# we need to scale by the ramification index because p-adics use a
|
|
1052
|
+
# different normalization
|
|
1053
|
+
normalized_error = (error / self.value_group().gen()).ceil()
|
|
1054
|
+
return x.add_bigoh(normalized_error + 1).lift_to_precision()
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
class pAdicValuation_int(pAdicValuation_base):
|
|
1058
|
+
r"""
|
|
1059
|
+
A `p`-adic valuation on the integers or the rationals.
|
|
1060
|
+
|
|
1061
|
+
EXAMPLES::
|
|
1062
|
+
|
|
1063
|
+
sage: v = ZZ.valuation(3); v
|
|
1064
|
+
3-adic valuation
|
|
1065
|
+
|
|
1066
|
+
TESTS::
|
|
1067
|
+
|
|
1068
|
+
sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron
|
|
1069
|
+
"""
|
|
1070
|
+
def _repr_(self):
|
|
1071
|
+
"""
|
|
1072
|
+
Return a printable representation of this valuation.
|
|
1073
|
+
|
|
1074
|
+
EXAMPLES::
|
|
1075
|
+
|
|
1076
|
+
sage: ZZ.valuation(3)._repr_()
|
|
1077
|
+
'3-adic valuation'
|
|
1078
|
+
"""
|
|
1079
|
+
return "%s-adic valuation" % (self.p())
|
|
1080
|
+
|
|
1081
|
+
def _call_(self, x):
|
|
1082
|
+
"""
|
|
1083
|
+
Evaluate this valuation at ``x``.
|
|
1084
|
+
|
|
1085
|
+
INPUT:
|
|
1086
|
+
|
|
1087
|
+
- ``x`` -- an element in the domain of this valuation
|
|
1088
|
+
|
|
1089
|
+
EXAMPLES::
|
|
1090
|
+
|
|
1091
|
+
sage: ZZ.valuation(3)(9)
|
|
1092
|
+
2
|
|
1093
|
+
"""
|
|
1094
|
+
if x.is_zero():
|
|
1095
|
+
# x.valuation() is a factor 10 slower when computing the valuation
|
|
1096
|
+
# of a rational zero than when computing the valuation of another
|
|
1097
|
+
# small rational. Special casing this is a factor 100 faster.
|
|
1098
|
+
return infinity
|
|
1099
|
+
return x.valuation(self._p)
|
|
1100
|
+
|
|
1101
|
+
def uniformizer(self):
|
|
1102
|
+
"""
|
|
1103
|
+
Return a uniformizer of this `p`-adic valuation, i.e., `p` as an
|
|
1104
|
+
element of the domain.
|
|
1105
|
+
|
|
1106
|
+
EXAMPLES::
|
|
1107
|
+
|
|
1108
|
+
sage: v = ZZ.valuation(3)
|
|
1109
|
+
sage: v.uniformizer()
|
|
1110
|
+
3
|
|
1111
|
+
"""
|
|
1112
|
+
return self.domain()(self.p())
|
|
1113
|
+
|
|
1114
|
+
def residue_ring(self):
|
|
1115
|
+
"""
|
|
1116
|
+
Return the residue field of this valuation.
|
|
1117
|
+
|
|
1118
|
+
EXAMPLES::
|
|
1119
|
+
|
|
1120
|
+
sage: v = ZZ.valuation(3)
|
|
1121
|
+
sage: v.residue_ring()
|
|
1122
|
+
Finite Field of size 3
|
|
1123
|
+
"""
|
|
1124
|
+
from sage.rings.finite_rings.finite_field_constructor import GF
|
|
1125
|
+
return GF(self.p())
|
|
1126
|
+
|
|
1127
|
+
def _ge_(self, other):
|
|
1128
|
+
r"""
|
|
1129
|
+
Return whether this valuation is greater than or equal than ``other``
|
|
1130
|
+
everywhere.
|
|
1131
|
+
|
|
1132
|
+
EXAMPLES::
|
|
1133
|
+
|
|
1134
|
+
sage: v = ZZ.valuation(2)
|
|
1135
|
+
sage: w = valuations.TrivialValuation(ZZ)
|
|
1136
|
+
sage: v >= w
|
|
1137
|
+
True
|
|
1138
|
+
"""
|
|
1139
|
+
if other.is_trivial():
|
|
1140
|
+
return other.is_discrete_valuation()
|
|
1141
|
+
if isinstance(other, pAdicValuation_int):
|
|
1142
|
+
return self.p() == other.p()
|
|
1143
|
+
return super(pAdicValuation_base, self)._ge_(other)
|
|
1144
|
+
|
|
1145
|
+
def _relative_size(self, x):
|
|
1146
|
+
r"""
|
|
1147
|
+
Return an estimate on the coefficient size of ``x``.
|
|
1148
|
+
|
|
1149
|
+
The number returned is an estimate on the factor between the number of
|
|
1150
|
+
bits used by ``x`` and the minimal number of bits used by an element
|
|
1151
|
+
congruent to ``x``.
|
|
1152
|
+
|
|
1153
|
+
This is used by :meth:`simplify` to decide whether simplification of
|
|
1154
|
+
coefficients is going to lead to a significant shrinking of the
|
|
1155
|
+
coefficients of ``x``.
|
|
1156
|
+
|
|
1157
|
+
EXAMPLES::
|
|
1158
|
+
|
|
1159
|
+
sage: v = ZZ.valuation(2)
|
|
1160
|
+
sage: v._relative_size(2)
|
|
1161
|
+
1
|
|
1162
|
+
sage: v._relative_size(2**20)
|
|
1163
|
+
11
|
|
1164
|
+
"""
|
|
1165
|
+
x = self.domain().coerce(x)
|
|
1166
|
+
return (x.numerator().nbits() + x.denominator().nbits())//self.p().nbits()
|
|
1167
|
+
|
|
1168
|
+
def simplify(self, x, error=None, force=False, size_heuristic_bound=32):
|
|
1169
|
+
r"""
|
|
1170
|
+
Return a simplified version of ``x``.
|
|
1171
|
+
|
|
1172
|
+
Produce an element which differs from ``x`` by an element of
|
|
1173
|
+
valuation strictly greater than the valuation of ``x`` (or strictly
|
|
1174
|
+
greater than ``error`` if set.)
|
|
1175
|
+
|
|
1176
|
+
INPUT:
|
|
1177
|
+
|
|
1178
|
+
- ``x`` -- an element in the domain of this valuation
|
|
1179
|
+
|
|
1180
|
+
- ``error`` -- a rational, infinity, or ``None`` (default: ``None``),
|
|
1181
|
+
the error allowed to introduce through the simplification
|
|
1182
|
+
|
|
1183
|
+
- ``force`` -- ignored
|
|
1184
|
+
|
|
1185
|
+
- ``size_heuristic_bound`` -- when ``force`` is not set, the expected
|
|
1186
|
+
factor by which the ``x`` need to shrink to perform an actual
|
|
1187
|
+
simplification (default: 32)
|
|
1188
|
+
|
|
1189
|
+
EXAMPLES::
|
|
1190
|
+
|
|
1191
|
+
sage: v = ZZ.valuation(2)
|
|
1192
|
+
sage: v.simplify(6, force=True)
|
|
1193
|
+
2
|
|
1194
|
+
sage: v.simplify(6, error=0, force=True)
|
|
1195
|
+
0
|
|
1196
|
+
|
|
1197
|
+
In this example, the usual rational reconstruction misses a good answer
|
|
1198
|
+
for some moduli (because the absolute value of the numerator is not
|
|
1199
|
+
bounded by the square root of the modulus)::
|
|
1200
|
+
|
|
1201
|
+
sage: v = QQ.valuation(2)
|
|
1202
|
+
sage: v.simplify(110406, error=16, force=True)
|
|
1203
|
+
562/19
|
|
1204
|
+
sage: Qp(2, 16)(110406).rational_reconstruction()
|
|
1205
|
+
Traceback (most recent call last):
|
|
1206
|
+
...
|
|
1207
|
+
ArithmeticError: rational reconstruction of 55203 (mod 65536) does not exist
|
|
1208
|
+
"""
|
|
1209
|
+
if not force and self._relative_size(x) <= size_heuristic_bound:
|
|
1210
|
+
return x
|
|
1211
|
+
|
|
1212
|
+
x = self.domain().coerce(x)
|
|
1213
|
+
|
|
1214
|
+
v = self(x)
|
|
1215
|
+
if error is None:
|
|
1216
|
+
error = v
|
|
1217
|
+
from sage.rings.infinity import infinity
|
|
1218
|
+
if error is infinity:
|
|
1219
|
+
return x
|
|
1220
|
+
if error < v:
|
|
1221
|
+
return self.domain().zero()
|
|
1222
|
+
|
|
1223
|
+
from sage.rings.rational_field import QQ
|
|
1224
|
+
from sage.rings.padics.factory import Qp
|
|
1225
|
+
precision_ring = Qp(self.p(), QQ(error).floor() + 1 - v)
|
|
1226
|
+
reduced = precision_ring(x)
|
|
1227
|
+
lift = (reduced >> v).lift()
|
|
1228
|
+
best = self.domain()(lift) * self.p()**v
|
|
1229
|
+
|
|
1230
|
+
if self._relative_size(x) < self._relative_size(best):
|
|
1231
|
+
best = x
|
|
1232
|
+
|
|
1233
|
+
# We implement a modified version of the usual rational reconstruction
|
|
1234
|
+
# algorithm (based on the extended Euclidean algorithm) here. We do not
|
|
1235
|
+
# get the uniqueness properties but we do not need them actually.
|
|
1236
|
+
# This is certainly slower than the implementation in Cython.
|
|
1237
|
+
from sage.categories.fields import Fields
|
|
1238
|
+
m = self.p()**(QQ(error).floor() + 1 - v)
|
|
1239
|
+
if self.domain() in Fields():
|
|
1240
|
+
r = (m, lift)
|
|
1241
|
+
s = (0, 1)
|
|
1242
|
+
while r[1]:
|
|
1243
|
+
qq, rr = r[0].quo_rem(r[1])
|
|
1244
|
+
r = r[1], rr
|
|
1245
|
+
s = s[1], s[0] - qq*s[1]
|
|
1246
|
+
from sage.arith.misc import GCD as gcd
|
|
1247
|
+
if s[1] != 0 and gcd(s[1], r[1]) == 1:
|
|
1248
|
+
rational = self.domain()(r[1]) / self.domain()(s[1]) * self.p()**v
|
|
1249
|
+
if self._relative_size(rational) < self._relative_size(best):
|
|
1250
|
+
best = rational
|
|
1251
|
+
|
|
1252
|
+
assert (self(x-best) > error)
|
|
1253
|
+
|
|
1254
|
+
return best
|
|
1255
|
+
|
|
1256
|
+
def inverse(self, x, precision):
|
|
1257
|
+
r"""
|
|
1258
|
+
Return an approximate inverse of ``x``.
|
|
1259
|
+
|
|
1260
|
+
The element returned is such that the product differs from 1 by an
|
|
1261
|
+
element of valuation at least ``precision``.
|
|
1262
|
+
|
|
1263
|
+
INPUT:
|
|
1264
|
+
|
|
1265
|
+
- ``x`` -- an element in the domain of this valuation
|
|
1266
|
+
|
|
1267
|
+
- ``precision`` -- a rational or infinity
|
|
1268
|
+
|
|
1269
|
+
EXAMPLES::
|
|
1270
|
+
|
|
1271
|
+
sage: v = ZZ.valuation(2)
|
|
1272
|
+
sage: x = 3
|
|
1273
|
+
sage: y = v.inverse(3, 2); y
|
|
1274
|
+
3
|
|
1275
|
+
sage: x*y - 1
|
|
1276
|
+
8
|
|
1277
|
+
|
|
1278
|
+
This might not be possible for elements of positive valuation::
|
|
1279
|
+
|
|
1280
|
+
sage: v.inverse(2, 2)
|
|
1281
|
+
Traceback (most recent call last):
|
|
1282
|
+
...
|
|
1283
|
+
ValueError: element has no approximate inverse in this ring
|
|
1284
|
+
|
|
1285
|
+
Unless the precision is very small::
|
|
1286
|
+
|
|
1287
|
+
sage: v.inverse(2, 0)
|
|
1288
|
+
1
|
|
1289
|
+
"""
|
|
1290
|
+
if not x.is_zero():
|
|
1291
|
+
y = ~x
|
|
1292
|
+
if y in self.domain():
|
|
1293
|
+
return self.domain()(y)
|
|
1294
|
+
if precision <= 0:
|
|
1295
|
+
return self.domain().one()
|
|
1296
|
+
|
|
1297
|
+
from sage.rings.infinity import infinity
|
|
1298
|
+
if self(x) > 0 or precision is infinity:
|
|
1299
|
+
raise ValueError("element has no approximate inverse in this ring")
|
|
1300
|
+
|
|
1301
|
+
from sage.rings.integer_ring import ZZ
|
|
1302
|
+
from sage.rings.rational_field import QQ
|
|
1303
|
+
return self.domain()(ZZ(x).inverse_mod(self.p() ** QQ(precision).ceil()))
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
class pAdicFromLimitValuation(FiniteExtensionFromLimitValuation, pAdicValuation_base):
|
|
1307
|
+
r"""
|
|
1308
|
+
A `p`-adic valuation on a number field or a subring thereof, i.e., a
|
|
1309
|
+
valuation that extends the `p`-adic valuation on the integers.
|
|
1310
|
+
|
|
1311
|
+
EXAMPLES::
|
|
1312
|
+
|
|
1313
|
+
sage: v = GaussianIntegers().valuation(3); v # needs sage.rings.number_field
|
|
1314
|
+
3-adic valuation
|
|
1315
|
+
|
|
1316
|
+
TESTS::
|
|
1317
|
+
|
|
1318
|
+
sage: TestSuite(v).run(skip='_test_shift') # long time # needs sage.rings.number_field
|
|
1319
|
+
|
|
1320
|
+
The ``_test_shift`` test fails because the parent of the shift is
|
|
1321
|
+
incorrect, see :issue:`23971`::
|
|
1322
|
+
|
|
1323
|
+
sage: v.shift(1, -1).parent() # needs sage.rings.number_field
|
|
1324
|
+
Number Field in I with defining polynomial x^2 + 1 with I = 1*I
|
|
1325
|
+
"""
|
|
1326
|
+
def __init__(self, parent, approximant, G, approximants):
|
|
1327
|
+
r"""
|
|
1328
|
+
TESTS::
|
|
1329
|
+
|
|
1330
|
+
sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
|
|
1331
|
+
sage: from sage.rings.padics.padic_valuation import pAdicFromLimitValuation
|
|
1332
|
+
sage: isinstance(v, pAdicFromLimitValuation) # needs sage.rings.number_field
|
|
1333
|
+
True
|
|
1334
|
+
"""
|
|
1335
|
+
FiniteExtensionFromLimitValuation.__init__(self, parent, approximant, G, approximants)
|
|
1336
|
+
pAdicValuation_base.__init__(self, parent, approximant.restriction(approximant.domain().base_ring()).p())
|
|
1337
|
+
|
|
1338
|
+
def _to_base_domain(self, f):
|
|
1339
|
+
r"""
|
|
1340
|
+
Return ``f``, an element of the underlying limit valuation, as an
|
|
1341
|
+
element of the domain of this valuation.
|
|
1342
|
+
|
|
1343
|
+
EXAMPLES::
|
|
1344
|
+
|
|
1345
|
+
sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
|
|
1346
|
+
sage: I = GaussianIntegers().fraction_field().gen() # needs sage.rings.number_field
|
|
1347
|
+
sage: v._to_base_domain(I) # needs sage.rings.number_field
|
|
1348
|
+
x
|
|
1349
|
+
|
|
1350
|
+
TESTS:
|
|
1351
|
+
|
|
1352
|
+
Check that this also works for relative extensions::
|
|
1353
|
+
|
|
1354
|
+
sage: # needs sage.rings.number_field
|
|
1355
|
+
sage: v = QQ.valuation(2)
|
|
1356
|
+
sage: x = polygen(ZZ, 'x')
|
|
1357
|
+
sage: L.<a> = NumberField(x^2 + 2)
|
|
1358
|
+
sage: M.<b> = L.extension(x^2 + 1)
|
|
1359
|
+
sage: w = v.extension(L).extension(M) # needs sage.geometry.polyhedron
|
|
1360
|
+
sage: w._to_base_domain(b) # needs sage.geometry.polyhedron
|
|
1361
|
+
x
|
|
1362
|
+
"""
|
|
1363
|
+
polynomial = f.lift()
|
|
1364
|
+
return polynomial(self._base_valuation.domain().gen())
|
|
1365
|
+
|
|
1366
|
+
def _from_base_domain(self, f):
|
|
1367
|
+
r"""
|
|
1368
|
+
Return ``f``, an element of the domain of this valuation, as an element
|
|
1369
|
+
of the domain of the underlying limit valuation.
|
|
1370
|
+
|
|
1371
|
+
EXAMPLES::
|
|
1372
|
+
|
|
1373
|
+
sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
|
|
1374
|
+
sage: v._from_base_domain(v._base_valuation.domain().gen()) # needs sage.rings.number_field
|
|
1375
|
+
I
|
|
1376
|
+
"""
|
|
1377
|
+
return self.domain()(f)
|
|
1378
|
+
|
|
1379
|
+
def extensions(self, ring):
|
|
1380
|
+
r"""
|
|
1381
|
+
Return the extensions of this valuation to ``ring``.
|
|
1382
|
+
|
|
1383
|
+
EXAMPLES::
|
|
1384
|
+
|
|
1385
|
+
sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
|
|
1386
|
+
sage: v.extensions(v.domain().fraction_field()) # needs sage.rings.number_field
|
|
1387
|
+
[3-adic valuation]
|
|
1388
|
+
"""
|
|
1389
|
+
if ring is self.domain().fraction_field():
|
|
1390
|
+
if self.domain() is not self.domain().fraction_field():
|
|
1391
|
+
G = ring.relative_polynomial()
|
|
1392
|
+
approximant = self._base_valuation.change_domain(G.parent())._initial_approximation
|
|
1393
|
+
return [pAdicValuation(ring, approximant)]
|
|
1394
|
+
return super().extensions(ring)
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
def _fraction_field(ring):
|
|
1398
|
+
r"""
|
|
1399
|
+
Return a fraction field of ``ring``.
|
|
1400
|
+
|
|
1401
|
+
EXAMPLES:
|
|
1402
|
+
|
|
1403
|
+
This works around some annoyances with ``ring.fraction_field()``::
|
|
1404
|
+
|
|
1405
|
+
sage: R.<x> = ZZ[]
|
|
1406
|
+
sage: S = R.quo(x^2 + 1)
|
|
1407
|
+
sage: S.fraction_field()
|
|
1408
|
+
Fraction Field of Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1
|
|
1409
|
+
|
|
1410
|
+
sage: from sage.rings.padics.padic_valuation import _fraction_field
|
|
1411
|
+
sage: _fraction_field(S)
|
|
1412
|
+
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1
|
|
1413
|
+
"""
|
|
1414
|
+
from sage.categories.fields import Fields
|
|
1415
|
+
if ring in Fields():
|
|
1416
|
+
return ring
|
|
1417
|
+
|
|
1418
|
+
from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
|
|
1419
|
+
if isinstance(ring, PolynomialQuotientRing_generic):
|
|
1420
|
+
from sage.categories.integral_domains import IntegralDomains
|
|
1421
|
+
if ring in IntegralDomains():
|
|
1422
|
+
return ring.base().change_ring(ring.base_ring().fraction_field()).quo(ring.modulus())
|
|
1423
|
+
return ring.fraction_field()
|