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,1450 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
r"""
|
|
3
|
+
Discrete valuations on function fields
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- Julian Rüth (2016-10-16): initial version
|
|
8
|
+
|
|
9
|
+
EXAMPLES:
|
|
10
|
+
|
|
11
|
+
We can create classical valuations that correspond to finite and infinite
|
|
12
|
+
places on a rational function field::
|
|
13
|
+
|
|
14
|
+
sage: K.<x> = FunctionField(QQ)
|
|
15
|
+
sage: v = K.valuation(1); v
|
|
16
|
+
(x - 1)-adic valuation
|
|
17
|
+
sage: v = K.valuation(x^2 + 1); v
|
|
18
|
+
(x^2 + 1)-adic valuation
|
|
19
|
+
sage: v = K.valuation(1/x); v
|
|
20
|
+
Valuation at the infinite place
|
|
21
|
+
|
|
22
|
+
Note that we can also specify valuations which do not correspond to a place of
|
|
23
|
+
the function field::
|
|
24
|
+
|
|
25
|
+
sage: R.<x> = QQ[]
|
|
26
|
+
sage: w = valuations.GaussValuation(R, QQ.valuation(2))
|
|
27
|
+
sage: v = K.valuation(w); v
|
|
28
|
+
2-adic valuation
|
|
29
|
+
|
|
30
|
+
Valuations on a rational function field can then be extended to finite
|
|
31
|
+
extensions::
|
|
32
|
+
|
|
33
|
+
sage: v = K.valuation(x - 1); v
|
|
34
|
+
(x - 1)-adic valuation
|
|
35
|
+
sage: R.<y> = K[]
|
|
36
|
+
sage: L.<y> = K.extension(y^2 - x) # needs sage.rings.function_field
|
|
37
|
+
sage: w = v.extensions(L); w # needs sage.geometry.polyhedron sage.rings.function_field
|
|
38
|
+
[[ (x - 1)-adic valuation, v(y + 1) = 1 ]-adic valuation,
|
|
39
|
+
[ (x - 1)-adic valuation, v(y - 1) = 1 ]-adic valuation]
|
|
40
|
+
|
|
41
|
+
TESTS:
|
|
42
|
+
|
|
43
|
+
Run test suite for classical places over rational function fields::
|
|
44
|
+
|
|
45
|
+
sage: K.<x> = FunctionField(QQ)
|
|
46
|
+
sage: v = K.valuation(1)
|
|
47
|
+
sage: TestSuite(v).run(max_runs=100) # long time
|
|
48
|
+
|
|
49
|
+
sage: v = K.valuation(x^2 + 1)
|
|
50
|
+
sage: TestSuite(v).run(max_runs=100) # long time
|
|
51
|
+
|
|
52
|
+
sage: v = K.valuation(1/x)
|
|
53
|
+
sage: TestSuite(v).run(max_runs=100) # long time
|
|
54
|
+
|
|
55
|
+
Run test suite over classical places of finite extensions::
|
|
56
|
+
|
|
57
|
+
sage: K.<x> = FunctionField(QQ)
|
|
58
|
+
sage: v = K.valuation(x - 1)
|
|
59
|
+
sage: R.<y> = K[]
|
|
60
|
+
sage: L.<y> = K.extension(y^2 - x) # needs sage.rings.function_field
|
|
61
|
+
sage: ws = v.extensions(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
62
|
+
sage: for w in ws: TestSuite(w).run(max_runs=100) # long time # needs sage.geometry.polyhedron sage.rings.function_field
|
|
63
|
+
|
|
64
|
+
Run test suite for valuations that do not correspond to a classical place::
|
|
65
|
+
|
|
66
|
+
sage: K.<x> = FunctionField(QQ)
|
|
67
|
+
sage: R.<x> = QQ[]
|
|
68
|
+
sage: v = GaussValuation(R, QQ.valuation(2))
|
|
69
|
+
sage: w = K.valuation(v)
|
|
70
|
+
sage: TestSuite(w).run() # long time
|
|
71
|
+
|
|
72
|
+
Run test suite for a non-classical valuation that does not correspond to an
|
|
73
|
+
affinoid contained in the unit disk::
|
|
74
|
+
|
|
75
|
+
sage: w = K.valuation((w, K.hom(K.gen()/2), K.hom(2*K.gen()))); w
|
|
76
|
+
2-adic valuation (in Rational function field in x over Rational Field after x |--> 1/2*x)
|
|
77
|
+
sage: TestSuite(w).run() # long time
|
|
78
|
+
|
|
79
|
+
Run test suite for some other classical places over large ground fields::
|
|
80
|
+
|
|
81
|
+
sage: K.<t> = FunctionField(GF(3))
|
|
82
|
+
sage: M.<x> = FunctionField(K)
|
|
83
|
+
sage: v = M.valuation(x^3 - t)
|
|
84
|
+
sage: TestSuite(v).run(max_runs=10) # long time
|
|
85
|
+
|
|
86
|
+
Run test suite for extensions over the infinite place::
|
|
87
|
+
|
|
88
|
+
sage: K.<x> = FunctionField(QQ)
|
|
89
|
+
sage: v = K.valuation(1/x)
|
|
90
|
+
sage: R.<y> = K[]
|
|
91
|
+
sage: L.<y> = K.extension(y^2 - 1/(x^2 + 1)) # needs sage.rings.function_field
|
|
92
|
+
sage: w = v.extensions(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
93
|
+
sage: TestSuite(w).run() # long time # needs sage.geometry.polyhedron sage.rings.function_field
|
|
94
|
+
|
|
95
|
+
Run test suite for a valuation with `v(1/x) > 0` which does not come from a
|
|
96
|
+
classical valuation of the infinite place::
|
|
97
|
+
|
|
98
|
+
sage: K.<x> = FunctionField(QQ)
|
|
99
|
+
sage: R.<x> = QQ[]
|
|
100
|
+
sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1)
|
|
101
|
+
sage: w = K.valuation(w)
|
|
102
|
+
sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()])))
|
|
103
|
+
sage: TestSuite(v).run() # long time
|
|
104
|
+
|
|
105
|
+
Run test suite for extensions which come from the splitting in the base field::
|
|
106
|
+
|
|
107
|
+
sage: K.<x> = FunctionField(QQ)
|
|
108
|
+
sage: v = K.valuation(x^2 + 1)
|
|
109
|
+
sage: L.<x> = FunctionField(GaussianIntegers().fraction_field())
|
|
110
|
+
sage: ws = v.extensions(L) # needs sage.rings.function_field
|
|
111
|
+
sage: for w in ws: TestSuite(w).run(max_runs=100) # long time # needs sage.rings.function_field
|
|
112
|
+
|
|
113
|
+
Run test suite for a finite place with residual degree and ramification::
|
|
114
|
+
|
|
115
|
+
sage: K.<t> = FunctionField(GF(3))
|
|
116
|
+
sage: L.<x> = FunctionField(K)
|
|
117
|
+
sage: v = L.valuation(x^6 - t)
|
|
118
|
+
sage: TestSuite(v).run(max_runs=10) # long time
|
|
119
|
+
|
|
120
|
+
Run test suite for a valuation which is backed by limit valuation::
|
|
121
|
+
|
|
122
|
+
sage: K.<x> = FunctionField(QQ)
|
|
123
|
+
sage: R.<y> = K[]
|
|
124
|
+
sage: L.<y> = K.extension(y^2 - (x^2 + x + 1))
|
|
125
|
+
sage: v = K.valuation(x - 1)
|
|
126
|
+
sage: w = v.extension(L) # needs sage.rings.function_field
|
|
127
|
+
sage: TestSuite(w).run() # long time # needs sage.rings.function_field
|
|
128
|
+
|
|
129
|
+
Run test suite for a valuation which sends an element to `-\infty`::
|
|
130
|
+
|
|
131
|
+
sage: R.<x> = QQ[]
|
|
132
|
+
sage: v = GaussValuation(QQ['x'], QQ.valuation(2)).augmentation(x, infinity)
|
|
133
|
+
sage: K.<x> = FunctionField(QQ)
|
|
134
|
+
sage: w = K.valuation(v)
|
|
135
|
+
sage: TestSuite(w).run() # long time
|
|
136
|
+
|
|
137
|
+
REFERENCES:
|
|
138
|
+
|
|
139
|
+
An overview of some computational tools relating to valuations on function
|
|
140
|
+
fields can be found in Section 4.6 of [Rüt2014]_. Most of this was originally
|
|
141
|
+
developed for number fields in [Mac1936I]_ and [Mac1936II]_.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
# ****************************************************************************
|
|
145
|
+
# Copyright (C) 2016-2018 Julian Rüth <julian.rueth@fsfe.org>
|
|
146
|
+
#
|
|
147
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
148
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
149
|
+
# the License, or (at your option) any later version.
|
|
150
|
+
# https://www.gnu.org/licenses/
|
|
151
|
+
# ****************************************************************************
|
|
152
|
+
|
|
153
|
+
from sage.structure.factory import UniqueFactory
|
|
154
|
+
from sage.rings.rational_field import QQ
|
|
155
|
+
from sage.misc.cachefunc import cached_method
|
|
156
|
+
|
|
157
|
+
from sage.rings.valuation.valuation import DiscreteValuation, DiscretePseudoValuation, InfiniteDiscretePseudoValuation, NegativeInfiniteDiscretePseudoValuation
|
|
158
|
+
from sage.rings.valuation.trivial_valuation import TrivialValuation
|
|
159
|
+
from sage.rings.valuation.mapped_valuation import FiniteExtensionFromLimitValuation, MappedValuation_base
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class FunctionFieldValuationFactory(UniqueFactory):
|
|
163
|
+
r"""
|
|
164
|
+
Create a valuation on ``domain`` corresponding to ``prime``.
|
|
165
|
+
|
|
166
|
+
INPUT:
|
|
167
|
+
|
|
168
|
+
- ``domain`` -- a function field
|
|
169
|
+
|
|
170
|
+
- ``prime`` -- a place of the function field, a valuation on a subring, or
|
|
171
|
+
a valuation on another function field together with information for
|
|
172
|
+
isomorphisms to and from that function field
|
|
173
|
+
|
|
174
|
+
EXAMPLES::
|
|
175
|
+
|
|
176
|
+
sage: K.<x> = FunctionField(QQ)
|
|
177
|
+
sage: v = K.valuation(1); v # indirect doctest
|
|
178
|
+
(x - 1)-adic valuation
|
|
179
|
+
sage: v(x)
|
|
180
|
+
0
|
|
181
|
+
sage: v(x - 1)
|
|
182
|
+
1
|
|
183
|
+
|
|
184
|
+
See :meth:`sage.rings.function_field.function_field.FunctionField.valuation` for further examples.
|
|
185
|
+
"""
|
|
186
|
+
def create_key_and_extra_args(self, domain, prime):
|
|
187
|
+
r"""
|
|
188
|
+
Create a unique key which identifies the valuation given by ``prime``
|
|
189
|
+
on ``domain``.
|
|
190
|
+
|
|
191
|
+
TESTS:
|
|
192
|
+
|
|
193
|
+
We specify a valuation on a function field by two different means and
|
|
194
|
+
get the same object::
|
|
195
|
+
|
|
196
|
+
sage: K.<x> = FunctionField(QQ)
|
|
197
|
+
sage: v = K.valuation(x - 1) # indirect doctest
|
|
198
|
+
|
|
199
|
+
sage: R.<x> = QQ[]
|
|
200
|
+
sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1)
|
|
201
|
+
sage: K.valuation(w) is v
|
|
202
|
+
True
|
|
203
|
+
|
|
204
|
+
The normalization is, however, not smart enough, to unwrap
|
|
205
|
+
substitutions that turn out to be trivial::
|
|
206
|
+
|
|
207
|
+
sage: w = GaussValuation(R, QQ.valuation(2))
|
|
208
|
+
sage: w = K.valuation(w)
|
|
209
|
+
sage: w is K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()])))
|
|
210
|
+
False
|
|
211
|
+
"""
|
|
212
|
+
from sage.categories.function_fields import FunctionFields
|
|
213
|
+
if domain not in FunctionFields():
|
|
214
|
+
raise ValueError("Domain must be a function field.")
|
|
215
|
+
|
|
216
|
+
if isinstance(prime, tuple):
|
|
217
|
+
if len(prime) == 3:
|
|
218
|
+
# prime is a triple of a valuation on another function field with
|
|
219
|
+
# isomorphism information
|
|
220
|
+
return self.create_key_and_extra_args_from_valuation_on_isomorphic_field(domain, prime[0], prime[1], prime[2])
|
|
221
|
+
|
|
222
|
+
from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
|
|
223
|
+
if prime.parent() is DiscretePseudoValuationSpace(domain):
|
|
224
|
+
# prime is already a valuation of the requested domain
|
|
225
|
+
# if we returned (domain, prime), we would break caching
|
|
226
|
+
# because this element has been created from a different key
|
|
227
|
+
# Instead, we return the key that was used to create prime
|
|
228
|
+
# so the caller gets back a correctly cached version of prime
|
|
229
|
+
if not hasattr(prime, "_factory_data"):
|
|
230
|
+
raise NotImplementedError("Valuations on function fields must be unique and come out of the FunctionFieldValuation factory but %r has been created by other means" % (prime,))
|
|
231
|
+
return prime._factory_data[2], {}
|
|
232
|
+
|
|
233
|
+
if prime in domain:
|
|
234
|
+
# prime defines a place
|
|
235
|
+
return self.create_key_and_extra_args_from_place(domain, prime)
|
|
236
|
+
if prime.parent() is DiscretePseudoValuationSpace(domain._ring):
|
|
237
|
+
# prime is a discrete (pseudo-)valuation on the polynomial ring
|
|
238
|
+
# that the domain is constructed from
|
|
239
|
+
return self.create_key_and_extra_args_from_valuation(domain, prime)
|
|
240
|
+
if domain.base_field() is not domain:
|
|
241
|
+
# prime might define a valuation on a subring of domain and have a
|
|
242
|
+
# unique extension to domain
|
|
243
|
+
base_valuation = domain.base_field().valuation(prime)
|
|
244
|
+
return self.create_key_and_extra_args_from_valuation(domain, base_valuation)
|
|
245
|
+
from sage.rings.ideal import Ideal_generic
|
|
246
|
+
if isinstance(prime, Ideal_generic):
|
|
247
|
+
raise NotImplementedError("a place cannot be given by an ideal yet")
|
|
248
|
+
|
|
249
|
+
raise NotImplementedError("argument must be a place or a pseudo-valuation on a supported subring but %r does not satisfy this for the domain %r" % (prime, domain))
|
|
250
|
+
|
|
251
|
+
def create_key_and_extra_args_from_place(self, domain, generator):
|
|
252
|
+
r"""
|
|
253
|
+
Create a unique key which identifies the valuation at the place
|
|
254
|
+
specified by ``generator``.
|
|
255
|
+
|
|
256
|
+
TESTS:
|
|
257
|
+
|
|
258
|
+
sage: K.<x> = FunctionField(QQ)
|
|
259
|
+
sage: v = K.valuation(1/x) # indirect doctest
|
|
260
|
+
"""
|
|
261
|
+
if generator not in domain.base_field():
|
|
262
|
+
raise NotImplementedError("a place must be defined over a rational function field")
|
|
263
|
+
|
|
264
|
+
if domain.base_field() is not domain:
|
|
265
|
+
# if this is an extension field, construct the unique place over
|
|
266
|
+
# the place on the subfield
|
|
267
|
+
return self.create_key_and_extra_args(domain, domain.base_field().valuation(generator))
|
|
268
|
+
|
|
269
|
+
if generator in domain.constant_base_field():
|
|
270
|
+
# generator is a constant, we associate to it the place which
|
|
271
|
+
# corresponds to the polynomial (x - generator)
|
|
272
|
+
return self.create_key_and_extra_args(domain, domain.gen() - generator)
|
|
273
|
+
|
|
274
|
+
if generator in domain._ring:
|
|
275
|
+
# generator is a polynomial
|
|
276
|
+
generator = domain._ring(generator)
|
|
277
|
+
if not generator.is_monic():
|
|
278
|
+
raise ValueError("place must be defined by a monic polynomial but %r is not monic" % (generator,))
|
|
279
|
+
if not generator.is_irreducible():
|
|
280
|
+
raise ValueError("place must be defined by an irreducible polynomial but %r factors over %r" % (generator, domain._ring))
|
|
281
|
+
# we construct the corresponding valuation on the polynomial ring
|
|
282
|
+
# with v(generator) = 1
|
|
283
|
+
from sage.rings.valuation.gauss_valuation import GaussValuation
|
|
284
|
+
valuation = GaussValuation(domain._ring, TrivialValuation(domain.constant_base_field())).augmentation(generator, 1)
|
|
285
|
+
return self.create_key_and_extra_args(domain, valuation)
|
|
286
|
+
elif generator == ~domain.gen():
|
|
287
|
+
# generator is 1/x, the infinite place
|
|
288
|
+
return (domain, (domain.valuation(domain.gen()), domain.hom(~domain.gen()), domain.hom(~domain.gen()))), {}
|
|
289
|
+
else:
|
|
290
|
+
raise ValueError("a place must be given by an irreducible polynomial or the inverse of the generator; %r does not define a place over %r" % (generator, domain))
|
|
291
|
+
|
|
292
|
+
def create_key_and_extra_args_from_valuation(self, domain, valuation):
|
|
293
|
+
r"""
|
|
294
|
+
Create a unique key which identifies the valuation which extends
|
|
295
|
+
``valuation``.
|
|
296
|
+
|
|
297
|
+
TESTS:
|
|
298
|
+
|
|
299
|
+
sage: K.<x> = FunctionField(QQ)
|
|
300
|
+
sage: R.<x> = QQ[]
|
|
301
|
+
sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1)
|
|
302
|
+
sage: v = K.valuation(w) # indirect doctest
|
|
303
|
+
|
|
304
|
+
Check that :issue:`25294` has been resolved::
|
|
305
|
+
|
|
306
|
+
sage: K.<x> = FunctionField(QQ)
|
|
307
|
+
sage: R.<y> = K[]
|
|
308
|
+
sage: L.<y> = K.extension(y^3 + 1/x^3*y + 2/x^4) # needs sage.rings.function_field
|
|
309
|
+
sage: v = K.valuation(x) # needs sage.rings.function_field
|
|
310
|
+
sage: v.extensions(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
311
|
+
[[ (x)-adic valuation, v(y) = 1 ]-adic valuation
|
|
312
|
+
(in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y),
|
|
313
|
+
[ (x)-adic valuation, v(y) = 1/2 ]-adic valuation
|
|
314
|
+
(in Function field in y defined by y^3 + x*y + 2*x^2 after y |--> 1/x^2*y)]
|
|
315
|
+
"""
|
|
316
|
+
# this should have been handled by create_key already
|
|
317
|
+
assert valuation.domain() is not domain
|
|
318
|
+
|
|
319
|
+
if valuation.domain() is domain._ring:
|
|
320
|
+
if domain.base_field() is not domain:
|
|
321
|
+
vK = valuation.restriction(valuation.domain().base_ring())
|
|
322
|
+
if vK.domain() is not domain.base_field():
|
|
323
|
+
raise ValueError("valuation must extend a valuation on the base field but %r extends %r whose domain is not %r" % (valuation, vK, domain.base_field()))
|
|
324
|
+
# Valuation is an approximant that describes a single valuation
|
|
325
|
+
# on domain.
|
|
326
|
+
# For uniqueness of valuations (which provides better caching
|
|
327
|
+
# and easier pickling) we need to find a normal form of
|
|
328
|
+
# valuation, i.e., the smallest approximant that describes this
|
|
329
|
+
# valuation
|
|
330
|
+
approximants = vK.mac_lane_approximants(domain.polynomial(), require_incomparability=True)
|
|
331
|
+
approximant = vK.mac_lane_approximant(domain.polynomial(), valuation, approximants)
|
|
332
|
+
return (domain, approximant), {'approximants': approximants}
|
|
333
|
+
else:
|
|
334
|
+
# on a rational function field K(x), any valuation on K[x] that
|
|
335
|
+
# does not have an element with valuation -infty extends to a
|
|
336
|
+
# pseudo-valuation on K(x)
|
|
337
|
+
if valuation.is_negative_pseudo_valuation():
|
|
338
|
+
raise ValueError("there must not be an element of valuation -Infinity in the domain of valuation %r" % (valuation,))
|
|
339
|
+
return (domain, valuation), {}
|
|
340
|
+
|
|
341
|
+
if valuation.domain().is_subring(domain.base_field()):
|
|
342
|
+
# valuation is defined on a subring of this function field, try to lift it
|
|
343
|
+
return self.create_key_and_extra_args(domain, valuation.extension(domain))
|
|
344
|
+
|
|
345
|
+
raise NotImplementedError("extension of valuation from %r to %r not implemented yet" % (valuation.domain(), domain))
|
|
346
|
+
|
|
347
|
+
def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, valuation, to_valuation_domain, from_valuation_domain):
|
|
348
|
+
r"""
|
|
349
|
+
Create a unique key which identifies the valuation which is
|
|
350
|
+
``valuation`` after mapping through ``to_valuation_domain``.
|
|
351
|
+
|
|
352
|
+
TESTS::
|
|
353
|
+
|
|
354
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
355
|
+
sage: R.<y> = K[]
|
|
356
|
+
sage: L.<y> = K.extension(y^2 + y + x^3) # needs sage.rings.function_field
|
|
357
|
+
sage: v = K.valuation(1/x) # needs sage.rings.function_field
|
|
358
|
+
sage: w = v.extension(L) # indirect doctest # needs sage.geometry.polyhedron sage.rings.function_field
|
|
359
|
+
"""
|
|
360
|
+
from sage.categories.function_fields import FunctionFields
|
|
361
|
+
if valuation.domain() not in FunctionFields():
|
|
362
|
+
raise ValueError("valuation must be defined over an isomorphic function field but %r is not a function field" % (valuation.domain(),))
|
|
363
|
+
|
|
364
|
+
from sage.categories.homset import Hom
|
|
365
|
+
if to_valuation_domain not in Hom(domain, valuation.domain()):
|
|
366
|
+
raise ValueError("to_valuation_domain must map from %r to %r but %r maps from %r to %r" % (domain, valuation.domain(), to_valuation_domain, to_valuation_domain.domain(), to_valuation_domain.codomain()))
|
|
367
|
+
if from_valuation_domain not in Hom(valuation.domain(), domain):
|
|
368
|
+
raise ValueError("from_valuation_domain must map from %r to %r but %r maps from %r to %r" % (valuation.domain(), domain, from_valuation_domain, from_valuation_domain.domain(), from_valuation_domain.codomain()))
|
|
369
|
+
|
|
370
|
+
if domain is domain.base():
|
|
371
|
+
if valuation.domain() is not valuation.domain().base() or valuation.domain().constant_base_field() != domain.constant_base_field():
|
|
372
|
+
raise NotImplementedError("maps must be isomorphisms with a rational function field over the same base field, not with %r" % (valuation.domain(),))
|
|
373
|
+
if domain != valuation.domain():
|
|
374
|
+
# make it harder to create different representations of the same valuation
|
|
375
|
+
# (nothing bad happens if we did, but >= and <= are only implemented when this is the case.)
|
|
376
|
+
raise NotImplementedError("domain and valuation.domain() must be the same rational function field but %r is not %r" % (domain, valuation.domain()))
|
|
377
|
+
else:
|
|
378
|
+
if domain.base() is not valuation.domain().base():
|
|
379
|
+
raise NotImplementedError("domain and valuation.domain() must have the same base field but %r is not %r" % (domain.base(), valuation.domain().base()))
|
|
380
|
+
if to_valuation_domain != domain.hom([to_valuation_domain(domain.gen())]):
|
|
381
|
+
raise NotImplementedError("to_valuation_domain must be trivial on the base fields but %r is not %r" % (to_valuation_domain, domain.hom([to_valuation_domain(domain.gen())])))
|
|
382
|
+
if from_valuation_domain != valuation.domain().hom([from_valuation_domain(valuation.domain().gen())]):
|
|
383
|
+
raise NotImplementedError("from_valuation_domain must be trivial on the base fields but %r is not %r" % (from_valuation_domain, valuation.domain().hom([from_valuation_domain(valuation.domain().gen())])))
|
|
384
|
+
if to_valuation_domain(domain.gen()) == valuation.domain().gen():
|
|
385
|
+
raise NotImplementedError("to_valuation_domain seems to be trivial but trivial maps would currently break partial orders of valuations")
|
|
386
|
+
|
|
387
|
+
if from_valuation_domain(to_valuation_domain(domain.gen())) != domain.gen():
|
|
388
|
+
# only a necessary condition
|
|
389
|
+
raise ValueError("to_valuation_domain and from_valuation_domain are not inverses of each other")
|
|
390
|
+
|
|
391
|
+
return (domain, (valuation, to_valuation_domain, from_valuation_domain)), {}
|
|
392
|
+
|
|
393
|
+
def create_object(self, version, key, **extra_args):
|
|
394
|
+
r"""
|
|
395
|
+
Create the valuation specified by ``key``.
|
|
396
|
+
|
|
397
|
+
EXAMPLES::
|
|
398
|
+
|
|
399
|
+
sage: K.<x> = FunctionField(QQ)
|
|
400
|
+
sage: R.<x> = QQ[]
|
|
401
|
+
sage: w = valuations.GaussValuation(R, QQ.valuation(2))
|
|
402
|
+
sage: v = K.valuation(w); v # indirect doctest
|
|
403
|
+
2-adic valuation
|
|
404
|
+
"""
|
|
405
|
+
domain, valuation = key
|
|
406
|
+
from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
|
|
407
|
+
parent = DiscretePseudoValuationSpace(domain)
|
|
408
|
+
|
|
409
|
+
if isinstance(valuation, tuple) and len(valuation) == 3:
|
|
410
|
+
valuation, to_valuation_domain, from_valuation_domain = valuation
|
|
411
|
+
if domain is domain.base() and valuation.domain() is valuation.domain().base():
|
|
412
|
+
if valuation == valuation.domain().valuation(valuation.domain().gen()):
|
|
413
|
+
if to_valuation_domain != domain.hom([~valuation.domain().gen()]) or from_valuation_domain != valuation.domain().hom([~domain.gen()]):
|
|
414
|
+
raise ValueError("the only allowed automorphism for classical valuations is the automorphism x |--> 1/x")
|
|
415
|
+
# valuation on the rational function field after x |--> 1/x,
|
|
416
|
+
# i.e., the classical valuation at infinity
|
|
417
|
+
return parent.__make_element_class__(InfiniteRationalFunctionFieldValuation)(parent)
|
|
418
|
+
|
|
419
|
+
from sage.structure.dynamic_class import dynamic_class
|
|
420
|
+
clazz = RationalFunctionFieldMappedValuation
|
|
421
|
+
if valuation.is_discrete_valuation():
|
|
422
|
+
clazz = dynamic_class("RationalFunctionFieldMappedValuation_discrete", (clazz, DiscreteValuation))
|
|
423
|
+
else:
|
|
424
|
+
clazz = dynamic_class("RationalFunctionFieldMappedValuation_infinite", (clazz, InfiniteDiscretePseudoValuation))
|
|
425
|
+
return parent.__make_element_class__(clazz)(parent, valuation, to_valuation_domain, from_valuation_domain)
|
|
426
|
+
return parent.__make_element_class__(FunctionFieldExtensionMappedValuation)(parent, valuation, to_valuation_domain, from_valuation_domain)
|
|
427
|
+
|
|
428
|
+
if domain is valuation.domain():
|
|
429
|
+
# we cannot just return valuation in this case
|
|
430
|
+
# as this would break uniqueness and pickling
|
|
431
|
+
raise ValueError("valuation must not be a valuation on domain yet but %r is a valuation on %r" % (valuation, domain))
|
|
432
|
+
|
|
433
|
+
if domain.base_field() is domain:
|
|
434
|
+
# valuation is a base valuation on K[x] that induces a valuation on K(x)
|
|
435
|
+
if valuation.restriction(domain.constant_base_field()).is_trivial() and valuation.is_discrete_valuation():
|
|
436
|
+
# valuation corresponds to a finite place
|
|
437
|
+
return parent.__make_element_class__(FiniteRationalFunctionFieldValuation)(parent, valuation)
|
|
438
|
+
else:
|
|
439
|
+
from sage.structure.dynamic_class import dynamic_class
|
|
440
|
+
clazz = NonClassicalRationalFunctionFieldValuation
|
|
441
|
+
if valuation.is_discrete_valuation():
|
|
442
|
+
clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_discrete", (clazz, DiscreteFunctionFieldValuation_base))
|
|
443
|
+
else:
|
|
444
|
+
clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_negative_infinite", (clazz, NegativeInfiniteDiscretePseudoValuation))
|
|
445
|
+
return parent.__make_element_class__(clazz)(parent, valuation)
|
|
446
|
+
else:
|
|
447
|
+
# valuation is a limit valuation that singles out an extension
|
|
448
|
+
return parent.__make_element_class__(FunctionFieldFromLimitValuation)(parent, valuation, domain.polynomial(), extra_args['approximants'])
|
|
449
|
+
|
|
450
|
+
raise NotImplementedError("valuation on %r from %r on %r" % (domain, valuation, valuation.domain()))
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
FunctionFieldValuation = FunctionFieldValuationFactory("sage.rings.function_field.valuation.FunctionFieldValuation")
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
class FunctionFieldValuation_base(DiscretePseudoValuation):
|
|
457
|
+
r"""
|
|
458
|
+
Abstract base class for any discrete (pseudo-)valuation on a function
|
|
459
|
+
field.
|
|
460
|
+
|
|
461
|
+
TESTS::
|
|
462
|
+
|
|
463
|
+
sage: K.<x> = FunctionField(QQ)
|
|
464
|
+
sage: v = K.valuation(x) # indirect doctest
|
|
465
|
+
sage: from sage.rings.function_field.valuation import FunctionFieldValuation_base
|
|
466
|
+
sage: isinstance(v, FunctionFieldValuation_base)
|
|
467
|
+
True
|
|
468
|
+
"""
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
class DiscreteFunctionFieldValuation_base(DiscreteValuation):
|
|
472
|
+
r"""
|
|
473
|
+
Base class for discrete valuations on function fields.
|
|
474
|
+
|
|
475
|
+
TESTS::
|
|
476
|
+
|
|
477
|
+
sage: K.<x> = FunctionField(QQ)
|
|
478
|
+
sage: v = K.valuation(x) # indirect doctest
|
|
479
|
+
sage: from sage.rings.function_field.valuation import DiscreteFunctionFieldValuation_base
|
|
480
|
+
sage: isinstance(v, DiscreteFunctionFieldValuation_base)
|
|
481
|
+
True
|
|
482
|
+
"""
|
|
483
|
+
def extensions(self, L):
|
|
484
|
+
r"""
|
|
485
|
+
Return the extensions of this valuation to ``L``.
|
|
486
|
+
|
|
487
|
+
EXAMPLES::
|
|
488
|
+
|
|
489
|
+
sage: K.<x> = FunctionField(QQ)
|
|
490
|
+
sage: v = K.valuation(x)
|
|
491
|
+
sage: R.<y> = K[]
|
|
492
|
+
sage: L.<y> = K.extension(y^2 - x) # needs sage.rings.function_field
|
|
493
|
+
sage: v.extensions(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
494
|
+
[(x)-adic valuation]
|
|
495
|
+
|
|
496
|
+
TESTS:
|
|
497
|
+
|
|
498
|
+
Valuations over the infinite place::
|
|
499
|
+
|
|
500
|
+
sage: v = K.valuation(1/x)
|
|
501
|
+
sage: R.<y> = K[]
|
|
502
|
+
sage: L.<y> = K.extension(y^2 - 1/(x^2 + 1)) # needs sage.rings.function_field
|
|
503
|
+
sage: sorted(v.extensions(L), key=str) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
504
|
+
[[ Valuation at the infinite place, v(y + 1/x) = 3 ]-adic valuation,
|
|
505
|
+
[ Valuation at the infinite place, v(y - 1/x) = 3 ]-adic valuation]
|
|
506
|
+
|
|
507
|
+
Iterated extensions over the infinite place::
|
|
508
|
+
|
|
509
|
+
sage: # needs sage.geometry.polyhedron sage.rings.function_field
|
|
510
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
511
|
+
sage: R.<y> = K[]
|
|
512
|
+
sage: L.<y> = K.extension(y^2 + y + x^3)
|
|
513
|
+
sage: v = K.valuation(1/x)
|
|
514
|
+
sage: w = v.extension(L)
|
|
515
|
+
sage: R.<z> = L[]
|
|
516
|
+
sage: M.<z> = L.extension(z^2 - y)
|
|
517
|
+
sage: w.extension(M) # not implemented
|
|
518
|
+
Traceback (most recent call last):
|
|
519
|
+
...
|
|
520
|
+
NotImplementedError
|
|
521
|
+
|
|
522
|
+
A case that caused some trouble at some point::
|
|
523
|
+
|
|
524
|
+
sage: R.<x> = QQ[]
|
|
525
|
+
sage: v = GaussValuation(R, QQ.valuation(2))
|
|
526
|
+
|
|
527
|
+
sage: K.<x> = FunctionField(QQ)
|
|
528
|
+
sage: v = K.valuation(v)
|
|
529
|
+
|
|
530
|
+
sage: R.<y> = K[]
|
|
531
|
+
sage: L.<y> = K.extension(y^3 - x^4 - 1) # needs sage.rings.function_field
|
|
532
|
+
sage: v.extensions(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
533
|
+
[2-adic valuation]
|
|
534
|
+
|
|
535
|
+
Test that this works in towers::
|
|
536
|
+
|
|
537
|
+
sage: # needs sage.rings.function_field
|
|
538
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
539
|
+
sage: R.<y> = K[]
|
|
540
|
+
sage: L.<y> = K.extension(y - x)
|
|
541
|
+
sage: R.<z> = L[]
|
|
542
|
+
sage: L.<z> = L.extension(z - y)
|
|
543
|
+
sage: v = K.valuation(x)
|
|
544
|
+
sage: v.extensions(L) # needs sage.geometry.polyhedron
|
|
545
|
+
[(x)-adic valuation]
|
|
546
|
+
"""
|
|
547
|
+
K = self.domain()
|
|
548
|
+
from sage.categories.function_fields import FunctionFields
|
|
549
|
+
if L is K:
|
|
550
|
+
return [self]
|
|
551
|
+
if L in FunctionFields():
|
|
552
|
+
if K.is_subring(L):
|
|
553
|
+
if L.base() is K:
|
|
554
|
+
# L = K[y]/(G) is a simple extension of the domain of this valuation
|
|
555
|
+
G = L.polynomial()
|
|
556
|
+
if not G.is_monic():
|
|
557
|
+
G = G / G.leading_coefficient()
|
|
558
|
+
if any(self(c) < 0 for c in G.coefficients()):
|
|
559
|
+
# rewrite L = K[u]/(H) with H integral and compute the extensions
|
|
560
|
+
from sage.rings.valuation.gauss_valuation import GaussValuation
|
|
561
|
+
g = GaussValuation(G.parent(), self)
|
|
562
|
+
y_to_u, u_to_y, H = g.monic_integral_model(G)
|
|
563
|
+
M = K.extension(H, names=L.variable_names())
|
|
564
|
+
H_extensions = self.extensions(M)
|
|
565
|
+
|
|
566
|
+
from sage.rings.morphism import RingHomomorphism_im_gens
|
|
567
|
+
if isinstance(y_to_u, RingHomomorphism_im_gens) and isinstance(u_to_y, RingHomomorphism_im_gens):
|
|
568
|
+
return [L.valuation((w, L.hom([M(y_to_u(y_to_u.domain().gen()))]), M.hom([L(u_to_y(u_to_y.domain().gen()))]))) for w in H_extensions]
|
|
569
|
+
raise NotImplementedError
|
|
570
|
+
return [L.valuation(w) for w in self.mac_lane_approximants(L.polynomial(), require_incomparability=True)]
|
|
571
|
+
elif L.base() is not L and K.is_subring(L):
|
|
572
|
+
# recursively call this method for the tower of fields
|
|
573
|
+
from operator import add
|
|
574
|
+
from functools import reduce
|
|
575
|
+
A = [base_valuation.extensions(L) for base_valuation in self.extensions(L.base())]
|
|
576
|
+
return reduce(add, A, [])
|
|
577
|
+
elif L.constant_base_field() is not K.constant_base_field() and K.constant_base_field().is_subring(L):
|
|
578
|
+
# subclasses should override this method and handle this case, so we never get here
|
|
579
|
+
raise NotImplementedError("Cannot compute the extensions of %r from %r to %r since the base ring changes." % (self, self.domain(), L))
|
|
580
|
+
raise NotImplementedError("extension of %r from %r to %r not implemented" % (self, K, L))
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
class RationalFunctionFieldValuation_base(FunctionFieldValuation_base):
|
|
584
|
+
r"""
|
|
585
|
+
Base class for valuations on rational function fields.
|
|
586
|
+
|
|
587
|
+
TESTS::
|
|
588
|
+
|
|
589
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
590
|
+
sage: v = K.valuation(x) # indirect doctest
|
|
591
|
+
sage: from sage.rings.function_field.valuation import RationalFunctionFieldValuation_base
|
|
592
|
+
sage: isinstance(v, RationalFunctionFieldValuation_base)
|
|
593
|
+
True
|
|
594
|
+
"""
|
|
595
|
+
@cached_method
|
|
596
|
+
def element_with_valuation(self, s):
|
|
597
|
+
r"""
|
|
598
|
+
Return an element with valuation ``s``.
|
|
599
|
+
|
|
600
|
+
EXAMPLES::
|
|
601
|
+
|
|
602
|
+
sage: # needs sage.geometry.polyhedron sage.rings.number_field
|
|
603
|
+
sage: x = polygen(ZZ, 'x')
|
|
604
|
+
sage: K.<a> = NumberField(x^3 + 6)
|
|
605
|
+
sage: v = K.valuation(2)
|
|
606
|
+
sage: R.<x> = K[]
|
|
607
|
+
sage: w = GaussValuation(R, v).augmentation(x, 1/123)
|
|
608
|
+
sage: K.<x> = FunctionField(K)
|
|
609
|
+
sage: w = w.extension(K)
|
|
610
|
+
sage: w.element_with_valuation(122/123)
|
|
611
|
+
2/x
|
|
612
|
+
sage: w.element_with_valuation(1)
|
|
613
|
+
2
|
|
614
|
+
"""
|
|
615
|
+
constant_valuation = self.restriction(self.domain().constant_base_field())
|
|
616
|
+
if constant_valuation.is_trivial():
|
|
617
|
+
return super().element_with_valuation(s)
|
|
618
|
+
|
|
619
|
+
a, b = self.value_group()._element_with_valuation(constant_valuation.value_group(), s)
|
|
620
|
+
ret = self.uniformizer()**a * constant_valuation.element_with_valuation(constant_valuation.value_group().gen()*b)
|
|
621
|
+
|
|
622
|
+
return self.simplify(ret, error=s)
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
class ClassicalFunctionFieldValuation_base(DiscreteFunctionFieldValuation_base):
|
|
626
|
+
r"""
|
|
627
|
+
Base class for discrete valuations on rational function fields that come
|
|
628
|
+
from points on the projective line.
|
|
629
|
+
|
|
630
|
+
TESTS::
|
|
631
|
+
|
|
632
|
+
sage: K.<x> = FunctionField(GF(5))
|
|
633
|
+
sage: v = K.valuation(x) # indirect doctest
|
|
634
|
+
sage: from sage.rings.function_field.valuation import ClassicalFunctionFieldValuation_base
|
|
635
|
+
sage: isinstance(v, ClassicalFunctionFieldValuation_base)
|
|
636
|
+
True
|
|
637
|
+
"""
|
|
638
|
+
def _test_classical_residue_field(self, **options):
|
|
639
|
+
r"""
|
|
640
|
+
Check correctness of the residue field of a discrete valuation at a
|
|
641
|
+
classical point.
|
|
642
|
+
|
|
643
|
+
TESTS::
|
|
644
|
+
|
|
645
|
+
sage: K.<x> = FunctionField(QQ)
|
|
646
|
+
sage: v = K.valuation(x^2 + 1)
|
|
647
|
+
sage: v._test_classical_residue_field() # needs sage.rings.number_field
|
|
648
|
+
"""
|
|
649
|
+
tester = self._tester(**options)
|
|
650
|
+
|
|
651
|
+
tester.assertTrue(self.domain().constant_base_field().is_subring(self.residue_field()))
|
|
652
|
+
|
|
653
|
+
def _ge_(self, other):
|
|
654
|
+
r"""
|
|
655
|
+
Return whether ``self`` is greater or equal to ``other`` everywhere.
|
|
656
|
+
|
|
657
|
+
EXAMPLES::
|
|
658
|
+
|
|
659
|
+
sage: K.<x> = FunctionField(QQ)
|
|
660
|
+
sage: v = K.valuation(x^2 + 1)
|
|
661
|
+
sage: w = K.valuation(x)
|
|
662
|
+
sage: v >= w
|
|
663
|
+
False
|
|
664
|
+
sage: w >= v
|
|
665
|
+
False
|
|
666
|
+
"""
|
|
667
|
+
if other.is_trivial():
|
|
668
|
+
return other.is_discrete_valuation()
|
|
669
|
+
if isinstance(other, ClassicalFunctionFieldValuation_base):
|
|
670
|
+
return self == other
|
|
671
|
+
super()._ge_(other)
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
class InducedRationalFunctionFieldValuation_base(FunctionFieldValuation_base):
|
|
675
|
+
r"""
|
|
676
|
+
Base class for function field valuation induced by a valuation on the
|
|
677
|
+
underlying polynomial ring.
|
|
678
|
+
|
|
679
|
+
TESTS::
|
|
680
|
+
|
|
681
|
+
sage: K.<x> = FunctionField(QQ)
|
|
682
|
+
sage: v = K.valuation(x^2 + 1) # indirect doctest
|
|
683
|
+
"""
|
|
684
|
+
def __init__(self, parent, base_valuation):
|
|
685
|
+
r"""
|
|
686
|
+
TESTS::
|
|
687
|
+
|
|
688
|
+
sage: K.<x> = FunctionField(QQ)
|
|
689
|
+
sage: v = K.valuation(x) # indirect doctest
|
|
690
|
+
sage: from sage.rings.function_field.valuation import InducedRationalFunctionFieldValuation_base
|
|
691
|
+
sage: isinstance(v, InducedRationalFunctionFieldValuation_base)
|
|
692
|
+
True
|
|
693
|
+
"""
|
|
694
|
+
FunctionFieldValuation_base.__init__(self, parent)
|
|
695
|
+
|
|
696
|
+
domain = parent.domain()
|
|
697
|
+
if base_valuation.domain() is not domain._ring:
|
|
698
|
+
raise ValueError("base valuation must be defined on %r but %r is defined on %r" % (domain._ring, base_valuation, base_valuation.domain()))
|
|
699
|
+
|
|
700
|
+
self._base_valuation = base_valuation
|
|
701
|
+
|
|
702
|
+
def uniformizer(self):
|
|
703
|
+
r"""
|
|
704
|
+
Return a uniformizing element for this valuation.
|
|
705
|
+
|
|
706
|
+
EXAMPLES::
|
|
707
|
+
|
|
708
|
+
sage: K.<x> = FunctionField(QQ)
|
|
709
|
+
sage: K.valuation(x).uniformizer()
|
|
710
|
+
x
|
|
711
|
+
"""
|
|
712
|
+
return self.domain()(self._base_valuation.uniformizer())
|
|
713
|
+
|
|
714
|
+
def lift(self, F):
|
|
715
|
+
r"""
|
|
716
|
+
Return a lift of ``F`` to the domain of this valuation such
|
|
717
|
+
that :meth:`reduce` returns the original element.
|
|
718
|
+
|
|
719
|
+
EXAMPLES::
|
|
720
|
+
|
|
721
|
+
sage: K.<x> = FunctionField(QQ)
|
|
722
|
+
sage: v = K.valuation(x)
|
|
723
|
+
sage: v.lift(0)
|
|
724
|
+
0
|
|
725
|
+
sage: v.lift(1)
|
|
726
|
+
1
|
|
727
|
+
"""
|
|
728
|
+
F = self.residue_ring().coerce(F)
|
|
729
|
+
if F in self._base_valuation.residue_ring():
|
|
730
|
+
num = self._base_valuation.residue_ring()(F)
|
|
731
|
+
den = self._base_valuation.residue_ring()(1)
|
|
732
|
+
elif F in self._base_valuation.residue_ring().fraction_field():
|
|
733
|
+
num = self._base_valuation.residue_ring()(F.numerator())
|
|
734
|
+
den = self._base_valuation.residue_ring()(F.denominator())
|
|
735
|
+
else:
|
|
736
|
+
raise NotImplementedError("lifting not implemented for this valuation")
|
|
737
|
+
|
|
738
|
+
return self.domain()(self._base_valuation.lift(num)) / self.domain()(self._base_valuation.lift(den))
|
|
739
|
+
|
|
740
|
+
def value_group(self):
|
|
741
|
+
r"""
|
|
742
|
+
Return the value group of this valuation.
|
|
743
|
+
|
|
744
|
+
EXAMPLES::
|
|
745
|
+
|
|
746
|
+
sage: K.<x> = FunctionField(QQ)
|
|
747
|
+
sage: K.valuation(x).value_group()
|
|
748
|
+
Additive Abelian Group generated by 1
|
|
749
|
+
"""
|
|
750
|
+
return self._base_valuation.value_group()
|
|
751
|
+
|
|
752
|
+
def reduce(self, f):
|
|
753
|
+
r"""
|
|
754
|
+
Return the reduction of ``f`` in :meth:`residue_ring`.
|
|
755
|
+
|
|
756
|
+
EXAMPLES::
|
|
757
|
+
|
|
758
|
+
sage: K.<x> = FunctionField(QQ)
|
|
759
|
+
sage: v = K.valuation(x^2 + 1)
|
|
760
|
+
sage: v.reduce(x) # needs sage.rings.number_field
|
|
761
|
+
u1
|
|
762
|
+
"""
|
|
763
|
+
f = self.domain().coerce(f)
|
|
764
|
+
|
|
765
|
+
if self(f) > 0:
|
|
766
|
+
return self.residue_field().zero()
|
|
767
|
+
if self(f) < 0:
|
|
768
|
+
raise ValueError("cannot reduce element of negative valuation")
|
|
769
|
+
|
|
770
|
+
base = self._base_valuation
|
|
771
|
+
|
|
772
|
+
num = f.numerator()
|
|
773
|
+
den = f.denominator()
|
|
774
|
+
|
|
775
|
+
assert base(num) == base(den)
|
|
776
|
+
shift = base.element_with_valuation(-base(num))
|
|
777
|
+
num *= shift
|
|
778
|
+
den *= shift
|
|
779
|
+
ret = base.reduce(num) / base.reduce(den)
|
|
780
|
+
assert not ret.is_zero()
|
|
781
|
+
return self.residue_field()(ret)
|
|
782
|
+
|
|
783
|
+
def _repr_(self):
|
|
784
|
+
r"""
|
|
785
|
+
Return a printable representation of this valuation.
|
|
786
|
+
|
|
787
|
+
EXAMPLES::
|
|
788
|
+
|
|
789
|
+
sage: K.<x> = FunctionField(QQ)
|
|
790
|
+
sage: K.valuation(x^2 + 1) # indirect doctest
|
|
791
|
+
(x^2 + 1)-adic valuation
|
|
792
|
+
"""
|
|
793
|
+
from sage.rings.valuation.augmented_valuation import AugmentedValuation_base
|
|
794
|
+
from sage.rings.valuation.gauss_valuation import GaussValuation
|
|
795
|
+
if isinstance(self._base_valuation, AugmentedValuation_base):
|
|
796
|
+
if self._base_valuation._base_valuation == GaussValuation(self.domain()._ring, TrivialValuation(self.domain().constant_base_field())):
|
|
797
|
+
if self._base_valuation._mu == 1:
|
|
798
|
+
return "(%r)-adic valuation" % (self._base_valuation.phi())
|
|
799
|
+
vK = self._base_valuation.restriction(self._base_valuation.domain().base_ring())
|
|
800
|
+
if self._base_valuation == GaussValuation(self.domain()._ring, vK):
|
|
801
|
+
return repr(vK)
|
|
802
|
+
return "Valuation on rational function field induced by %s" % self._base_valuation
|
|
803
|
+
|
|
804
|
+
def extensions(self, L):
|
|
805
|
+
r"""
|
|
806
|
+
Return all extensions of this valuation to ``L`` which has a larger
|
|
807
|
+
constant field than the domain of this valuation.
|
|
808
|
+
|
|
809
|
+
EXAMPLES::
|
|
810
|
+
|
|
811
|
+
sage: # needs sage.rings.number_field
|
|
812
|
+
sage: K.<x> = FunctionField(QQ)
|
|
813
|
+
sage: v = K.valuation(x^2 + 1)
|
|
814
|
+
sage: L.<x> = FunctionField(GaussianIntegers().fraction_field())
|
|
815
|
+
sage: v.extensions(L) # indirect doctest
|
|
816
|
+
[(x - I)-adic valuation, (x + I)-adic valuation]
|
|
817
|
+
"""
|
|
818
|
+
K = self.domain()
|
|
819
|
+
if L is K:
|
|
820
|
+
return [self]
|
|
821
|
+
|
|
822
|
+
from sage.categories.function_fields import FunctionFields
|
|
823
|
+
if (L in FunctionFields()
|
|
824
|
+
and K.is_subring(L)
|
|
825
|
+
and L.base() is L
|
|
826
|
+
and L.constant_base_field() is not K.constant_base_field()
|
|
827
|
+
and K.constant_base_field().is_subring(L.constant_base_field())):
|
|
828
|
+
# The above condition checks whether L is an extension of K that
|
|
829
|
+
# comes from an extension of the field of constants
|
|
830
|
+
# Condition "L.base() is L" is important so we do not call this
|
|
831
|
+
# code for extensions from K(x) to K(x)(y)
|
|
832
|
+
|
|
833
|
+
# We extend the underlying valuation on the polynomial ring
|
|
834
|
+
W = self._base_valuation.extensions(L._ring)
|
|
835
|
+
return [L.valuation(w) for w in W]
|
|
836
|
+
|
|
837
|
+
return super().extensions(L)
|
|
838
|
+
|
|
839
|
+
def _call_(self, f):
|
|
840
|
+
r"""
|
|
841
|
+
Evaluate this valuation at the function ``f``.
|
|
842
|
+
|
|
843
|
+
EXAMPLES::
|
|
844
|
+
|
|
845
|
+
sage: K.<x> = FunctionField(QQ)
|
|
846
|
+
sage: v = K.valuation(x) # indirect doctest
|
|
847
|
+
sage: v((x+1)/x^2)
|
|
848
|
+
-2
|
|
849
|
+
"""
|
|
850
|
+
return self._base_valuation(f.numerator()) - self._base_valuation(f.denominator())
|
|
851
|
+
|
|
852
|
+
def residue_ring(self):
|
|
853
|
+
r"""
|
|
854
|
+
Return the residue field of this valuation.
|
|
855
|
+
|
|
856
|
+
EXAMPLES::
|
|
857
|
+
|
|
858
|
+
sage: K.<x> = FunctionField(QQ)
|
|
859
|
+
sage: K.valuation(x).residue_ring()
|
|
860
|
+
Rational Field
|
|
861
|
+
"""
|
|
862
|
+
return self._base_valuation.residue_ring().fraction_field()
|
|
863
|
+
|
|
864
|
+
def restriction(self, ring):
|
|
865
|
+
r"""
|
|
866
|
+
Return the restriction of this valuation to ``ring``.
|
|
867
|
+
|
|
868
|
+
EXAMPLES::
|
|
869
|
+
|
|
870
|
+
sage: K.<x> = FunctionField(QQ)
|
|
871
|
+
sage: K.valuation(x).restriction(QQ)
|
|
872
|
+
Trivial valuation on Rational Field
|
|
873
|
+
"""
|
|
874
|
+
if ring.is_subring(self._base_valuation.domain()):
|
|
875
|
+
return self._base_valuation.restriction(ring)
|
|
876
|
+
return super().restriction(ring)
|
|
877
|
+
|
|
878
|
+
def simplify(self, f, error=None, force=False):
|
|
879
|
+
r"""
|
|
880
|
+
Return a simplified version of ``f``.
|
|
881
|
+
|
|
882
|
+
Produce an element which differs from ``f`` by an element of
|
|
883
|
+
valuation strictly greater than the valuation of ``f`` (or strictly
|
|
884
|
+
greater than ``error`` if set.)
|
|
885
|
+
|
|
886
|
+
If ``force`` is not set, then expensive simplifications may be avoided.
|
|
887
|
+
|
|
888
|
+
EXAMPLES::
|
|
889
|
+
|
|
890
|
+
sage: K.<x> = FunctionField(QQ)
|
|
891
|
+
sage: v = K.valuation(2)
|
|
892
|
+
sage: f = (x + 1)/(x - 1)
|
|
893
|
+
|
|
894
|
+
As the coefficients of this fraction are small, we do not simplify as
|
|
895
|
+
this could be very costly in some cases::
|
|
896
|
+
|
|
897
|
+
sage: v.simplify(f)
|
|
898
|
+
(x + 1)/(x - 1)
|
|
899
|
+
|
|
900
|
+
However, simplification can be forced::
|
|
901
|
+
|
|
902
|
+
sage: v.simplify(f, force=True)
|
|
903
|
+
3
|
|
904
|
+
"""
|
|
905
|
+
f = self.domain().coerce(f)
|
|
906
|
+
|
|
907
|
+
if error is None:
|
|
908
|
+
# if the caller was sure that we should simplify, then we should try to do the best simplification possible
|
|
909
|
+
error = self(f) if force else self.upper_bound(f)
|
|
910
|
+
|
|
911
|
+
from sage.rings.infinity import infinity
|
|
912
|
+
if error is infinity:
|
|
913
|
+
return f
|
|
914
|
+
|
|
915
|
+
numerator = f.numerator()
|
|
916
|
+
denominator = f.denominator()
|
|
917
|
+
|
|
918
|
+
v_numerator = self._base_valuation(numerator)
|
|
919
|
+
v_denominator = self._base_valuation(denominator)
|
|
920
|
+
|
|
921
|
+
if v_numerator - v_denominator > error:
|
|
922
|
+
return self.domain().zero()
|
|
923
|
+
|
|
924
|
+
if error == -infinity:
|
|
925
|
+
# This case is not implemented yet, so we just return f which is always safe.
|
|
926
|
+
return f
|
|
927
|
+
|
|
928
|
+
numerator = self.domain()(self._base_valuation.simplify(numerator, error=error+v_denominator, force=force))
|
|
929
|
+
denominator = self.domain()(self._base_valuation.simplify(denominator, error=max(v_denominator, error - v_numerator + 2*v_denominator), force=force))
|
|
930
|
+
|
|
931
|
+
ret = numerator/denominator
|
|
932
|
+
assert self(ret - f) > error
|
|
933
|
+
return ret
|
|
934
|
+
|
|
935
|
+
def _relative_size(self, f):
|
|
936
|
+
r"""
|
|
937
|
+
Return an estimate on the coefficient size of ``f``.
|
|
938
|
+
|
|
939
|
+
The number returned is an estimate on the factor between the number of
|
|
940
|
+
bits used by ``f`` and the minimal number of bits used by an element
|
|
941
|
+
congruent to ``f``.
|
|
942
|
+
|
|
943
|
+
This can be used by :meth:`simplify` to decide whether simplification
|
|
944
|
+
of coefficients is going to lead to a significant shrinking of the
|
|
945
|
+
coefficients of ``f``.
|
|
946
|
+
|
|
947
|
+
EXAMPLES::
|
|
948
|
+
|
|
949
|
+
sage: K.<x> = FunctionField(QQ)
|
|
950
|
+
sage: v = K.valuation(0)
|
|
951
|
+
sage: f = (x + 1024)/(x - 1024)
|
|
952
|
+
|
|
953
|
+
Here we report a small size, as the numerator and the denominator
|
|
954
|
+
independently cannot be simplified much::
|
|
955
|
+
|
|
956
|
+
sage: v._relative_size(f)
|
|
957
|
+
1
|
|
958
|
+
|
|
959
|
+
However, a forced simplification, finds that we could have saved many
|
|
960
|
+
more bits::
|
|
961
|
+
|
|
962
|
+
sage: v.simplify(f, force=True)
|
|
963
|
+
-1
|
|
964
|
+
"""
|
|
965
|
+
return max(self._base_valuation._relative_size(f.numerator()), self._base_valuation._relative_size(f.denominator()))
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
class FiniteRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation_base, ClassicalFunctionFieldValuation_base, RationalFunctionFieldValuation_base):
|
|
969
|
+
r"""
|
|
970
|
+
Valuation of a finite place of a function field.
|
|
971
|
+
|
|
972
|
+
EXAMPLES::
|
|
973
|
+
|
|
974
|
+
sage: K.<x> = FunctionField(QQ)
|
|
975
|
+
sage: v = K.valuation(x + 1); v # indirect doctest
|
|
976
|
+
(x + 1)-adic valuation
|
|
977
|
+
|
|
978
|
+
A finite place with residual degree::
|
|
979
|
+
|
|
980
|
+
sage: w = K.valuation(x^2 + 1); w
|
|
981
|
+
(x^2 + 1)-adic valuation
|
|
982
|
+
|
|
983
|
+
A finite place with ramification::
|
|
984
|
+
|
|
985
|
+
sage: K.<t> = FunctionField(GF(3))
|
|
986
|
+
sage: L.<x> = FunctionField(K)
|
|
987
|
+
sage: u = L.valuation(x^3 - t); u
|
|
988
|
+
(x^3 + 2*t)-adic valuation
|
|
989
|
+
|
|
990
|
+
A finite place with residual degree and ramification::
|
|
991
|
+
|
|
992
|
+
sage: q = L.valuation(x^6 - t); q
|
|
993
|
+
(x^6 + 2*t)-adic valuation
|
|
994
|
+
"""
|
|
995
|
+
def __init__(self, parent, base_valuation):
|
|
996
|
+
r"""
|
|
997
|
+
TESTS::
|
|
998
|
+
|
|
999
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1000
|
+
sage: v = K.valuation(x + 1)
|
|
1001
|
+
sage: from sage.rings.function_field.valuation import FiniteRationalFunctionFieldValuation
|
|
1002
|
+
sage: isinstance(v, FiniteRationalFunctionFieldValuation)
|
|
1003
|
+
True
|
|
1004
|
+
"""
|
|
1005
|
+
InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation)
|
|
1006
|
+
ClassicalFunctionFieldValuation_base.__init__(self, parent)
|
|
1007
|
+
RationalFunctionFieldValuation_base.__init__(self, parent)
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
class NonClassicalRationalFunctionFieldValuation(InducedRationalFunctionFieldValuation_base, RationalFunctionFieldValuation_base):
|
|
1011
|
+
r"""
|
|
1012
|
+
Valuation induced by a valuation on the underlying polynomial ring which is
|
|
1013
|
+
non-classical.
|
|
1014
|
+
|
|
1015
|
+
EXAMPLES::
|
|
1016
|
+
|
|
1017
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1018
|
+
sage: v = GaussValuation(QQ['x'], QQ.valuation(2))
|
|
1019
|
+
sage: w = K.valuation(v); w # indirect doctest
|
|
1020
|
+
2-adic valuation
|
|
1021
|
+
"""
|
|
1022
|
+
def __init__(self, parent, base_valuation):
|
|
1023
|
+
r"""
|
|
1024
|
+
TESTS:
|
|
1025
|
+
|
|
1026
|
+
There is some support for discrete pseudo-valuations on rational
|
|
1027
|
+
function fields in the code. However, since these valuations must send
|
|
1028
|
+
elements to `-\infty`, they are not supported yet::
|
|
1029
|
+
|
|
1030
|
+
sage: R.<x> = QQ[]
|
|
1031
|
+
sage: v = GaussValuation(QQ['x'], QQ.valuation(2)).augmentation(x, infinity)
|
|
1032
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1033
|
+
sage: w = K.valuation(v)
|
|
1034
|
+
sage: from sage.rings.function_field.valuation import NonClassicalRationalFunctionFieldValuation
|
|
1035
|
+
sage: isinstance(w, NonClassicalRationalFunctionFieldValuation)
|
|
1036
|
+
True
|
|
1037
|
+
"""
|
|
1038
|
+
InducedRationalFunctionFieldValuation_base.__init__(self, parent, base_valuation)
|
|
1039
|
+
RationalFunctionFieldValuation_base.__init__(self, parent)
|
|
1040
|
+
|
|
1041
|
+
def residue_ring(self):
|
|
1042
|
+
r"""
|
|
1043
|
+
Return the residue field of this valuation.
|
|
1044
|
+
|
|
1045
|
+
EXAMPLES::
|
|
1046
|
+
|
|
1047
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1048
|
+
sage: v = valuations.GaussValuation(QQ['x'], QQ.valuation(2))
|
|
1049
|
+
sage: w = K.valuation(v)
|
|
1050
|
+
sage: w.residue_ring()
|
|
1051
|
+
Rational function field in x over Finite Field of size 2
|
|
1052
|
+
|
|
1053
|
+
sage: R.<x> = QQ[]
|
|
1054
|
+
sage: vv = v.augmentation(x, 1)
|
|
1055
|
+
sage: w = K.valuation(vv)
|
|
1056
|
+
sage: w.residue_ring()
|
|
1057
|
+
Rational function field in x over Finite Field of size 2
|
|
1058
|
+
|
|
1059
|
+
sage: R.<y> = K[]
|
|
1060
|
+
sage: L.<y> = K.extension(y^2 + 2*x) # needs sage.rings.function_field
|
|
1061
|
+
sage: w.extension(L).residue_ring() # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1062
|
+
Function field in u2 defined by u2^2 + x
|
|
1063
|
+
|
|
1064
|
+
TESTS:
|
|
1065
|
+
|
|
1066
|
+
This still works for pseudo-valuations::
|
|
1067
|
+
|
|
1068
|
+
sage: R.<x> = QQ[]
|
|
1069
|
+
sage: v = valuations.GaussValuation(R, QQ.valuation(2))
|
|
1070
|
+
sage: vv = v.augmentation(x, infinity)
|
|
1071
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1072
|
+
sage: w = K.valuation(vv)
|
|
1073
|
+
sage: w.residue_ring()
|
|
1074
|
+
Finite Field of size 2
|
|
1075
|
+
"""
|
|
1076
|
+
if not self.is_discrete_valuation():
|
|
1077
|
+
# A pseudo valuation attaining negative infinity does typically not have a function field as its residue ring
|
|
1078
|
+
return super().residue_ring()
|
|
1079
|
+
return self._base_valuation.residue_ring().fraction_field().function_field()
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
class FunctionFieldFromLimitValuation(FiniteExtensionFromLimitValuation, DiscreteFunctionFieldValuation_base):
|
|
1083
|
+
r"""
|
|
1084
|
+
A valuation on a finite extensions of function fields `L=K[y]/(G)` where `K` is
|
|
1085
|
+
another function field.
|
|
1086
|
+
|
|
1087
|
+
EXAMPLES::
|
|
1088
|
+
|
|
1089
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1090
|
+
sage: R.<y> = K[]
|
|
1091
|
+
sage: L.<y> = K.extension(y^2 - (x^2 + x + 1)) # needs sage.rings.function_field
|
|
1092
|
+
sage: v = K.valuation(x - 1) # indirect doctest # needs sage.rings.function_field
|
|
1093
|
+
sage: w = v.extension(L); w # needs sage.rings.function_field
|
|
1094
|
+
(x - 1)-adic valuation
|
|
1095
|
+
"""
|
|
1096
|
+
def __init__(self, parent, approximant, G, approximants):
|
|
1097
|
+
r"""
|
|
1098
|
+
TESTS::
|
|
1099
|
+
|
|
1100
|
+
sage: # needs sage.rings.function_field
|
|
1101
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1102
|
+
sage: R.<y> = K[]
|
|
1103
|
+
sage: L.<y> = K.extension(y^2 - (x^2 + x + 1))
|
|
1104
|
+
sage: v = K.valuation(x - 1) # indirect doctest
|
|
1105
|
+
sage: w = v.extension(L)
|
|
1106
|
+
sage: from sage.rings.function_field.valuation import FunctionFieldFromLimitValuation
|
|
1107
|
+
sage: isinstance(w, FunctionFieldFromLimitValuation)
|
|
1108
|
+
True
|
|
1109
|
+
"""
|
|
1110
|
+
FiniteExtensionFromLimitValuation.__init__(self, parent, approximant, G, approximants)
|
|
1111
|
+
DiscreteFunctionFieldValuation_base.__init__(self, parent)
|
|
1112
|
+
|
|
1113
|
+
def _to_base_domain(self, f):
|
|
1114
|
+
r"""
|
|
1115
|
+
Return ``f`` as an element of the domain of the underlying limit valuation.
|
|
1116
|
+
|
|
1117
|
+
EXAMPLES::
|
|
1118
|
+
|
|
1119
|
+
sage: # needs sage.rings.function_field
|
|
1120
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1121
|
+
sage: R.<y> = K[]
|
|
1122
|
+
sage: L.<y> = K.extension(y^2 - (x^2 + x + 1))
|
|
1123
|
+
sage: v = K.valuation(x - 1) # indirect doctest
|
|
1124
|
+
sage: w = v.extension(L)
|
|
1125
|
+
sage: w._to_base_domain(y).parent()
|
|
1126
|
+
Univariate Polynomial Ring in y over Rational function field in x over Rational Field
|
|
1127
|
+
"""
|
|
1128
|
+
return f.element()
|
|
1129
|
+
|
|
1130
|
+
def scale(self, scalar):
|
|
1131
|
+
r"""
|
|
1132
|
+
Return this valuation scaled by ``scalar``.
|
|
1133
|
+
|
|
1134
|
+
EXAMPLES::
|
|
1135
|
+
|
|
1136
|
+
sage: # needs sage.rings.function_field
|
|
1137
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1138
|
+
sage: R.<y> = K[]
|
|
1139
|
+
sage: L.<y> = K.extension(y^2 - (x^2 + x + 1))
|
|
1140
|
+
sage: v = K.valuation(x - 1) # indirect doctest
|
|
1141
|
+
sage: w = v.extension(L)
|
|
1142
|
+
sage: 3*w
|
|
1143
|
+
3 * (x - 1)-adic valuation
|
|
1144
|
+
"""
|
|
1145
|
+
if scalar in QQ and scalar > 0 and scalar != 1:
|
|
1146
|
+
return self.domain().valuation(self._base_valuation._initial_approximation.scale(scalar))
|
|
1147
|
+
return super().scale(scalar)
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
class FunctionFieldMappedValuation_base(FunctionFieldValuation_base, MappedValuation_base):
|
|
1151
|
+
r"""
|
|
1152
|
+
A valuation on a function field which relies on a ``base_valuation`` on an
|
|
1153
|
+
isomorphic function field.
|
|
1154
|
+
|
|
1155
|
+
EXAMPLES::
|
|
1156
|
+
|
|
1157
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1158
|
+
sage: v = K.valuation(1/x); v
|
|
1159
|
+
Valuation at the infinite place
|
|
1160
|
+
"""
|
|
1161
|
+
def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain):
|
|
1162
|
+
r"""
|
|
1163
|
+
TESTS::
|
|
1164
|
+
|
|
1165
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1166
|
+
sage: v = K.valuation(1/x)
|
|
1167
|
+
sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuation_base
|
|
1168
|
+
sage: isinstance(v, FunctionFieldMappedValuation_base)
|
|
1169
|
+
True
|
|
1170
|
+
"""
|
|
1171
|
+
FunctionFieldValuation_base.__init__(self, parent)
|
|
1172
|
+
MappedValuation_base.__init__(self, parent, base_valuation)
|
|
1173
|
+
|
|
1174
|
+
self._to_base = to_base_valuation_domain
|
|
1175
|
+
self._from_base = from_base_valuation_domain
|
|
1176
|
+
|
|
1177
|
+
def _to_base_domain(self, f):
|
|
1178
|
+
r"""
|
|
1179
|
+
Return ``f`` as an element in the domain of ``_base_valuation``.
|
|
1180
|
+
|
|
1181
|
+
EXAMPLES::
|
|
1182
|
+
|
|
1183
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1184
|
+
sage: R.<y> = K[]
|
|
1185
|
+
sage: L.<y> = K.extension(y^2 + y + x^3) # needs sage.rings.function_field
|
|
1186
|
+
sage: v = K.valuation(1/x)
|
|
1187
|
+
sage: w = v.extension(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1188
|
+
sage: w._to_base_domain(y) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1189
|
+
x^2*y
|
|
1190
|
+
"""
|
|
1191
|
+
return self._to_base(f)
|
|
1192
|
+
|
|
1193
|
+
def _from_base_domain(self, f):
|
|
1194
|
+
r"""
|
|
1195
|
+
Return ``f`` as an element in the domain of this valuation.
|
|
1196
|
+
|
|
1197
|
+
EXAMPLES::
|
|
1198
|
+
|
|
1199
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1200
|
+
sage: R.<y> = K[]
|
|
1201
|
+
sage: L.<y> = K.extension(y^2 + y + x^3) # needs sage.rings.function_field
|
|
1202
|
+
sage: v = K.valuation(1/x)
|
|
1203
|
+
sage: w = v.extension(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1204
|
+
sage: w._from_base_domain(w._to_base_domain(y)) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1205
|
+
y
|
|
1206
|
+
|
|
1207
|
+
r"""
|
|
1208
|
+
return self._from_base(f)
|
|
1209
|
+
|
|
1210
|
+
def scale(self, scalar):
|
|
1211
|
+
r"""
|
|
1212
|
+
Return this valuation scaled by ``scalar``.
|
|
1213
|
+
|
|
1214
|
+
EXAMPLES::
|
|
1215
|
+
|
|
1216
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1217
|
+
sage: R.<y> = K[]
|
|
1218
|
+
sage: L.<y> = K.extension(y^2 + y + x^3) # needs sage.rings.function_field
|
|
1219
|
+
sage: v = K.valuation(1/x)
|
|
1220
|
+
sage: w = v.extension(L) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1221
|
+
sage: 3*w # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1222
|
+
3 * (x)-adic valuation (in Rational function field in x over Finite Field of size 2 after x |--> 1/x)
|
|
1223
|
+
"""
|
|
1224
|
+
from sage.rings.rational_field import QQ
|
|
1225
|
+
if scalar in QQ and scalar > 0 and scalar != 1:
|
|
1226
|
+
return self.domain().valuation((self._base_valuation.scale(scalar), self._to_base, self._from_base))
|
|
1227
|
+
return super().scale(scalar)
|
|
1228
|
+
|
|
1229
|
+
def _repr_(self):
|
|
1230
|
+
r"""
|
|
1231
|
+
Return a printable representation of this valuation.
|
|
1232
|
+
|
|
1233
|
+
EXAMPLES::
|
|
1234
|
+
|
|
1235
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1236
|
+
sage: R.<y> = K[]
|
|
1237
|
+
sage: L.<y> = K.extension(y^2 + y + x^3) # needs sage.rings.function_field
|
|
1238
|
+
sage: v = K.valuation(1/x)
|
|
1239
|
+
sage: v.extension(L) # indirect doctest # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1240
|
+
Valuation at the infinite place
|
|
1241
|
+
"""
|
|
1242
|
+
to_base = repr(self._to_base)
|
|
1243
|
+
if hasattr(self._to_base, '_repr_defn'):
|
|
1244
|
+
to_base = self._to_base._repr_defn().replace('\n', ', ')
|
|
1245
|
+
return "%r (in %r after %s)" % (self._base_valuation, self._base_valuation.domain(), to_base)
|
|
1246
|
+
|
|
1247
|
+
def is_discrete_valuation(self):
|
|
1248
|
+
r"""
|
|
1249
|
+
Return whether this is a discrete valuation.
|
|
1250
|
+
|
|
1251
|
+
EXAMPLES::
|
|
1252
|
+
|
|
1253
|
+
sage: # needs sage.rings.function_field
|
|
1254
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1255
|
+
sage: R.<y> = K[]
|
|
1256
|
+
sage: L.<y> = K.extension(y^2 - x^4 - 1)
|
|
1257
|
+
sage: v = K.valuation(1/x)
|
|
1258
|
+
sage: w0,w1 = v.extensions(L) # needs sage.geometry.polyhedron
|
|
1259
|
+
sage: w0.is_discrete_valuation() # needs sage.geometry.polyhedron
|
|
1260
|
+
True
|
|
1261
|
+
"""
|
|
1262
|
+
return self._base_valuation.is_discrete_valuation()
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
class FunctionFieldMappedValuationRelative_base(FunctionFieldMappedValuation_base):
|
|
1266
|
+
r"""
|
|
1267
|
+
A valuation on a function field which relies on a ``base_valuation`` on an
|
|
1268
|
+
isomorphic function field and which is such that the map from and to the
|
|
1269
|
+
other function field is the identity on the constant field.
|
|
1270
|
+
|
|
1271
|
+
EXAMPLES::
|
|
1272
|
+
|
|
1273
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1274
|
+
sage: v = K.valuation(1/x); v
|
|
1275
|
+
Valuation at the infinite place
|
|
1276
|
+
"""
|
|
1277
|
+
def __init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain):
|
|
1278
|
+
r"""
|
|
1279
|
+
TESTS::
|
|
1280
|
+
|
|
1281
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1282
|
+
sage: v = K.valuation(1/x)
|
|
1283
|
+
sage: from sage.rings.function_field.valuation import FunctionFieldMappedValuationRelative_base
|
|
1284
|
+
sage: isinstance(v, FunctionFieldMappedValuationRelative_base)
|
|
1285
|
+
True
|
|
1286
|
+
"""
|
|
1287
|
+
FunctionFieldMappedValuation_base.__init__(self, parent, base_valuation, to_base_valuation_domain, from_base_valuation_domain)
|
|
1288
|
+
if self.domain().constant_base_field() is not base_valuation.domain().constant_base_field():
|
|
1289
|
+
raise ValueError("constant fields must be identical but they differ for %r and %r" % (self.domain(), base_valuation.domain()))
|
|
1290
|
+
|
|
1291
|
+
def restriction(self, ring):
|
|
1292
|
+
r"""
|
|
1293
|
+
Return the restriction of this valuation to ``ring``.
|
|
1294
|
+
|
|
1295
|
+
EXAMPLES::
|
|
1296
|
+
|
|
1297
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1298
|
+
sage: K.valuation(1/x).restriction(GF(2))
|
|
1299
|
+
Trivial valuation on Finite Field of size 2
|
|
1300
|
+
"""
|
|
1301
|
+
if ring.is_subring(self.domain().constant_base_field()):
|
|
1302
|
+
return self._base_valuation.restriction(ring)
|
|
1303
|
+
return super().restriction(ring)
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
class RationalFunctionFieldMappedValuation(FunctionFieldMappedValuationRelative_base, RationalFunctionFieldValuation_base):
|
|
1307
|
+
r"""
|
|
1308
|
+
Valuation on a rational function field that is implemented after a map to
|
|
1309
|
+
an isomorphic rational function field.
|
|
1310
|
+
|
|
1311
|
+
EXAMPLES::
|
|
1312
|
+
|
|
1313
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1314
|
+
sage: R.<x> = QQ[]
|
|
1315
|
+
sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1)
|
|
1316
|
+
sage: w = K.valuation(w)
|
|
1317
|
+
sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))); v
|
|
1318
|
+
Valuation on rational function field induced by
|
|
1319
|
+
[ Gauss valuation induced by 2-adic valuation, v(x) = 1 ]
|
|
1320
|
+
(in Rational function field in x over Rational Field after x |--> 1/x)
|
|
1321
|
+
"""
|
|
1322
|
+
def __init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain):
|
|
1323
|
+
r"""
|
|
1324
|
+
TESTS::
|
|
1325
|
+
|
|
1326
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1327
|
+
sage: R.<x> = QQ[]
|
|
1328
|
+
sage: w = GaussValuation(R, QQ.valuation(2)).augmentation(x, 1)
|
|
1329
|
+
sage: w = K.valuation(w)
|
|
1330
|
+
sage: v = K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()])))
|
|
1331
|
+
sage: from sage.rings.function_field.valuation import RationalFunctionFieldMappedValuation
|
|
1332
|
+
sage: isinstance(v, RationalFunctionFieldMappedValuation)
|
|
1333
|
+
True
|
|
1334
|
+
"""
|
|
1335
|
+
FunctionFieldMappedValuationRelative_base.__init__(self, parent, base_valuation, to_base_valuation_doain, from_base_valuation_domain)
|
|
1336
|
+
RationalFunctionFieldValuation_base.__init__(self, parent)
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
class InfiniteRationalFunctionFieldValuation(FunctionFieldMappedValuationRelative_base, RationalFunctionFieldValuation_base, ClassicalFunctionFieldValuation_base):
|
|
1340
|
+
r"""
|
|
1341
|
+
Valuation of the infinite place of a function field.
|
|
1342
|
+
|
|
1343
|
+
EXAMPLES::
|
|
1344
|
+
|
|
1345
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1346
|
+
sage: v = K.valuation(1/x) # indirect doctest
|
|
1347
|
+
"""
|
|
1348
|
+
def __init__(self, parent):
|
|
1349
|
+
r"""
|
|
1350
|
+
TESTS::
|
|
1351
|
+
|
|
1352
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1353
|
+
sage: v = K.valuation(1/x) # indirect doctest
|
|
1354
|
+
sage: from sage.rings.function_field.valuation import InfiniteRationalFunctionFieldValuation
|
|
1355
|
+
sage: isinstance(v, InfiniteRationalFunctionFieldValuation)
|
|
1356
|
+
True
|
|
1357
|
+
"""
|
|
1358
|
+
x = parent.domain().gen()
|
|
1359
|
+
FunctionFieldMappedValuationRelative_base.__init__(self, parent, FunctionFieldValuation(parent.domain(), x), parent.domain().hom([1/x]), parent.domain().hom([1/x]))
|
|
1360
|
+
RationalFunctionFieldValuation_base.__init__(self, parent)
|
|
1361
|
+
ClassicalFunctionFieldValuation_base.__init__(self, parent)
|
|
1362
|
+
|
|
1363
|
+
def _repr_(self):
|
|
1364
|
+
r"""
|
|
1365
|
+
Return a printable representation of this valuation.
|
|
1366
|
+
|
|
1367
|
+
EXAMPLES::
|
|
1368
|
+
|
|
1369
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1370
|
+
sage: K.valuation(1/x) # indirect doctest
|
|
1371
|
+
Valuation at the infinite place
|
|
1372
|
+
"""
|
|
1373
|
+
return "Valuation at the infinite place"
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
class FunctionFieldExtensionMappedValuation(FunctionFieldMappedValuationRelative_base):
|
|
1377
|
+
r"""
|
|
1378
|
+
A valuation on a finite extensions of function fields `L=K[y]/(G)` where `K` is
|
|
1379
|
+
another function field which redirects to another ``base_valuation`` on an
|
|
1380
|
+
isomorphism function field `M=K[y]/(H)`.
|
|
1381
|
+
|
|
1382
|
+
The isomorphisms must be trivial on ``K``.
|
|
1383
|
+
|
|
1384
|
+
EXAMPLES::
|
|
1385
|
+
|
|
1386
|
+
sage: # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1387
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1388
|
+
sage: R.<y> = K[]
|
|
1389
|
+
sage: L.<y> = K.extension(y^2 + y + x^3)
|
|
1390
|
+
sage: v = K.valuation(1/x)
|
|
1391
|
+
sage: w = v.extension(L)
|
|
1392
|
+
sage: w(x)
|
|
1393
|
+
-1
|
|
1394
|
+
sage: w(y)
|
|
1395
|
+
-3/2
|
|
1396
|
+
sage: w.uniformizer()
|
|
1397
|
+
1/x^2*y
|
|
1398
|
+
|
|
1399
|
+
TESTS::
|
|
1400
|
+
|
|
1401
|
+
sage: from sage.rings.function_field.valuation import FunctionFieldExtensionMappedValuation
|
|
1402
|
+
sage: isinstance(w, FunctionFieldExtensionMappedValuation) # needs sage.geometry.polyhedron sage.rings.function_field
|
|
1403
|
+
True
|
|
1404
|
+
"""
|
|
1405
|
+
def _repr_(self):
|
|
1406
|
+
r"""
|
|
1407
|
+
Return a printable representation of this valuation.
|
|
1408
|
+
|
|
1409
|
+
EXAMPLES::
|
|
1410
|
+
|
|
1411
|
+
sage: # needs sage.rings.function_field
|
|
1412
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1413
|
+
sage: R.<y> = K[]
|
|
1414
|
+
sage: L.<y> = K.extension(y^2 + y + x^3)
|
|
1415
|
+
sage: v = K.valuation(1/x)
|
|
1416
|
+
sage: w = v.extension(L); w # needs sage.geometry.polyhedron
|
|
1417
|
+
Valuation at the infinite place
|
|
1418
|
+
|
|
1419
|
+
sage: # needs sage.rings.function_field
|
|
1420
|
+
sage: K.<x> = FunctionField(QQ)
|
|
1421
|
+
sage: R.<y> = K[]
|
|
1422
|
+
sage: L.<y> = K.extension(y^2 - 1/x^2 - 1)
|
|
1423
|
+
sage: v = K.valuation(1/x)
|
|
1424
|
+
sage: w = v.extensions(L); w # needs sage.geometry.polyhedron
|
|
1425
|
+
[[ Valuation at the infinite place, v(y + 1) = 2 ]-adic valuation,
|
|
1426
|
+
[ Valuation at the infinite place, v(y - 1) = 2 ]-adic valuation]
|
|
1427
|
+
"""
|
|
1428
|
+
assert (self.domain().base() is not self.domain())
|
|
1429
|
+
if repr(self._base_valuation) == repr(self.restriction(self.domain().base())):
|
|
1430
|
+
return repr(self._base_valuation)
|
|
1431
|
+
return super()._repr_()
|
|
1432
|
+
|
|
1433
|
+
def restriction(self, ring):
|
|
1434
|
+
r"""
|
|
1435
|
+
Return the restriction of this valuation to ``ring``.
|
|
1436
|
+
|
|
1437
|
+
EXAMPLES::
|
|
1438
|
+
|
|
1439
|
+
sage: # needs sage.rings.function_field
|
|
1440
|
+
sage: K.<x> = FunctionField(GF(2))
|
|
1441
|
+
sage: R.<y> = K[]
|
|
1442
|
+
sage: L.<y> = K.extension(y^2 + y + x^3)
|
|
1443
|
+
sage: v = K.valuation(1/x)
|
|
1444
|
+
sage: w = v.extension(L) # needs sage.geometry.polyhedron
|
|
1445
|
+
sage: w.restriction(K) is v # needs sage.geometry.polyhedron
|
|
1446
|
+
True
|
|
1447
|
+
"""
|
|
1448
|
+
if ring.is_subring(self.domain().base()):
|
|
1449
|
+
return self._base_valuation.restriction(ring)
|
|
1450
|
+
return super().restriction(ring)
|