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,3464 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
"""
|
|
3
|
+
Tate algebra element
|
|
4
|
+
|
|
5
|
+
A class for series in Tate algebras.
|
|
6
|
+
|
|
7
|
+
AUTHOR:
|
|
8
|
+
|
|
9
|
+
- Xavier Caruso, Thibaut Verron (2018-09)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# ***************************************************************************
|
|
13
|
+
# Copyright (C) 2018 Xavier Caruso <xavier.caruso@normalesup.org>
|
|
14
|
+
# Thibaut Verron <thibaut.verron@gmail.com>
|
|
15
|
+
#
|
|
16
|
+
# This program is free software: you can redistribute it and/or modify
|
|
17
|
+
# it under the terms of the GNU General Public License as published by
|
|
18
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
19
|
+
# (at your option) any later version.
|
|
20
|
+
# https://www.gnu.org/licenses/
|
|
21
|
+
# ***************************************************************************
|
|
22
|
+
|
|
23
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
24
|
+
from sage.structure.richcmp cimport rich_to_bool_sgn
|
|
25
|
+
from sage.structure.element import coerce_binop
|
|
26
|
+
|
|
27
|
+
from sage.structure.element cimport Element
|
|
28
|
+
from sage.structure.element cimport MonoidElement
|
|
29
|
+
from sage.structure.element cimport CommutativeAlgebraElement
|
|
30
|
+
|
|
31
|
+
from sage.rings.infinity import Infinity
|
|
32
|
+
from sage.rings.integer_ring import ZZ
|
|
33
|
+
from sage.rings.rational_field import QQ
|
|
34
|
+
|
|
35
|
+
from sage.rings.polynomial.polydict cimport PolyDict
|
|
36
|
+
from sage.rings.polynomial.polydict cimport ETuple
|
|
37
|
+
from sage.rings.padics.padic_generic_element cimport pAdicGenericElement
|
|
38
|
+
from sage.rings.padics.precision_error import PrecisionError
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _pushout_family(elements, initial=ZZ):
|
|
42
|
+
"""
|
|
43
|
+
Return a parent in which ``initial`` and all elements
|
|
44
|
+
in ``elements`` coerce.
|
|
45
|
+
|
|
46
|
+
INPUT:
|
|
47
|
+
|
|
48
|
+
- ``elements`` -- list of elements
|
|
49
|
+
|
|
50
|
+
- ``initial`` -- a parent
|
|
51
|
+
|
|
52
|
+
EXAMPLES::
|
|
53
|
+
|
|
54
|
+
sage: from sage.rings.tate_algebra_element import _pushout_family
|
|
55
|
+
|
|
56
|
+
sage: R = Zp(2)
|
|
57
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
58
|
+
sage: S.<a> = Zq(4) # needs sage.libs.ntl
|
|
59
|
+
|
|
60
|
+
sage: _pushout_family([a, x, 3]) # needs sage.libs.ntl
|
|
61
|
+
Tate Algebra in x (val >= 0), y (val >= 0)
|
|
62
|
+
over 2-adic Unramified Extension Field in a defined by x^2 + x + 1
|
|
63
|
+
"""
|
|
64
|
+
from sage.structure.coerce_exceptions import CoercionException
|
|
65
|
+
from sage.categories.pushout import pushout
|
|
66
|
+
A = initial
|
|
67
|
+
for elt in elements:
|
|
68
|
+
if not isinstance(elt, Element):
|
|
69
|
+
raise TypeError("cannot coerce all the elements to the same parent")
|
|
70
|
+
try:
|
|
71
|
+
A = pushout(A, elt.parent())
|
|
72
|
+
except CoercionException:
|
|
73
|
+
raise TypeError("cannot coerce all the elements to the same parent")
|
|
74
|
+
return A
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
cdef class TateAlgebraTerm(MonoidElement):
|
|
78
|
+
r"""
|
|
79
|
+
A class for Tate algebra terms.
|
|
80
|
+
|
|
81
|
+
A term in `K\{X_1,\dots,X_n\}` is the product of a coefficient in `K` and a
|
|
82
|
+
monomial in the variables `X_1,\dots,X_n`.
|
|
83
|
+
|
|
84
|
+
Those terms form a partially ordered monoid, with term multiplication and the
|
|
85
|
+
term order of the parent Tate algebra.
|
|
86
|
+
|
|
87
|
+
INPUT:
|
|
88
|
+
|
|
89
|
+
- ``coeff`` -- an element in the base field
|
|
90
|
+
|
|
91
|
+
- ``exponent`` -- tuple of length ``n``
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
96
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
97
|
+
sage: T = A.monoid_of_terms(); T
|
|
98
|
+
Monoid of terms in x (val >= 0), y (val >= 0)
|
|
99
|
+
over 2-adic Field with capped relative precision 10
|
|
100
|
+
|
|
101
|
+
sage: T(2*x*y)
|
|
102
|
+
...00000000010*x*y
|
|
103
|
+
sage: T(0)
|
|
104
|
+
Traceback (most recent call last):
|
|
105
|
+
...
|
|
106
|
+
TypeError: a term cannot be zero
|
|
107
|
+
"""
|
|
108
|
+
def __init__(self, parent, coeff, exponent=None):
|
|
109
|
+
"""
|
|
110
|
+
Initialize a Tate algebra term.
|
|
111
|
+
|
|
112
|
+
INPUT:
|
|
113
|
+
|
|
114
|
+
- ``coeff`` -- an element in the base field
|
|
115
|
+
|
|
116
|
+
- ``exponent`` -- tuple
|
|
117
|
+
|
|
118
|
+
TESTS::
|
|
119
|
+
|
|
120
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
121
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
122
|
+
sage: T = A.monoid_of_terms()
|
|
123
|
+
|
|
124
|
+
sage: t = T(x)
|
|
125
|
+
sage: TestSuite(t).run()
|
|
126
|
+
"""
|
|
127
|
+
MonoidElement.__init__(self, parent)
|
|
128
|
+
field = parent.base_ring().fraction_field()
|
|
129
|
+
if isinstance(coeff, TateAlgebraElement):
|
|
130
|
+
coeff = coeff.leading_term()
|
|
131
|
+
if isinstance(coeff, TateAlgebraTerm):
|
|
132
|
+
if coeff.parent().variable_names() != self._parent.variable_names():
|
|
133
|
+
raise ValueError("the variable names do not match")
|
|
134
|
+
self._coeff = field((<TateAlgebraTerm>coeff)._coeff)
|
|
135
|
+
self._exponent = (<TateAlgebraTerm>coeff)._exponent
|
|
136
|
+
else:
|
|
137
|
+
self._coeff = field(coeff)
|
|
138
|
+
if self._coeff.is_zero():
|
|
139
|
+
raise TypeError("a term cannot be zero")
|
|
140
|
+
self._exponent = ETuple([0] * parent.ngens())
|
|
141
|
+
if exponent is not None:
|
|
142
|
+
if not isinstance(exponent, ETuple):
|
|
143
|
+
exponent = ETuple(exponent)
|
|
144
|
+
self._exponent = self._exponent.eadd(exponent)
|
|
145
|
+
if len(self._exponent) != parent.ngens():
|
|
146
|
+
raise ValueError("the length of the exponent does not match the number of variables")
|
|
147
|
+
for i in self._exponent.nonzero_positions():
|
|
148
|
+
if self._exponent[i] < 0:
|
|
149
|
+
raise ValueError("only nonnegative exponents are allowed")
|
|
150
|
+
if not parent.base_ring().is_field() and self.valuation() < 0:
|
|
151
|
+
raise ValueError("this term is not in the ring of integers")
|
|
152
|
+
|
|
153
|
+
def __hash__(self):
|
|
154
|
+
"""
|
|
155
|
+
Return a hash of this term.
|
|
156
|
+
|
|
157
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
158
|
+
sage: A.<x,y> = TateAlgebra(R);
|
|
159
|
+
sage: T = A.monoid_of_terms()
|
|
160
|
+
sage: t = T(x^2)
|
|
161
|
+
|
|
162
|
+
sage: hash(t) == hash((t.coefficient(), t.exponent()))
|
|
163
|
+
True
|
|
164
|
+
"""
|
|
165
|
+
return hash((self._coeff, self._exponent))
|
|
166
|
+
|
|
167
|
+
cdef TateAlgebraTerm _new_c(self):
|
|
168
|
+
r"""
|
|
169
|
+
Fast creation of a Tate algebra term.
|
|
170
|
+
|
|
171
|
+
TESTS::
|
|
172
|
+
|
|
173
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
174
|
+
sage: A.<x,y> = TateAlgebra(R);
|
|
175
|
+
sage: T = A.monoid_of_terms(); T
|
|
176
|
+
Monoid of terms in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 10
|
|
177
|
+
sage: t = T(x*y); t
|
|
178
|
+
...0000000001*x*y
|
|
179
|
+
sage: 2*t # indirect doctest
|
|
180
|
+
...00000000010*x*y
|
|
181
|
+
"""
|
|
182
|
+
cdef TateAlgebraTerm ans = TateAlgebraTerm.__new__(TateAlgebraTerm)
|
|
183
|
+
ans._parent = self._parent
|
|
184
|
+
return ans
|
|
185
|
+
|
|
186
|
+
def __reduce__(self):
|
|
187
|
+
"""
|
|
188
|
+
Return a tuple of a function and data that can be used to unpickle this
|
|
189
|
+
element.
|
|
190
|
+
|
|
191
|
+
TESTS::
|
|
192
|
+
|
|
193
|
+
sage: A.<x,y> = TateAlgebra(Zp(2))
|
|
194
|
+
sage: t = x.leading_term()
|
|
195
|
+
sage: loads(dumps(t)) == t # indirect doctest
|
|
196
|
+
True
|
|
197
|
+
"""
|
|
198
|
+
return TateAlgebraTerm, (self.parent(), self._coeff, self._exponent)
|
|
199
|
+
|
|
200
|
+
def __bool__(self):
|
|
201
|
+
r"""
|
|
202
|
+
Return ``True`` if this term is nonzero, ``False`` otherwise.
|
|
203
|
+
|
|
204
|
+
TESTS::
|
|
205
|
+
|
|
206
|
+
sage: A.<x,y> = TateAlgebra(Zp(2))
|
|
207
|
+
sage: t = x.leading_term()
|
|
208
|
+
sage: bool(t)
|
|
209
|
+
True
|
|
210
|
+
"""
|
|
211
|
+
return bool(self._coeff)
|
|
212
|
+
|
|
213
|
+
def _repr_(self):
|
|
214
|
+
r"""
|
|
215
|
+
Return a string representation of this Tate algebra term.
|
|
216
|
+
|
|
217
|
+
EXAMPLES::
|
|
218
|
+
|
|
219
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
220
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
221
|
+
sage: T = A.monoid_of_terms()
|
|
222
|
+
sage: T(2*x*y) # indirect doctest
|
|
223
|
+
...00000000010*x*y
|
|
224
|
+
"""
|
|
225
|
+
parent = self._parent
|
|
226
|
+
if self._coeff._is_atomic() or (-self._coeff)._is_atomic():
|
|
227
|
+
s = repr(self._coeff)
|
|
228
|
+
if s == "1": s = ""
|
|
229
|
+
else:
|
|
230
|
+
s = "(%s)" % self._coeff
|
|
231
|
+
for i in range(parent._ngens):
|
|
232
|
+
if self._exponent[i] == 1:
|
|
233
|
+
s += "*%s" % parent._names[i]
|
|
234
|
+
elif self._exponent[i] > 1:
|
|
235
|
+
s += "*%s^%s" % (parent._names[i], self._exponent[i])
|
|
236
|
+
if s[0] == "*":
|
|
237
|
+
return s[1:]
|
|
238
|
+
else:
|
|
239
|
+
return s
|
|
240
|
+
|
|
241
|
+
def _latex_(self):
|
|
242
|
+
r"""
|
|
243
|
+
Return a LaTeX representation of this Tate algebra term.
|
|
244
|
+
|
|
245
|
+
EXAMPLES::
|
|
246
|
+
|
|
247
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
248
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
249
|
+
sage: T = A.monoid_of_terms()
|
|
250
|
+
sage: T(2*x*y)
|
|
251
|
+
...00000000010*x*y
|
|
252
|
+
sage: T(2*x*y)._latex_()
|
|
253
|
+
'...00000000010xy'
|
|
254
|
+
"""
|
|
255
|
+
parent = self._parent
|
|
256
|
+
s = ""
|
|
257
|
+
if self._coeff._is_atomic() or (-self._coeff)._is_atomic():
|
|
258
|
+
s = self._coeff._latex_()
|
|
259
|
+
if s == "1": s = ""
|
|
260
|
+
else:
|
|
261
|
+
s = "\\left(%s\\right)" % self._coeff._latex_()
|
|
262
|
+
for i in range(parent._ngens):
|
|
263
|
+
if self._exponent[i] == 1:
|
|
264
|
+
s += "%s" % parent._latex_names[i]
|
|
265
|
+
elif self._exponent[i] > 1:
|
|
266
|
+
s += "%s^{%s}" % (parent._latex_names[i], self._exponent[i])
|
|
267
|
+
if s[0] == "*":
|
|
268
|
+
return s[1:]
|
|
269
|
+
else:
|
|
270
|
+
return s
|
|
271
|
+
|
|
272
|
+
def coefficient(self):
|
|
273
|
+
r"""
|
|
274
|
+
Return the coefficient of this Tate algebra term.
|
|
275
|
+
|
|
276
|
+
EXAMPLES::
|
|
277
|
+
|
|
278
|
+
sage: R = Zp(2,prec=10)
|
|
279
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
280
|
+
sage: T = A.monoid_of_terms()
|
|
281
|
+
sage: t = T(2*x*y); t
|
|
282
|
+
(2 + O(2^11))*x*y
|
|
283
|
+
sage: t.coefficient()
|
|
284
|
+
2 + O(2^11)
|
|
285
|
+
"""
|
|
286
|
+
return self._coeff
|
|
287
|
+
|
|
288
|
+
def exponent(self):
|
|
289
|
+
r"""
|
|
290
|
+
Return the exponents of this Tate algebra term.
|
|
291
|
+
|
|
292
|
+
EXAMPLES::
|
|
293
|
+
|
|
294
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
295
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
296
|
+
sage: T = A.monoid_of_terms(); T
|
|
297
|
+
Monoid of terms in x (val >= 0), y (val >= 0)
|
|
298
|
+
over 2-adic Field with capped relative precision 10
|
|
299
|
+
sage: t = T(2,(1,1))
|
|
300
|
+
sage: t.exponent()
|
|
301
|
+
(1, 1)
|
|
302
|
+
"""
|
|
303
|
+
return self._exponent
|
|
304
|
+
|
|
305
|
+
cpdef _mul_(self, other):
|
|
306
|
+
r"""
|
|
307
|
+
Return the product of this Tate algebra term with ``other``.
|
|
308
|
+
|
|
309
|
+
INPUT:
|
|
310
|
+
|
|
311
|
+
- ``other`` -- a Tate algebra term
|
|
312
|
+
|
|
313
|
+
EXAMPLES::
|
|
314
|
+
|
|
315
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
316
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
317
|
+
sage: T = A.monoid_of_terms()
|
|
318
|
+
sage: s = T(2*x*y); s
|
|
319
|
+
...00000000010*x*y
|
|
320
|
+
sage: t = T(3*x^2*y); t
|
|
321
|
+
...0000000011*x^2*y
|
|
322
|
+
sage: s*t # indirect doctest
|
|
323
|
+
...00000000110*x^3*y^2
|
|
324
|
+
"""
|
|
325
|
+
cdef TateAlgebraTerm ans = self._new_c()
|
|
326
|
+
ans._exponent = self._exponent.eadd((<TateAlgebraTerm>other)._exponent)
|
|
327
|
+
ans._coeff = self._coeff * (<TateAlgebraTerm>other)._coeff
|
|
328
|
+
return ans
|
|
329
|
+
|
|
330
|
+
#def _div_(self, other):
|
|
331
|
+
# """
|
|
332
|
+
# Division of Tate series.
|
|
333
|
+
#
|
|
334
|
+
# It is currently not implemented because fraction fields
|
|
335
|
+
# of Tate algebras are not implemented.
|
|
336
|
+
#
|
|
337
|
+
# EXAMPLES::
|
|
338
|
+
#
|
|
339
|
+
# sage: A.<x,y> = TateAlgebra(Zp(2))
|
|
340
|
+
# sage! x / y
|
|
341
|
+
# Traceback (most recent call last):
|
|
342
|
+
# ...
|
|
343
|
+
# NotImplementedError: fraction fields of Tate algebras are not implemented; try inverse_of_unit()
|
|
344
|
+
#
|
|
345
|
+
# sage: ~x # indirect doctest
|
|
346
|
+
# Traceback (most recent call last):
|
|
347
|
+
# ...
|
|
348
|
+
# NotImplementedError: fraction fields of Tate algebras are not implemented; try inverse_of_unit()
|
|
349
|
+
#
|
|
350
|
+
# """
|
|
351
|
+
# raise NotImplementedError("fraction fields of Tate algebras are not implemented; try inverse_of_unit()")
|
|
352
|
+
|
|
353
|
+
cdef long _cmp_c(self, TateAlgebraTerm other) except? 300:
|
|
354
|
+
r"""
|
|
355
|
+
Compare the Tate algebra term with ``other``.
|
|
356
|
+
|
|
357
|
+
INPUT:
|
|
358
|
+
|
|
359
|
+
- ``other`` -- a term
|
|
360
|
+
|
|
361
|
+
EXAMPLES::
|
|
362
|
+
|
|
363
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
364
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
365
|
+
sage: T = A.monoid_of_terms()
|
|
366
|
+
sage: s = T(x^2*y^2)
|
|
367
|
+
sage: t = T(x*y^3)
|
|
368
|
+
sage: s > t # indirect doctest
|
|
369
|
+
True
|
|
370
|
+
"""
|
|
371
|
+
cdef long c = other._valuation_c() - self._valuation_c()
|
|
372
|
+
if not c:
|
|
373
|
+
skey = self._parent._sortkey
|
|
374
|
+
ks = skey(self._exponent)
|
|
375
|
+
ko = skey(other._exponent)
|
|
376
|
+
c = (ks > ko) - (ks < ko)
|
|
377
|
+
return c
|
|
378
|
+
|
|
379
|
+
cpdef _richcmp_(self, other, int op):
|
|
380
|
+
r"""
|
|
381
|
+
Compare the Tate algebra term with ``other`` according to
|
|
382
|
+
the rich comparison operator ``op``.
|
|
383
|
+
|
|
384
|
+
The term `a*X^A` is smaller or equal to `b*X^B` if its valuation is
|
|
385
|
+
greater than the valuation of `b*X^B`, or when equality occurs, when
|
|
386
|
+
`A` is smaller or equal to `B` for the Tate algebra monomial order.
|
|
387
|
+
|
|
388
|
+
INPUT:
|
|
389
|
+
|
|
390
|
+
- ``other`` -- a Tate algebra term
|
|
391
|
+
|
|
392
|
+
- ``op`` -- the comparison operator
|
|
393
|
+
|
|
394
|
+
EXAMPLES::
|
|
395
|
+
|
|
396
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
397
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
398
|
+
sage: T = A.monoid_of_terms()
|
|
399
|
+
sage: T.term_order()
|
|
400
|
+
Degree reverse lexicographic term order
|
|
401
|
+
sage: s = T(x^2*y^2); s
|
|
402
|
+
...0000000001*x^2*y^2
|
|
403
|
+
sage: t = T(x*y^3); t
|
|
404
|
+
...0000000001*x*y^3
|
|
405
|
+
sage: s < t # indirect doctest
|
|
406
|
+
False
|
|
407
|
+
sage: s > t # indirect doctest
|
|
408
|
+
True
|
|
409
|
+
sage: s <= t # indirect doctest
|
|
410
|
+
False
|
|
411
|
+
sage: s >= t # indirect doctest
|
|
412
|
+
True
|
|
413
|
+
|
|
414
|
+
Elements with the same valuation and monomial are equivalent
|
|
415
|
+
for the preorder::
|
|
416
|
+
|
|
417
|
+
sage: ss = T(3*x^2*y^2); ss
|
|
418
|
+
...0000000011*x^2*y^2
|
|
419
|
+
sage: s < ss # indirect doctest
|
|
420
|
+
False
|
|
421
|
+
sage: s > ss # indirect doctest
|
|
422
|
+
False
|
|
423
|
+
sage: s <= ss # indirect doctest
|
|
424
|
+
True
|
|
425
|
+
sage: s >= ss # indirect doctest
|
|
426
|
+
True
|
|
427
|
+
sage: s == ss
|
|
428
|
+
False
|
|
429
|
+
"""
|
|
430
|
+
if op == Py_EQ:
|
|
431
|
+
return ((<TateAlgebraTerm>self)._coeff == (<TateAlgebraTerm>other)._coeff
|
|
432
|
+
and (<TateAlgebraTerm>self)._exponent == (<TateAlgebraTerm>other)._exponent)
|
|
433
|
+
if op == Py_NE:
|
|
434
|
+
return ((<TateAlgebraTerm>self)._coeff != (<TateAlgebraTerm>other)._coeff
|
|
435
|
+
or (<TateAlgebraTerm>self)._exponent != (<TateAlgebraTerm>other)._exponent)
|
|
436
|
+
c = (<TateAlgebraTerm>self)._cmp_c(<TateAlgebraTerm>other)
|
|
437
|
+
return rich_to_bool_sgn(op, c)
|
|
438
|
+
|
|
439
|
+
cpdef TateAlgebraTerm monomial(self):
|
|
440
|
+
r"""
|
|
441
|
+
Return this term divided by its coefficient.
|
|
442
|
+
|
|
443
|
+
EXAMPLES::
|
|
444
|
+
|
|
445
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
446
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
447
|
+
sage: T = A.monoid_of_terms()
|
|
448
|
+
sage: s = T(3*x^2*y^2); s
|
|
449
|
+
...0000000011*x^2*y^2
|
|
450
|
+
sage: s.monomial()
|
|
451
|
+
...0000000001*x^2*y^2
|
|
452
|
+
"""
|
|
453
|
+
cdef TateAlgebraTerm ans = self._new_c()
|
|
454
|
+
ans._coeff = self._parent._field(1)
|
|
455
|
+
ans._exponent = self._exponent
|
|
456
|
+
return ans
|
|
457
|
+
|
|
458
|
+
cpdef TateAlgebraTerm monic(self):
|
|
459
|
+
r"""
|
|
460
|
+
Return this term normalized so that it has valuation 0
|
|
461
|
+
and its coefficient is a power of the uniformizer.
|
|
462
|
+
|
|
463
|
+
EXAMPLES:
|
|
464
|
+
|
|
465
|
+
When the log radii of convergence are all zero, the
|
|
466
|
+
coefficient of the returned term is `1`. In this case,
|
|
467
|
+
this method does the same thing as :meth:`monomial`::
|
|
468
|
+
|
|
469
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
470
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
471
|
+
sage: T = A.monoid_of_terms()
|
|
472
|
+
sage: s = T(3*x^2*y^2); s
|
|
473
|
+
...0000000011*x^2*y^2
|
|
474
|
+
sage: s.monic()
|
|
475
|
+
...0000000001*x^2*y^2
|
|
476
|
+
sage: s.monomial()
|
|
477
|
+
...0000000001*x^2*y^2
|
|
478
|
+
|
|
479
|
+
However, when log radii do not vanish, behaviors might
|
|
480
|
+
be different::
|
|
481
|
+
|
|
482
|
+
sage: A.<x,y> = TateAlgebra(R, log_radii=1)
|
|
483
|
+
sage: T = A.monoid_of_terms()
|
|
484
|
+
sage: s = T(3*x^2*y^2); s
|
|
485
|
+
...0000000011*x^2*y^2
|
|
486
|
+
sage: s.monic()
|
|
487
|
+
...00000000010000*x^2*y^2
|
|
488
|
+
sage: s.monomial()
|
|
489
|
+
...0000000001*x^2*y^2
|
|
490
|
+
|
|
491
|
+
We compare the valuations::
|
|
492
|
+
|
|
493
|
+
sage: s.monic().valuation()
|
|
494
|
+
0
|
|
495
|
+
sage: s.monomial().valuation()
|
|
496
|
+
-4
|
|
497
|
+
"""
|
|
498
|
+
cdef TateAlgebraTerm ans = self._new_c()
|
|
499
|
+
cdef long v = self._exponent.dotprod(self._parent._log_radii)
|
|
500
|
+
ans._coeff = self._parent._field.uniformizer_pow(v)
|
|
501
|
+
ans._exponent = self._exponent
|
|
502
|
+
return ans
|
|
503
|
+
|
|
504
|
+
def valuation(self):
|
|
505
|
+
r"""
|
|
506
|
+
Return the valuation of this term.
|
|
507
|
+
|
|
508
|
+
EXAMPLES::
|
|
509
|
+
|
|
510
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
511
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
512
|
+
sage: T = A.monoid_of_terms()
|
|
513
|
+
sage: t = T(4*x^2*y^2); t
|
|
514
|
+
...000000000100*x^2*y^2
|
|
515
|
+
sage: t.valuation()
|
|
516
|
+
2
|
|
517
|
+
|
|
518
|
+
In case of nonzero log radii, the valuations of the variables
|
|
519
|
+
contribute::
|
|
520
|
+
|
|
521
|
+
sage: A.<x,y> = TateAlgebra(R, log_radii=1)
|
|
522
|
+
sage: T = A.monoid_of_terms()
|
|
523
|
+
sage: t = T(4*x^2*y^2); t
|
|
524
|
+
...000000000100*x^2*y^2
|
|
525
|
+
sage: t.valuation()
|
|
526
|
+
-2
|
|
527
|
+
"""
|
|
528
|
+
return ZZ(self._valuation_c())
|
|
529
|
+
|
|
530
|
+
cdef long _valuation_c(self) noexcept:
|
|
531
|
+
r"""
|
|
532
|
+
Return the valuation of this term.
|
|
533
|
+
|
|
534
|
+
EXAMPLES::
|
|
535
|
+
|
|
536
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
537
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
538
|
+
sage: T = A.monoid_of_terms()
|
|
539
|
+
sage: t = T(4*x^2*y^2); t
|
|
540
|
+
...000000000100*x^2*y^2
|
|
541
|
+
sage: t.valuation() # indirect doctest
|
|
542
|
+
2
|
|
543
|
+
"""
|
|
544
|
+
return (<pAdicGenericElement>self._coeff).valuation_c() - <long>self._exponent.dotprod(self._parent._log_radii)
|
|
545
|
+
|
|
546
|
+
cdef Element _call_c(self, list arg):
|
|
547
|
+
"""
|
|
548
|
+
Return this term evaluated at ``args``.
|
|
549
|
+
|
|
550
|
+
INPUT:
|
|
551
|
+
|
|
552
|
+
- ``args`` -- elements
|
|
553
|
+
|
|
554
|
+
TESTS::
|
|
555
|
+
|
|
556
|
+
sage: R = Zp(2)
|
|
557
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
558
|
+
sage: M = A.monoid_of_terms()
|
|
559
|
+
sage: t = M(x*y)
|
|
560
|
+
sage: t(0, 1)
|
|
561
|
+
0
|
|
562
|
+
"""
|
|
563
|
+
cdef Element ans = self._coeff
|
|
564
|
+
cdef ETuple exponent = self._exponent
|
|
565
|
+
cdef size_t ind
|
|
566
|
+
for ind in range(exponent._nonzero):
|
|
567
|
+
ans *= arg[exponent._data[2*ind]] ** exponent._data[2*ind+1]
|
|
568
|
+
return ans
|
|
569
|
+
|
|
570
|
+
def __call__(self, *args):
|
|
571
|
+
"""
|
|
572
|
+
Return this term evaluated at ``args``.
|
|
573
|
+
|
|
574
|
+
INPUT:
|
|
575
|
+
|
|
576
|
+
- ``args`` -- elements
|
|
577
|
+
|
|
578
|
+
EXAMPLES::
|
|
579
|
+
|
|
580
|
+
sage: R = Zp(2)
|
|
581
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
582
|
+
sage: M = A.monoid_of_terms()
|
|
583
|
+
sage: t = M(x*y)
|
|
584
|
+
sage: t(1, 2)
|
|
585
|
+
2 + O(2^21)
|
|
586
|
+
|
|
587
|
+
An error is raised if we ask for the evaluation at one
|
|
588
|
+
point which is outside the domain of convergence::
|
|
589
|
+
|
|
590
|
+
sage: t(1/2, 1)
|
|
591
|
+
Traceback (most recent call last):
|
|
592
|
+
...
|
|
593
|
+
ValueError: not in the domain of convergence
|
|
594
|
+
|
|
595
|
+
TESTS::
|
|
596
|
+
|
|
597
|
+
sage: t(1/2, 1, 0)
|
|
598
|
+
Traceback (most recent call last):
|
|
599
|
+
...
|
|
600
|
+
TypeError: wrong number of arguments
|
|
601
|
+
|
|
602
|
+
sage: t(1/2, GF(3)(2))
|
|
603
|
+
Traceback (most recent call last):
|
|
604
|
+
...
|
|
605
|
+
TypeError: cannot coerce all the elements to the same parent
|
|
606
|
+
"""
|
|
607
|
+
parent = self._parent
|
|
608
|
+
if len(args) != parent._ngens:
|
|
609
|
+
raise TypeError("wrong number of arguments")
|
|
610
|
+
A = _pushout_family(args, parent._field)
|
|
611
|
+
args = [ A(arg) for arg in args ]
|
|
612
|
+
ratio = A.absolute_e() // parent._base.absolute_e()
|
|
613
|
+
for i in range(parent._ngens):
|
|
614
|
+
if args[i].valuation() < -ratio * parent._log_radii[i]:
|
|
615
|
+
raise ValueError("not in the domain of convergence")
|
|
616
|
+
res = self._call_c(args)
|
|
617
|
+
if parent._integral:
|
|
618
|
+
try:
|
|
619
|
+
res = res.parent().integer_ring()(res)
|
|
620
|
+
except AttributeError:
|
|
621
|
+
pass
|
|
622
|
+
return res
|
|
623
|
+
|
|
624
|
+
@coerce_binop
|
|
625
|
+
def is_coprime_with(self, other):
|
|
626
|
+
r"""
|
|
627
|
+
Return ``True`` if this term is coprime with ``other``.
|
|
628
|
+
|
|
629
|
+
INPUT:
|
|
630
|
+
|
|
631
|
+
- ``other`` -- a Tate term
|
|
632
|
+
|
|
633
|
+
EXAMPLES::
|
|
634
|
+
|
|
635
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
636
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
637
|
+
sage: T = A.monoid_of_terms()
|
|
638
|
+
sage: t = T(4*x^2*y^2); t
|
|
639
|
+
...000000000100*x^2*y^2
|
|
640
|
+
sage: s = T(y^3); s
|
|
641
|
+
...0000000001*y^3
|
|
642
|
+
sage: s.is_coprime_with(t)
|
|
643
|
+
False
|
|
644
|
+
sage: t.is_coprime_with(s)
|
|
645
|
+
False
|
|
646
|
+
|
|
647
|
+
sage: tt = T(3*x^2); tt
|
|
648
|
+
...0000000011*x^2
|
|
649
|
+
sage: s.is_coprime_with(tt)
|
|
650
|
+
True
|
|
651
|
+
sage: tt.is_coprime_with(s)
|
|
652
|
+
True
|
|
653
|
+
|
|
654
|
+
When working over a rational Tate algebra, only the
|
|
655
|
+
monomial part of terms are compared::
|
|
656
|
+
|
|
657
|
+
sage: t = T(2*x^2); t
|
|
658
|
+
...00000000010*x^2
|
|
659
|
+
sage: s = T(4*y^3); s
|
|
660
|
+
...000000000100*y^3
|
|
661
|
+
sage: s.is_coprime_with(t)
|
|
662
|
+
True
|
|
663
|
+
|
|
664
|
+
But coefficients play a role when we are working over
|
|
665
|
+
the ring of integers of the Tate Algebra::
|
|
666
|
+
|
|
667
|
+
sage: Ao = A.integer_ring()
|
|
668
|
+
sage: To = Ao.monoid_of_terms()
|
|
669
|
+
sage: To(s).is_coprime_with(To(t))
|
|
670
|
+
False
|
|
671
|
+
"""
|
|
672
|
+
for i in range(self._parent.ngens()):
|
|
673
|
+
if self._exponent[i] > 0 and other.exponent()[i] > 0:
|
|
674
|
+
return False
|
|
675
|
+
if self._parent.base_ring().is_field():
|
|
676
|
+
return True
|
|
677
|
+
else:
|
|
678
|
+
return self.valuation() == 0 or other.valuation() == 0
|
|
679
|
+
|
|
680
|
+
@coerce_binop
|
|
681
|
+
def gcd(self, other):
|
|
682
|
+
r"""
|
|
683
|
+
Return the greatest common divisor of this term and ``other``.
|
|
684
|
+
|
|
685
|
+
The result is normalized so that:
|
|
686
|
+
|
|
687
|
+
- its valuation is equal to the smallest valuation of
|
|
688
|
+
this term and ``other``
|
|
689
|
+
|
|
690
|
+
- its coefficient is a power of the uniformizer.
|
|
691
|
+
|
|
692
|
+
INPUT:
|
|
693
|
+
|
|
694
|
+
- ``other`` -- a Tate term
|
|
695
|
+
|
|
696
|
+
EXAMPLES::
|
|
697
|
+
|
|
698
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
699
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
700
|
+
sage: T = A.monoid_of_terms()
|
|
701
|
+
sage: s = T(8*x^2*y^2); s
|
|
702
|
+
...0000000001000*x^2*y^2
|
|
703
|
+
sage: t = T(4*x*y^3); t
|
|
704
|
+
...000000000100*x*y^3
|
|
705
|
+
sage: s.gcd(t)
|
|
706
|
+
...000000000100*x*y^2
|
|
707
|
+
"""
|
|
708
|
+
return self._gcd_c(other)
|
|
709
|
+
|
|
710
|
+
cdef TateAlgebraTerm _gcd_c(self, TateAlgebraTerm other):
|
|
711
|
+
r"""
|
|
712
|
+
Return the greatest common divisor of this term and ``other``.
|
|
713
|
+
|
|
714
|
+
The result is normalized so that:
|
|
715
|
+
|
|
716
|
+
- its valuation is equal to the smallest valuation of
|
|
717
|
+
this term and ``other``
|
|
718
|
+
|
|
719
|
+
- its coefficient is a power of the uniformizer.
|
|
720
|
+
|
|
721
|
+
INPUT:
|
|
722
|
+
|
|
723
|
+
- ``other`` -- a Tate term
|
|
724
|
+
|
|
725
|
+
EXAMPLES::
|
|
726
|
+
|
|
727
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
728
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
729
|
+
sage: T = A.monoid_of_terms()
|
|
730
|
+
sage: s = T(8*x^2*y^2); s
|
|
731
|
+
...0000000001000*x^2*y^2
|
|
732
|
+
sage: t = T(4*x*y^3); t
|
|
733
|
+
...000000000100*x*y^3
|
|
734
|
+
sage: s.gcd(t) # indirect doctest
|
|
735
|
+
...000000000100*x*y^2
|
|
736
|
+
|
|
737
|
+
::
|
|
738
|
+
|
|
739
|
+
sage: A.<x,y> = TateAlgebra(R, log_radii=1)
|
|
740
|
+
sage: T = A.monoid_of_terms()
|
|
741
|
+
sage: T(x^5).gcd(T(y^5))
|
|
742
|
+
...00000.00001
|
|
743
|
+
"""
|
|
744
|
+
cdef TateAlgebraTerm ans = self._new_c()
|
|
745
|
+
cdef long val
|
|
746
|
+
ans._exponent = self._exponent.emin(other._exponent)
|
|
747
|
+
val = min(self._valuation_c(), other._valuation_c()) + ans._exponent.dotprod(self._parent._log_radii)
|
|
748
|
+
ans._coeff = self._parent._field.uniformizer_pow(val)
|
|
749
|
+
return ans
|
|
750
|
+
|
|
751
|
+
@coerce_binop
|
|
752
|
+
def lcm(self, other):
|
|
753
|
+
r"""
|
|
754
|
+
Return the least common multiple of two Tate terms.
|
|
755
|
+
|
|
756
|
+
The result is normalized so that `\gcd(a,b) \lcm(a,b) = ab`.
|
|
757
|
+
|
|
758
|
+
INPUT:
|
|
759
|
+
|
|
760
|
+
- ``other`` -- a Tate term
|
|
761
|
+
|
|
762
|
+
EXAMPLES::
|
|
763
|
+
|
|
764
|
+
In a Tate algebra over a field:
|
|
765
|
+
|
|
766
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
767
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
768
|
+
sage: T = A.monoid_of_terms()
|
|
769
|
+
sage: s = T(8*x^2*y^2); s
|
|
770
|
+
...0000000001000*x^2*y^2
|
|
771
|
+
sage: t = T(4*x*y^3); t
|
|
772
|
+
...000000000100*x*y^3
|
|
773
|
+
sage: s.lcm(t)
|
|
774
|
+
...0000000001000*x^2*y^3
|
|
775
|
+
"""
|
|
776
|
+
return self._lcm_c(other)
|
|
777
|
+
|
|
778
|
+
cdef TateAlgebraTerm _lcm_c(self, TateAlgebraTerm other):
|
|
779
|
+
r"""
|
|
780
|
+
Return the least common multiple of two Tate terms.
|
|
781
|
+
|
|
782
|
+
The result is normalized so that `\gcd(a,b) \lcm(a,b) = ab`.
|
|
783
|
+
|
|
784
|
+
INPUT:
|
|
785
|
+
|
|
786
|
+
- ``other`` -- a Tate term
|
|
787
|
+
|
|
788
|
+
EXAMPLES::
|
|
789
|
+
|
|
790
|
+
In a Tate algebra over a field:
|
|
791
|
+
|
|
792
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
793
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
794
|
+
sage: T = A.monoid_of_terms()
|
|
795
|
+
sage: s = T(8*x^2*y^2); s
|
|
796
|
+
...0000000001000*x^2*y^2
|
|
797
|
+
sage: t = T(12*x*y^3); t
|
|
798
|
+
...000000001100*x*y^3
|
|
799
|
+
sage: s.lcm(t) # indirect doctest
|
|
800
|
+
...0000000011000*x^2*y^3
|
|
801
|
+
|
|
802
|
+
TESTS::
|
|
803
|
+
|
|
804
|
+
sage: s.gcd(t) * s.lcm(t) == s * t
|
|
805
|
+
True
|
|
806
|
+
"""
|
|
807
|
+
cdef TateAlgebraTerm ans = self._new_c()
|
|
808
|
+
cdef long val
|
|
809
|
+
ans._exponent = self._exponent.emax(other._exponent)
|
|
810
|
+
val = max(self._valuation_c(), other._valuation_c()) + ans._exponent.dotprod(self._parent._log_radii)
|
|
811
|
+
ans._coeff = (self._coeff.unit_part() * other._coeff.unit_part()) << val
|
|
812
|
+
return ans
|
|
813
|
+
|
|
814
|
+
@coerce_binop
|
|
815
|
+
def is_divisible_by(self, other, integral=False):
|
|
816
|
+
r"""
|
|
817
|
+
Return ``True`` if this term is divisible by ``other``.
|
|
818
|
+
|
|
819
|
+
INPUT:
|
|
820
|
+
|
|
821
|
+
- ``other`` -- a Tate term
|
|
822
|
+
|
|
823
|
+
- ``integral`` -- (default: ``False``) if ``True``, test
|
|
824
|
+
for divisibility in the ring of integers of the Tate algebra
|
|
825
|
+
|
|
826
|
+
EXAMPLES::
|
|
827
|
+
|
|
828
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
829
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
830
|
+
sage: T = A.monoid_of_terms()
|
|
831
|
+
sage: s = T(4*x^2*y^2); s
|
|
832
|
+
...000000000100*x^2*y^2
|
|
833
|
+
sage: t = T(4*x*y^3); t
|
|
834
|
+
...000000000100*x*y^3
|
|
835
|
+
sage: s.is_divisible_by(t)
|
|
836
|
+
False
|
|
837
|
+
|
|
838
|
+
sage: t = T(4*x*y^2); t
|
|
839
|
+
...000000000100*x*y^2
|
|
840
|
+
sage: s.is_divisible_by(t)
|
|
841
|
+
True
|
|
842
|
+
|
|
843
|
+
sage: t = T(16); t
|
|
844
|
+
...00000000010000
|
|
845
|
+
sage: s.is_divisible_by(t)
|
|
846
|
+
True
|
|
847
|
+
sage: s.is_divisible_by(t, integral=True)
|
|
848
|
+
False
|
|
849
|
+
|
|
850
|
+
If you are working over the ring of integers of the Tate algebra,
|
|
851
|
+
divisibility is always checked in the ring of integers (even if
|
|
852
|
+
``integral`` is set to ``False``)::
|
|
853
|
+
|
|
854
|
+
sage: Ao = A.integer_ring()
|
|
855
|
+
sage: To = Ao.monoid_of_terms()
|
|
856
|
+
sage: so = To(s)
|
|
857
|
+
sage: to = To(t)
|
|
858
|
+
sage: so.is_divisible_by(to)
|
|
859
|
+
False
|
|
860
|
+
sage: so.is_divisible_by(to, integral=False)
|
|
861
|
+
False
|
|
862
|
+
|
|
863
|
+
Be careful that coercion between the Tate algebra and its ring of
|
|
864
|
+
integers can be done silently::
|
|
865
|
+
|
|
866
|
+
sage: s.is_divisible_by(to)
|
|
867
|
+
True
|
|
868
|
+
"""
|
|
869
|
+
return (<TateAlgebraTerm?>other)._divides_c(self, integral)
|
|
870
|
+
|
|
871
|
+
@coerce_binop
|
|
872
|
+
def divides(self, other, integral=False):
|
|
873
|
+
r"""
|
|
874
|
+
Return ``True`` if this term divides ``other``.
|
|
875
|
+
|
|
876
|
+
INPUT:
|
|
877
|
+
|
|
878
|
+
- ``other`` -- a Tate term
|
|
879
|
+
|
|
880
|
+
- ``integral`` -- (default: ``False``) if ``True``, test for
|
|
881
|
+
divisibility in the ring of integers of the Tate algebra
|
|
882
|
+
|
|
883
|
+
EXAMPLES::
|
|
884
|
+
|
|
885
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
886
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
887
|
+
sage: T = A.monoid_of_terms()
|
|
888
|
+
sage: s = T(4*x^2*y^2); s
|
|
889
|
+
...000000000100*x^2*y^2
|
|
890
|
+
sage: t = T(4*x*y^3); t
|
|
891
|
+
...000000000100*x*y^3
|
|
892
|
+
sage: t.divides(s)
|
|
893
|
+
False
|
|
894
|
+
|
|
895
|
+
sage: t = T(4*x*y^2); t
|
|
896
|
+
...000000000100*x*y^2
|
|
897
|
+
sage: t.divides(s)
|
|
898
|
+
True
|
|
899
|
+
|
|
900
|
+
sage: t = T(16); t
|
|
901
|
+
...00000000010000
|
|
902
|
+
sage: t.divides(s)
|
|
903
|
+
True
|
|
904
|
+
sage: t.divides(s, integral=True)
|
|
905
|
+
False
|
|
906
|
+
|
|
907
|
+
If you are working over the ring of integers of the Tate algebra,
|
|
908
|
+
divisibility is always checked in the ring of integers (even if
|
|
909
|
+
``integral`` is set to ``False``)::
|
|
910
|
+
|
|
911
|
+
sage: Ao = A.integer_ring()
|
|
912
|
+
sage: To = Ao.monoid_of_terms()
|
|
913
|
+
sage: so = To(s)
|
|
914
|
+
sage: to = To(t)
|
|
915
|
+
sage: to.divides(so)
|
|
916
|
+
False
|
|
917
|
+
sage: to.divides(so, integral=False)
|
|
918
|
+
False
|
|
919
|
+
|
|
920
|
+
Be careful that coercion between the Tate algebra and its ring of
|
|
921
|
+
integers can be done silently::
|
|
922
|
+
|
|
923
|
+
sage: to.divides(s)
|
|
924
|
+
True
|
|
925
|
+
"""
|
|
926
|
+
return self._divides_c(other, integral)
|
|
927
|
+
|
|
928
|
+
cdef bint _divides_c(self, TateAlgebraTerm other, bint integral) noexcept:
|
|
929
|
+
r"""
|
|
930
|
+
Return ``True`` if this term divides ``other``.
|
|
931
|
+
|
|
932
|
+
INPUT:
|
|
933
|
+
|
|
934
|
+
- ``other`` -- a Tate term
|
|
935
|
+
|
|
936
|
+
- ``integral`` -- boolean (default: ``False``); if ``True``, test for
|
|
937
|
+
divisibility in the ring of integers of the Tate algebra
|
|
938
|
+
|
|
939
|
+
EXAMPLES::
|
|
940
|
+
|
|
941
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
942
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
943
|
+
sage: T = A.monoid_of_terms()
|
|
944
|
+
sage: s = T(4*x^2*y^2); s
|
|
945
|
+
...000000000100*x^2*y^2
|
|
946
|
+
sage: t = T(4*x*y^3); t
|
|
947
|
+
...000000000100*x*y^3
|
|
948
|
+
sage: t.divides(s) # indirect doctest
|
|
949
|
+
False
|
|
950
|
+
"""
|
|
951
|
+
parent = self._parent
|
|
952
|
+
if (integral or not parent.base_ring().is_field()) and self.valuation() > other.valuation():
|
|
953
|
+
return False
|
|
954
|
+
for i in range(parent._ngens):
|
|
955
|
+
if self._exponent[i] > other._exponent[i]:
|
|
956
|
+
return False
|
|
957
|
+
return True
|
|
958
|
+
|
|
959
|
+
cpdef _floordiv_(self, other):
|
|
960
|
+
r"""
|
|
961
|
+
Return the result of the exact division of this term by ``other``.
|
|
962
|
+
|
|
963
|
+
INPUT:
|
|
964
|
+
|
|
965
|
+
- ``other`` -- a Tate term
|
|
966
|
+
|
|
967
|
+
EXAMPLES::
|
|
968
|
+
|
|
969
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
970
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
971
|
+
sage: T = A.monoid_of_terms()
|
|
972
|
+
sage: t = T(2*x^2*y^3); t
|
|
973
|
+
...00000000010*x^2*y^3
|
|
974
|
+
sage: s = T(6*x*y^2); s
|
|
975
|
+
...00000000110*x*y^2
|
|
976
|
+
sage: t // s
|
|
977
|
+
...1010101011*x*y
|
|
978
|
+
|
|
979
|
+
If the Tate terms are not divisible, an error is raised::
|
|
980
|
+
|
|
981
|
+
sage: s // t
|
|
982
|
+
Traceback (most recent call last):
|
|
983
|
+
...
|
|
984
|
+
ValueError: the division is not exact
|
|
985
|
+
"""
|
|
986
|
+
if not self.is_divisible_by(other):
|
|
987
|
+
raise ValueError("the division is not exact")
|
|
988
|
+
return (<TateAlgebraTerm>self)._floordiv_c(<TateAlgebraTerm>other)
|
|
989
|
+
|
|
990
|
+
cdef TateAlgebraTerm _floordiv_c(self, TateAlgebraTerm other):
|
|
991
|
+
r"""
|
|
992
|
+
Return the result of the exact division of this term by ``other``.
|
|
993
|
+
|
|
994
|
+
INPUT:
|
|
995
|
+
|
|
996
|
+
- ``other`` -- a Tate term
|
|
997
|
+
|
|
998
|
+
EXAMPLES::
|
|
999
|
+
|
|
1000
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1001
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1002
|
+
sage: T = A.monoid_of_terms()
|
|
1003
|
+
sage: t = T(2*x^2*y^3); t
|
|
1004
|
+
...00000000010*x^2*y^3
|
|
1005
|
+
sage: s = T(6*x*y^2); s
|
|
1006
|
+
...00000000110*x*y^2
|
|
1007
|
+
sage: t // s
|
|
1008
|
+
...1010101011*x*y
|
|
1009
|
+
|
|
1010
|
+
If the Tate terms are not divisible, an error is raised::
|
|
1011
|
+
|
|
1012
|
+
sage: s // t
|
|
1013
|
+
Traceback (most recent call last):
|
|
1014
|
+
...
|
|
1015
|
+
ValueError: the division is not exact
|
|
1016
|
+
"""
|
|
1017
|
+
cdef TateAlgebraTerm ans = self._new_c()
|
|
1018
|
+
ans._exponent = self.exponent().esub(other.exponent())
|
|
1019
|
+
ans._coeff = self._coeff / other._coeff
|
|
1020
|
+
return ans
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
cdef class TateAlgebraElement(CommutativeAlgebraElement):
|
|
1024
|
+
r"""
|
|
1025
|
+
A class for Tate series, elements of Tate algebras.
|
|
1026
|
+
|
|
1027
|
+
EXAMPLES::
|
|
1028
|
+
|
|
1029
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
1030
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1031
|
+
sage: A(2*x+1)
|
|
1032
|
+
...0000000001 + ...00000000010*x
|
|
1033
|
+
sage: A(2*x+1, prec=5)
|
|
1034
|
+
...00001 + ...00010*x + O(2^5 * <x, y>)
|
|
1035
|
+
sage: A(2*x+1, prec=20)
|
|
1036
|
+
...0000000001 + ...00000000010*x + O(2^20 * <x, y>)
|
|
1037
|
+
"""
|
|
1038
|
+
def __init__(self, parent, x, prec=None, reduce=True):
|
|
1039
|
+
r"""
|
|
1040
|
+
Initialize a Tate algebra series.
|
|
1041
|
+
|
|
1042
|
+
TESTS::
|
|
1043
|
+
|
|
1044
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
1045
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1046
|
+
sage: TestSuite(x).run()
|
|
1047
|
+
"""
|
|
1048
|
+
cdef TateAlgebraElement xc
|
|
1049
|
+
CommutativeAlgebraElement.__init__(self, parent)
|
|
1050
|
+
self._prec = Infinity # TODO: replace infinity by a big int
|
|
1051
|
+
if isinstance(x, TateAlgebraElement):
|
|
1052
|
+
xc = <TateAlgebraElement>x
|
|
1053
|
+
xparent = x.parent()
|
|
1054
|
+
if xparent is parent:
|
|
1055
|
+
self._poly = PolyDict(xc._poly.__repn, None)
|
|
1056
|
+
self._prec = xc._prec
|
|
1057
|
+
elif xparent.variable_names() == parent.variable_names():
|
|
1058
|
+
ratio = parent._base.absolute_e() / xparent.base_ring().absolute_e()
|
|
1059
|
+
for i in range(parent.ngens()):
|
|
1060
|
+
if parent.log_radii()[i] > xparent.log_radii()[i] * ratio:
|
|
1061
|
+
raise ValueError("cannot restrict to a bigger domain")
|
|
1062
|
+
self._poly = PolyDict({ e: parent._field(v) for (e,v) in xc._poly.__repn.items() }, None)
|
|
1063
|
+
if xc._prec is not Infinity:
|
|
1064
|
+
self._prec = (xc._prec * ratio).ceil()
|
|
1065
|
+
else:
|
|
1066
|
+
raise TypeError("variable names do not match")
|
|
1067
|
+
elif isinstance(x, TateAlgebraTerm):
|
|
1068
|
+
xparent = x.parent()
|
|
1069
|
+
if xparent.variable_names() == parent.variable_names():
|
|
1070
|
+
ratio = parent._base.absolute_e() / xparent.base_ring().absolute_e()
|
|
1071
|
+
for i in range(parent.ngens()):
|
|
1072
|
+
if parent.log_radii()[i] > xparent.log_radii()[i] * ratio:
|
|
1073
|
+
raise ValueError("cannot restrict to a bigger domain")
|
|
1074
|
+
self._poly = PolyDict({(<TateAlgebraTerm>x)._exponent: parent._field((<TateAlgebraTerm>x)._coeff)}, None)
|
|
1075
|
+
else:
|
|
1076
|
+
try:
|
|
1077
|
+
poly = parent._polynomial_ring(x)
|
|
1078
|
+
self._poly = PolyDict(poly.monomial_coefficients(), None)
|
|
1079
|
+
except TypeError:
|
|
1080
|
+
# last chance: we first try to convert to the rational Tate series
|
|
1081
|
+
if parent._integral:
|
|
1082
|
+
xc = parent._rational_ring(x)
|
|
1083
|
+
self._poly = xc._poly
|
|
1084
|
+
self._prec = xc._prec
|
|
1085
|
+
else:
|
|
1086
|
+
raise
|
|
1087
|
+
if prec is not None:
|
|
1088
|
+
self._prec = min(self._prec, prec)
|
|
1089
|
+
self._normalize()
|
|
1090
|
+
self._terms = self._terms_nonzero = None
|
|
1091
|
+
if not parent.base_ring().is_field() and self.valuation() < 0:
|
|
1092
|
+
raise ValueError("this series is not in the ring of integers")
|
|
1093
|
+
|
|
1094
|
+
cdef TateAlgebraElement _new_c(self):
|
|
1095
|
+
"""
|
|
1096
|
+
Fast creation of a new Tate series.
|
|
1097
|
+
|
|
1098
|
+
EXAMPLES::
|
|
1099
|
+
|
|
1100
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
1101
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1102
|
+
sage: x + y # indirect doctest
|
|
1103
|
+
...0000000001*x + ...0000000001*y
|
|
1104
|
+
"""
|
|
1105
|
+
cdef TateAlgebraElement ans = TateAlgebraElement.__new__(TateAlgebraElement)
|
|
1106
|
+
ans._parent = self._parent
|
|
1107
|
+
ans._is_normalized = False
|
|
1108
|
+
ans._terms = ans._terms_nonzero = None
|
|
1109
|
+
return ans
|
|
1110
|
+
|
|
1111
|
+
cdef _normalize(self):
|
|
1112
|
+
"""
|
|
1113
|
+
Normalize this series.
|
|
1114
|
+
|
|
1115
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
1116
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1117
|
+
sage: A(78612, prec=3) # indirect doctest
|
|
1118
|
+
...100 + O(2^3 * <x, y>)
|
|
1119
|
+
|
|
1120
|
+
TESTS:
|
|
1121
|
+
|
|
1122
|
+
We check that :issue:`40046` is fixed::
|
|
1123
|
+
|
|
1124
|
+
sage: S.<x,y> = TateAlgebra(Qp(5), log_radii=(1,0))
|
|
1125
|
+
sage: f = 5*x
|
|
1126
|
+
sage: f.add_bigoh(1)
|
|
1127
|
+
(5 + O(5^2))*x + O(5 * <x/5, y>)
|
|
1128
|
+
"""
|
|
1129
|
+
self._is_normalized = True
|
|
1130
|
+
if self._prec is Infinity:
|
|
1131
|
+
return
|
|
1132
|
+
cdef int v
|
|
1133
|
+
cdef pAdicGenericElement coeff
|
|
1134
|
+
for (e, c) in list(self._poly.__repn.items()):
|
|
1135
|
+
v = (<ETuple>self._parent._log_radii).dotprod(<ETuple>e)
|
|
1136
|
+
coeff = self._poly.__repn[e]
|
|
1137
|
+
if coeff.precision_absolute() > self._prec + v:
|
|
1138
|
+
coeff = coeff.add_bigoh(self._prec + v)
|
|
1139
|
+
if coeff.valuation() >= self._prec + v:
|
|
1140
|
+
del self._poly.__repn[e]
|
|
1141
|
+
else:
|
|
1142
|
+
self._poly.__repn[e] = coeff
|
|
1143
|
+
|
|
1144
|
+
def __reduce__(self):
|
|
1145
|
+
"""
|
|
1146
|
+
Return a tuple of a function and data that can be used to unpickle this
|
|
1147
|
+
element.
|
|
1148
|
+
|
|
1149
|
+
TESTS::
|
|
1150
|
+
|
|
1151
|
+
sage: A.<x,y> = TateAlgebra(Zp(2))
|
|
1152
|
+
sage: loads(dumps(x)) == x # indirect doctest
|
|
1153
|
+
True
|
|
1154
|
+
"""
|
|
1155
|
+
return TateAlgebraElement, (self.parent(), self._poly, self._prec)
|
|
1156
|
+
|
|
1157
|
+
def _repr_(self):
|
|
1158
|
+
r"""
|
|
1159
|
+
Return a string representation of this series.
|
|
1160
|
+
|
|
1161
|
+
The terms are ordered with decreasing term order
|
|
1162
|
+
(increasing valuation, then the monomial order of the parent algebra).
|
|
1163
|
+
|
|
1164
|
+
EXAMPLES::
|
|
1165
|
+
|
|
1166
|
+
sage: R = Zp(2, 10, print_mode='digits')
|
|
1167
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1168
|
+
sage: x + 2*x^2 + x^3
|
|
1169
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1170
|
+
|
|
1171
|
+
sage: A(x + 2*x^2 + x^3, prec=5)
|
|
1172
|
+
...00001*x^3 + ...00001*x + ...00010*x^2 + O(2^5 * <x, y>)
|
|
1173
|
+
"""
|
|
1174
|
+
base = self._parent.base_ring()
|
|
1175
|
+
nvars = self._parent.ngens()
|
|
1176
|
+
vars = self._parent.variable_names()
|
|
1177
|
+
s = ""
|
|
1178
|
+
for t in self._terms_c():
|
|
1179
|
+
if t.valuation() >= self._prec:
|
|
1180
|
+
continue
|
|
1181
|
+
st = repr(t)
|
|
1182
|
+
if s == "":
|
|
1183
|
+
s += st
|
|
1184
|
+
elif st[0] == "-":
|
|
1185
|
+
s += " - " + st[1:]
|
|
1186
|
+
else:
|
|
1187
|
+
s += " + " + st
|
|
1188
|
+
if self._prec is not Infinity:
|
|
1189
|
+
if s != "":
|
|
1190
|
+
s += " + "
|
|
1191
|
+
su = self._parent._uniformizer_repr
|
|
1192
|
+
lr = self._parent.log_radii()
|
|
1193
|
+
sv = [ ]
|
|
1194
|
+
for i in range(len(vars)):
|
|
1195
|
+
if lr[i] == 0:
|
|
1196
|
+
sv.append(vars[i])
|
|
1197
|
+
elif lr[i] == -1:
|
|
1198
|
+
sv.append("%s*%s" % (su, vars[i]))
|
|
1199
|
+
elif lr[i] == 1:
|
|
1200
|
+
sv.append("%s/%s" % (vars[i], su))
|
|
1201
|
+
elif lr[i] < 0:
|
|
1202
|
+
sv.append("%s^%s*%s" % (su, -lr[i], vars[i]))
|
|
1203
|
+
else:
|
|
1204
|
+
sv.append("%s/%s^%s" % (vars[i], su, lr[i]))
|
|
1205
|
+
sv = ", ".join(sv)
|
|
1206
|
+
if self._prec == 0:
|
|
1207
|
+
s += "O(<%s>)" % sv
|
|
1208
|
+
elif self._prec == 1:
|
|
1209
|
+
s += "O(%s * <%s>)" % (self._parent._uniformizer_repr, sv)
|
|
1210
|
+
else:
|
|
1211
|
+
s += "O(%s^%s * <%s>)" % (self._parent._uniformizer_repr, self._prec, sv)
|
|
1212
|
+
if s == "":
|
|
1213
|
+
return "0"
|
|
1214
|
+
return s
|
|
1215
|
+
|
|
1216
|
+
def _latex_(self):
|
|
1217
|
+
r"""
|
|
1218
|
+
Return a LaTeX representation of this series.
|
|
1219
|
+
|
|
1220
|
+
The terms are ordered with decreasing term order
|
|
1221
|
+
(increasing valuation of the coefficients, then
|
|
1222
|
+
the monomial order of the parent algebra).
|
|
1223
|
+
|
|
1224
|
+
EXAMPLES::
|
|
1225
|
+
|
|
1226
|
+
sage: R = Zp(2, 10, print_mode='digits')
|
|
1227
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1228
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1229
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1230
|
+
sage: f._latex_()
|
|
1231
|
+
'...0000000001x^{3} + ...0000000001x + ...00000000010x^{2}'
|
|
1232
|
+
"""
|
|
1233
|
+
base = self._parent.base_ring()
|
|
1234
|
+
nvars = self._parent.ngens()
|
|
1235
|
+
vars = self._parent.variable_names()
|
|
1236
|
+
s = ""
|
|
1237
|
+
for t in self.terms():
|
|
1238
|
+
if t.valuation() >= self._prec:
|
|
1239
|
+
continue
|
|
1240
|
+
st = t._latex_()
|
|
1241
|
+
if s == "":
|
|
1242
|
+
s += st
|
|
1243
|
+
elif st[0] == "-":
|
|
1244
|
+
s += " - " + st[1:]
|
|
1245
|
+
else:
|
|
1246
|
+
s += " + " + st
|
|
1247
|
+
if self._prec is not Infinity:
|
|
1248
|
+
if s != "":
|
|
1249
|
+
s += " + "
|
|
1250
|
+
sv = ",".join(vars)
|
|
1251
|
+
if self._prec == 0:
|
|
1252
|
+
s += "O\\left(%s\\right)" % self._parent.integer_ring()._latex_()
|
|
1253
|
+
elif self._prec == 1:
|
|
1254
|
+
s += "O\\left(%s %s\\right)" % (self._parent._uniformizer_latex, self._parent.integer_ring()._latex_())
|
|
1255
|
+
else:
|
|
1256
|
+
s += "O\\left(%s^{%s} %s\\right)" % (self._parent._uniformizer_latex, self._prec, self._parent.integer_ring()._latex_())
|
|
1257
|
+
return s
|
|
1258
|
+
|
|
1259
|
+
cpdef _add_(self, other):
|
|
1260
|
+
r"""
|
|
1261
|
+
Return the sum of this series and ``other``.
|
|
1262
|
+
|
|
1263
|
+
The precision of the output is adjusted to the minimum of both precisions.
|
|
1264
|
+
|
|
1265
|
+
INPUT:
|
|
1266
|
+
|
|
1267
|
+
- ``other`` -- a Tate series
|
|
1268
|
+
|
|
1269
|
+
EXAMPLES::
|
|
1270
|
+
|
|
1271
|
+
sage: R = Zp(2, 10, print_mode='digits')
|
|
1272
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1273
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1274
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1275
|
+
sage: g = A(x + 2*y^2, prec=5); g
|
|
1276
|
+
...00001*x + ...00010*y^2 + O(2^5 * <x, y>)
|
|
1277
|
+
sage: h = f + g; h # indirect doctest
|
|
1278
|
+
...00001*x^3 + ...00010*x^2 + ...00010*y^2 + ...00010*x + O(2^5 * <x, y>)
|
|
1279
|
+
|
|
1280
|
+
sage: f.precision_absolute()
|
|
1281
|
+
+Infinity
|
|
1282
|
+
sage: g.precision_absolute()
|
|
1283
|
+
5
|
|
1284
|
+
sage: h.precision_absolute()
|
|
1285
|
+
5
|
|
1286
|
+
"""
|
|
1287
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1288
|
+
ans._poly = self._poly + (<TateAlgebraElement>other)._poly
|
|
1289
|
+
ans._prec = min(self._prec, (<TateAlgebraElement>other)._prec)
|
|
1290
|
+
ans._normalize()
|
|
1291
|
+
return ans
|
|
1292
|
+
|
|
1293
|
+
cpdef _neg_(self):
|
|
1294
|
+
r"""
|
|
1295
|
+
Return the opposite of this series.
|
|
1296
|
+
|
|
1297
|
+
EXAMPLES::
|
|
1298
|
+
|
|
1299
|
+
sage: R = Zp(2, 10, print_mode='digits')
|
|
1300
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1301
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1302
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1303
|
+
sage: -f # indirect doctest
|
|
1304
|
+
...1111111111*x^3 + ...1111111111*x + ...11111111110*x^2
|
|
1305
|
+
"""
|
|
1306
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1307
|
+
cdef Element s = self._parent.base_ring()(-1)
|
|
1308
|
+
ans._poly = self._poly.scalar_lmult(s)
|
|
1309
|
+
ans._prec = self._prec
|
|
1310
|
+
return ans
|
|
1311
|
+
|
|
1312
|
+
cpdef _sub_(self, other):
|
|
1313
|
+
r"""
|
|
1314
|
+
Return the difference of this series and ``other``.
|
|
1315
|
+
|
|
1316
|
+
The precision of the output is adjusted to the minimum of both precisions.
|
|
1317
|
+
|
|
1318
|
+
EXAMPLES::
|
|
1319
|
+
|
|
1320
|
+
sage: R = Zp(2, 10, print_mode='digits')
|
|
1321
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1322
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1323
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1324
|
+
sage: g = A(x + 2*y^2, prec=5); g
|
|
1325
|
+
...00001*x + ...00010*y^2 + O(2^5 * <x, y>)
|
|
1326
|
+
sage: h = f - g; h # indirect doctest
|
|
1327
|
+
...00001*x^3 + ...00010*x^2 + ...11110*y^2 + O(2^5 * <x, y>)
|
|
1328
|
+
|
|
1329
|
+
::
|
|
1330
|
+
|
|
1331
|
+
sage: f.precision_absolute()
|
|
1332
|
+
+Infinity
|
|
1333
|
+
sage: g.precision_absolute()
|
|
1334
|
+
5
|
|
1335
|
+
sage: h.precision_absolute()
|
|
1336
|
+
5
|
|
1337
|
+
"""
|
|
1338
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1339
|
+
ans._poly = self._poly - (<TateAlgebraElement>other)._poly
|
|
1340
|
+
ans._prec = min(self._prec, (<TateAlgebraElement>other)._prec)
|
|
1341
|
+
ans._normalize()
|
|
1342
|
+
return ans
|
|
1343
|
+
|
|
1344
|
+
cpdef _mul_(self, other):
|
|
1345
|
+
r"""
|
|
1346
|
+
Return the product of this series with ``other``.
|
|
1347
|
+
|
|
1348
|
+
The precision is adjusted to match the best precision on the output.
|
|
1349
|
+
|
|
1350
|
+
EXAMPLES::
|
|
1351
|
+
|
|
1352
|
+
sage: R = Zp(2, 10, print_mode='digits')
|
|
1353
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1354
|
+
sage: f = 2*x + 4*x^2 + 2*x^3; f
|
|
1355
|
+
...00000000010*x^3 + ...00000000010*x + ...000000000100*x^2
|
|
1356
|
+
sage: g = A(x + 2*x^2, prec=5); g
|
|
1357
|
+
...00001*x + ...00010*x^2 + O(2^5 * <x, y>)
|
|
1358
|
+
sage: h = f * g; h # indirect doctest
|
|
1359
|
+
...001010*x^4 + ...000010*x^2 + ...000100*x^5 + ...001000*x^3 + O(2^6 * <x, y>)
|
|
1360
|
+
|
|
1361
|
+
::
|
|
1362
|
+
|
|
1363
|
+
sage: f.precision_absolute()
|
|
1364
|
+
+Infinity
|
|
1365
|
+
sage: g.precision_absolute()
|
|
1366
|
+
5
|
|
1367
|
+
sage: h.precision_absolute()
|
|
1368
|
+
6
|
|
1369
|
+
"""
|
|
1370
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1371
|
+
a = self._prec + (<TateAlgebraElement>other).valuation()
|
|
1372
|
+
b = self.valuation() + (<TateAlgebraElement>other)._prec
|
|
1373
|
+
ans._poly = self._poly * (<TateAlgebraElement>other)._poly
|
|
1374
|
+
ans._prec = min(a, b)
|
|
1375
|
+
ans._normalize()
|
|
1376
|
+
return ans
|
|
1377
|
+
|
|
1378
|
+
cpdef _lmul_(self, Element right):
|
|
1379
|
+
r"""
|
|
1380
|
+
Return the product of this series by ``right``.
|
|
1381
|
+
|
|
1382
|
+
EXAMPLES::
|
|
1383
|
+
|
|
1384
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1385
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1386
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1387
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1388
|
+
sage: 2*f # indirect doctest
|
|
1389
|
+
...00000000010*x^3 + ...00000000010*x + ...000000000100*x^2
|
|
1390
|
+
|
|
1391
|
+
sage: 6*f # indirect doctest
|
|
1392
|
+
...00000000110*x^3 + ...00000000110*x + ...000000001100*x^2
|
|
1393
|
+
"""
|
|
1394
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1395
|
+
ans._poly = self._poly.scalar_lmult(right)
|
|
1396
|
+
ans._prec = self._prec + (<pAdicGenericElement>self._parent._base(right)).valuation_c()
|
|
1397
|
+
return ans
|
|
1398
|
+
|
|
1399
|
+
def inverse_of_unit(self, prec=None):
|
|
1400
|
+
r"""
|
|
1401
|
+
Return the inverse of this series if it is invertible.
|
|
1402
|
+
|
|
1403
|
+
INPUT:
|
|
1404
|
+
|
|
1405
|
+
- ``prec`` -- integer or ``None`` (default: ``None``);
|
|
1406
|
+
the precision at which the result is computed, if ``None``,
|
|
1407
|
+
the result is truncated according to the cap of the parent
|
|
1408
|
+
|
|
1409
|
+
EXAMPLES::
|
|
1410
|
+
|
|
1411
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1412
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1413
|
+
sage: f = A(1); f
|
|
1414
|
+
...0000000001
|
|
1415
|
+
sage: f.inverse_of_unit()
|
|
1416
|
+
...0000000001 + O(2^10 * <x, y>)
|
|
1417
|
+
|
|
1418
|
+
sage: f = 2*x + 1; f
|
|
1419
|
+
...0000000001 + ...00000000010*x
|
|
1420
|
+
sage: f.inverse_of_unit()
|
|
1421
|
+
...0000000001 + ...1111111110*x + ...0000000100*x^2 + ...1111111000*x^3
|
|
1422
|
+
+ ...0000010000*x^4 + ...1111100000*x^5 + ...0001000000*x^6
|
|
1423
|
+
+ ...1110000000*x^7 + ...0100000000*x^8 + ...1000000000*x^9 + O(2^10 * <x, y>)
|
|
1424
|
+
|
|
1425
|
+
sage: f.inverse_of_unit(prec=4)
|
|
1426
|
+
...0001 + ...1110*x + ...0100*x^2 + ...1000*x^3 + O(2^4 * <x, y>)
|
|
1427
|
+
|
|
1428
|
+
If the series is not invertible, an error is raised::
|
|
1429
|
+
|
|
1430
|
+
sage: f = 1 + x; f
|
|
1431
|
+
...0000000001*x + ...0000000001
|
|
1432
|
+
sage: f.inverse_of_unit()
|
|
1433
|
+
Traceback (most recent call last):
|
|
1434
|
+
...
|
|
1435
|
+
ValueError: this series in not invertible
|
|
1436
|
+
"""
|
|
1437
|
+
cdef TateAlgebraTerm t
|
|
1438
|
+
cdef long v, curprec
|
|
1439
|
+
cdef pAdicGenericElement c
|
|
1440
|
+
cdef TateAlgebraElement inv, x
|
|
1441
|
+
if not self.is_unit():
|
|
1442
|
+
raise ValueError("this series in not invertible")
|
|
1443
|
+
t = self.leading_term()
|
|
1444
|
+
c = t.coefficient()
|
|
1445
|
+
parent = self._parent
|
|
1446
|
+
v, c = c.val_unit()
|
|
1447
|
+
x = self >> v
|
|
1448
|
+
|
|
1449
|
+
rprec = self.precision_relative()
|
|
1450
|
+
if prec is not None and prec + v < rprec:
|
|
1451
|
+
rprec = prec + v
|
|
1452
|
+
if rprec is Infinity:
|
|
1453
|
+
rprec = self._parent.precision_cap()
|
|
1454
|
+
|
|
1455
|
+
x = x.add_bigoh(rprec)
|
|
1456
|
+
inv = (<TateAlgebraElement>self)._new_c()
|
|
1457
|
+
inv._poly = PolyDict({ ETuple({}, parent._ngens): parent._field(~c.residue()).lift_to_precision() }, None)
|
|
1458
|
+
inv._prec = rprec
|
|
1459
|
+
curprec = 1
|
|
1460
|
+
while curprec < rprec:
|
|
1461
|
+
curprec *= 2
|
|
1462
|
+
inv = 2*inv - x*inv*inv
|
|
1463
|
+
return inv >> v
|
|
1464
|
+
|
|
1465
|
+
def is_unit(self):
|
|
1466
|
+
r"""
|
|
1467
|
+
Return ``True`` if this series is invertible.
|
|
1468
|
+
|
|
1469
|
+
EXAMPLES::
|
|
1470
|
+
|
|
1471
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1472
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1473
|
+
sage: f = 2*x + 1; f
|
|
1474
|
+
...0000000001 + ...00000000010*x
|
|
1475
|
+
sage: f.is_unit()
|
|
1476
|
+
True
|
|
1477
|
+
|
|
1478
|
+
sage: f = 1 + x; f
|
|
1479
|
+
...0000000001*x + ...0000000001
|
|
1480
|
+
sage: f.is_unit()
|
|
1481
|
+
False
|
|
1482
|
+
|
|
1483
|
+
Note that invertibility is tested in the parent of this series::
|
|
1484
|
+
|
|
1485
|
+
sage: f = 4*x + 2
|
|
1486
|
+
sage: f.is_unit()
|
|
1487
|
+
True
|
|
1488
|
+
|
|
1489
|
+
sage: Ao = A.integer_ring()
|
|
1490
|
+
sage: Ao(f).is_unit()
|
|
1491
|
+
False
|
|
1492
|
+
"""
|
|
1493
|
+
if self.is_zero():
|
|
1494
|
+
return False
|
|
1495
|
+
t = self.leading_term()
|
|
1496
|
+
if max(t.exponent()) != 0:
|
|
1497
|
+
return False
|
|
1498
|
+
base = self.base_ring()
|
|
1499
|
+
if not base.is_field() and t.valuation() > 0:
|
|
1500
|
+
return False
|
|
1501
|
+
return True
|
|
1502
|
+
|
|
1503
|
+
def __pow__(self, exponent, modulus):
|
|
1504
|
+
r"""
|
|
1505
|
+
Return this element raised to the power ``exponent``.
|
|
1506
|
+
|
|
1507
|
+
INPUT:
|
|
1508
|
+
|
|
1509
|
+
- ``exponent`` -- either an integer, a rational number or a
|
|
1510
|
+
Tate series
|
|
1511
|
+
|
|
1512
|
+
- ``modulus`` -- discarded
|
|
1513
|
+
|
|
1514
|
+
EXAMPLES::
|
|
1515
|
+
|
|
1516
|
+
sage: R = Zp(3, prec=4, print_mode='digits')
|
|
1517
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1518
|
+
sage: (x + y)^3
|
|
1519
|
+
...0001*x^3 + ...0001*y^3 + ...0010*x^2*y + ...0010*x*y^2
|
|
1520
|
+
|
|
1521
|
+
This function can be used to compute the inverse of a Tate series::
|
|
1522
|
+
|
|
1523
|
+
sage: f = 1 + 6*x^2 + 9*y^2
|
|
1524
|
+
sage: f^(-1)
|
|
1525
|
+
...0001 + ...2210*x^2 + ...1100*x^4 + ...2200*y^2 + ...1000*x^6
|
|
1526
|
+
+ ...1000*x^2*y^2 + O(3^4 * <x, y>)
|
|
1527
|
+
|
|
1528
|
+
or a square root (or more generally an n-th root)::
|
|
1529
|
+
|
|
1530
|
+
sage: g = f^(1/2); g
|
|
1531
|
+
...0001 + ...0010*x^2 + ...1100*x^4 + ...1200*y^2 + ...2000*x^6
|
|
1532
|
+
+ ...1000*x^2*y^2 + O(3^4 * <x, y>)
|
|
1533
|
+
sage: g^2 == f
|
|
1534
|
+
True
|
|
1535
|
+
|
|
1536
|
+
When the exponent is not an integer, `f^e` is computed as `\exp(e \log(f))`.
|
|
1537
|
+
This computation fails if `f` is outside the domain of the logarithm or if
|
|
1538
|
+
`e \log(f)` is outside the domain of convergence of the exponential::
|
|
1539
|
+
|
|
1540
|
+
sage: f^(1/3)
|
|
1541
|
+
Traceback (most recent call last):
|
|
1542
|
+
...
|
|
1543
|
+
ValueError: not in the domain of convergence
|
|
1544
|
+
|
|
1545
|
+
The exponent can be a series as well::
|
|
1546
|
+
|
|
1547
|
+
sage: g = f^x; g
|
|
1548
|
+
...0001 + ...0020*x^3 + ...1100*x^9 + ...2200*x^7 + ... + O(3^4 * <x, y>)
|
|
1549
|
+
|
|
1550
|
+
sage: x0 = R.random_element()
|
|
1551
|
+
sage: y0 = R.random_element()
|
|
1552
|
+
sage: g(x0, y0) == f(x0, y0)^x0
|
|
1553
|
+
True
|
|
1554
|
+
|
|
1555
|
+
TESTS::
|
|
1556
|
+
|
|
1557
|
+
sage: f^(x + y) == f^x * f^y
|
|
1558
|
+
True
|
|
1559
|
+
sage: f^(x*y) == (f^x)^y
|
|
1560
|
+
True
|
|
1561
|
+
sage: f^(x*y) == (f^y)^x
|
|
1562
|
+
True
|
|
1563
|
+
"""
|
|
1564
|
+
cdef TateAlgebraElement temp
|
|
1565
|
+
cdef long p, v, e
|
|
1566
|
+
if exponent in ZZ:
|
|
1567
|
+
if exponent == 0:
|
|
1568
|
+
return (<TateAlgebraElement>self)._parent.one()
|
|
1569
|
+
elif exponent > 0:
|
|
1570
|
+
# We handle precision
|
|
1571
|
+
temp = (<TateAlgebraElement>self)._new_c()
|
|
1572
|
+
temp._poly = (<TateAlgebraElement>self)._poly
|
|
1573
|
+
if (<TateAlgebraElement>self)._prec is Infinity:
|
|
1574
|
+
temp._prec = Infinity
|
|
1575
|
+
else:
|
|
1576
|
+
p = (<TateAlgebraElement>self)._parent.prime()
|
|
1577
|
+
e = (<TateAlgebraElement>self)._parent.absolute_e()
|
|
1578
|
+
v = (<TateAlgebraElement>self).valuation()
|
|
1579
|
+
temp._prec = p*v + (<TateAlgebraElement>self)._prec
|
|
1580
|
+
q = ZZ(exponent)
|
|
1581
|
+
while True:
|
|
1582
|
+
q, r = q.quo_rem(p)
|
|
1583
|
+
if r != 0: break
|
|
1584
|
+
temp._prec = min(p * temp._prec, temp._prec + e)
|
|
1585
|
+
# and perform the exponentiation
|
|
1586
|
+
return CommutativeAlgebraElement.__pow__(temp, exponent, None)
|
|
1587
|
+
else:
|
|
1588
|
+
return self.inverse_of_unit() ** (-exponent)
|
|
1589
|
+
elif exponent in QQ:
|
|
1590
|
+
exponent = QQ(exponent)
|
|
1591
|
+
return self.nth_root(exponent.denominator()) ** exponent.numerator()
|
|
1592
|
+
else:
|
|
1593
|
+
return ((<TateAlgebraElement>self).log() * exponent).exp()
|
|
1594
|
+
|
|
1595
|
+
def square_root(self, prec=None):
|
|
1596
|
+
r"""
|
|
1597
|
+
Return the square root of this series.
|
|
1598
|
+
|
|
1599
|
+
INPUT:
|
|
1600
|
+
|
|
1601
|
+
- ``prec`` -- integer or ``None`` (default: ``None``);
|
|
1602
|
+
the precision at which the result is computed, if ``None``,
|
|
1603
|
+
the result is truncated according to the cap of the parent
|
|
1604
|
+
|
|
1605
|
+
EXAMPLES::
|
|
1606
|
+
|
|
1607
|
+
sage: R = Zp(3, prec=10, print_mode='digits')
|
|
1608
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1609
|
+
sage: f = 1 + 6*x^2 + 9*y^2
|
|
1610
|
+
sage: g = f.sqrt(); g
|
|
1611
|
+
...0000000001 + ...0000000010*x^2 + ...1111111100*x^4 + ...1111111200*y^2
|
|
1612
|
+
+ ...1111112000*x^6 + ...1111111000*x^2*y^2 + ... + O(3^10 * <x, y>)
|
|
1613
|
+
|
|
1614
|
+
sage: f.square_root(prec=4)
|
|
1615
|
+
...0001 + ...0010*x^2 + ...1100*x^4 + ...1200*y^2 + ...2000*x^6
|
|
1616
|
+
+ ...1000*x^2*y^2 + O(3^4 * <x, y>)
|
|
1617
|
+
|
|
1618
|
+
sage: g^2 == f
|
|
1619
|
+
True
|
|
1620
|
+
|
|
1621
|
+
It's possible that `f` has a trivial square root (which is analytic on
|
|
1622
|
+
the correct domain) but that it takes its values outside the domain of
|
|
1623
|
+
convergence of the square root function.
|
|
1624
|
+
In this case, an error is raised::
|
|
1625
|
+
|
|
1626
|
+
sage: f = x^2
|
|
1627
|
+
sage: f.square_root()
|
|
1628
|
+
Traceback (most recent call last):
|
|
1629
|
+
...
|
|
1630
|
+
ValueError: not in the domain of convergence
|
|
1631
|
+
"""
|
|
1632
|
+
return self.nth_root(2, prec)
|
|
1633
|
+
|
|
1634
|
+
def sqrt(self, prec=None):
|
|
1635
|
+
r"""
|
|
1636
|
+
Return the square root of this series.
|
|
1637
|
+
|
|
1638
|
+
INPUT:
|
|
1639
|
+
|
|
1640
|
+
- ``prec`` -- integer or ``None`` (default: ``None``);
|
|
1641
|
+
the precision at which the result is computed, if ``None``,
|
|
1642
|
+
the result is truncated according to the cap of the parent
|
|
1643
|
+
|
|
1644
|
+
EXAMPLES::
|
|
1645
|
+
|
|
1646
|
+
sage: R = Zp(3, prec=10, print_mode='digits')
|
|
1647
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1648
|
+
sage: f = 1 + 6*x^2 + 9*y^2
|
|
1649
|
+
sage: g = f.sqrt(); g
|
|
1650
|
+
...0000000001 + ...0000000010*x^2 + ...1111111100*x^4 + ...1111111200*y^2
|
|
1651
|
+
+ ...1111112000*x^6 + ...1111111000*x^2*y^2 + ... + O(3^10 * <x, y>)
|
|
1652
|
+
|
|
1653
|
+
sage: f.sqrt(prec=4)
|
|
1654
|
+
...0001 + ...0010*x^2 + ...1100*x^4 + ...1200*y^2 + ...2000*x^6
|
|
1655
|
+
+ ...1000*x^2*y^2 + O(3^4 * <x, y>)
|
|
1656
|
+
|
|
1657
|
+
sage: g^2 == f
|
|
1658
|
+
True
|
|
1659
|
+
|
|
1660
|
+
It's possible that `f` has a trivial square root (which is analytic on
|
|
1661
|
+
the correct domain) but that it takes its values outside the domain of
|
|
1662
|
+
convergence of the square root function.
|
|
1663
|
+
In this case, an error is raised::
|
|
1664
|
+
|
|
1665
|
+
sage: f = x^2
|
|
1666
|
+
sage: f.sqrt()
|
|
1667
|
+
Traceback (most recent call last):
|
|
1668
|
+
...
|
|
1669
|
+
ValueError: not in the domain of convergence
|
|
1670
|
+
"""
|
|
1671
|
+
return self.nth_root(2, prec)
|
|
1672
|
+
|
|
1673
|
+
def nth_root(self, n=2, prec=None):
|
|
1674
|
+
r"""
|
|
1675
|
+
Return the `n`-th root of this series.
|
|
1676
|
+
|
|
1677
|
+
INPUT:
|
|
1678
|
+
|
|
1679
|
+
- ``n`` -- integer (default: `2`)
|
|
1680
|
+
|
|
1681
|
+
- ``prec`` -- integer or ``None`` (default: ``None``);
|
|
1682
|
+
the precision at which the result is computed, if ``None``,
|
|
1683
|
+
the result is truncated according to the cap of the parent
|
|
1684
|
+
|
|
1685
|
+
.. NOTE::
|
|
1686
|
+
|
|
1687
|
+
The `n`-th root is computed as `\exp(\frac 1 n \log(f))`.
|
|
1688
|
+
|
|
1689
|
+
EXAMPLES::
|
|
1690
|
+
|
|
1691
|
+
sage: R = Zp(3, prec=10, print_mode='digits')
|
|
1692
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1693
|
+
sage: f = 1 + 9*x^2 + 9*y^2
|
|
1694
|
+
sage: g = f.nth_root(3, prec=3); g
|
|
1695
|
+
...001 + ...010*x^2 + ...010*y^2 + ...200*x^6 + ...200*y^6 + ...200*x^4
|
|
1696
|
+
+ ...100*x^2*y^2 + ...200*y^4 + O(3^3 * <x, y>)
|
|
1697
|
+
sage: g^3 == f
|
|
1698
|
+
True
|
|
1699
|
+
|
|
1700
|
+
sage: for n in range(2, 9):
|
|
1701
|
+
....: if f.nth_root(n)^n != f: raise RuntimeError
|
|
1702
|
+
|
|
1703
|
+
It's possible that `f` has a trivial ``n``-th root (which is analytic on
|
|
1704
|
+
the correct domain) but that `\exp(\frac 1 n \log(f))` does not converge.
|
|
1705
|
+
In this case, an error is raised::
|
|
1706
|
+
|
|
1707
|
+
sage: f = x^3
|
|
1708
|
+
sage: f.nth_root(3)
|
|
1709
|
+
Traceback (most recent call last):
|
|
1710
|
+
...
|
|
1711
|
+
ValueError: not in the domain of convergence
|
|
1712
|
+
"""
|
|
1713
|
+
if n not in ZZ or n == 0:
|
|
1714
|
+
raise ValueError("n must be a nonzero integer")
|
|
1715
|
+
n = ZZ(n)
|
|
1716
|
+
|
|
1717
|
+
cdef TateAlgebraElement a, root
|
|
1718
|
+
cdef long v, e, ep, curprec
|
|
1719
|
+
cdef pAdicGenericElement scalar
|
|
1720
|
+
|
|
1721
|
+
parent = self._parent
|
|
1722
|
+
p = parent.prime()
|
|
1723
|
+
v = n.valuation(p)
|
|
1724
|
+
e = parent.absolute_e()
|
|
1725
|
+
ep = e // (p - 1)
|
|
1726
|
+
if v == 0:
|
|
1727
|
+
curprec = 1
|
|
1728
|
+
else:
|
|
1729
|
+
curprec = v*e + ep + 1
|
|
1730
|
+
if (self - 1).valuation() < curprec:
|
|
1731
|
+
raise ValueError("not in the domain of convergence")
|
|
1732
|
+
|
|
1733
|
+
aprec = self.precision_absolute()
|
|
1734
|
+
if prec is not None and prec < aprec:
|
|
1735
|
+
aprec = prec
|
|
1736
|
+
if aprec is Infinity:
|
|
1737
|
+
aprec = parent.precision_cap()
|
|
1738
|
+
|
|
1739
|
+
aprec += v*e
|
|
1740
|
+
root = parent(1).add_bigoh(v*e+1)
|
|
1741
|
+
if n > 0:
|
|
1742
|
+
a = self.inverse_of_unit(aprec)
|
|
1743
|
+
else:
|
|
1744
|
+
n = -n
|
|
1745
|
+
a = self.add_bigoh(aprec)
|
|
1746
|
+
scalar = ~(parent._field(n))
|
|
1747
|
+
while curprec < aprec:
|
|
1748
|
+
if v == 0:
|
|
1749
|
+
curprec *= 2
|
|
1750
|
+
else:
|
|
1751
|
+
curprec -= v*e
|
|
1752
|
+
curprec = min(2*curprec + v*e, p*curprec + (v-1)*e)
|
|
1753
|
+
root = root.lift_to_precision(min(aprec, curprec))
|
|
1754
|
+
root += scalar * root * (1 - a * root**n)
|
|
1755
|
+
return root
|
|
1756
|
+
|
|
1757
|
+
cpdef _richcmp_(self, other, int op):
|
|
1758
|
+
r"""
|
|
1759
|
+
Compare this series with ``other`` according to
|
|
1760
|
+
the rich comparison operator ``op``.
|
|
1761
|
+
|
|
1762
|
+
INPUT:
|
|
1763
|
+
|
|
1764
|
+
- ``other`` -- a Tate algebra element
|
|
1765
|
+
|
|
1766
|
+
- ``op`` -- the comparison operator
|
|
1767
|
+
|
|
1768
|
+
EXAMPLES::
|
|
1769
|
+
|
|
1770
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1771
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1772
|
+
sage: A.term_order()
|
|
1773
|
+
Degree reverse lexicographic term order
|
|
1774
|
+
|
|
1775
|
+
For terms, we first compare the valuation and ties are broken
|
|
1776
|
+
using the term ordering on `A`::
|
|
1777
|
+
|
|
1778
|
+
sage: 2*x^2*y^2 > x*y^3
|
|
1779
|
+
False
|
|
1780
|
+
sage: x^2*y^2 > x*y^3
|
|
1781
|
+
True
|
|
1782
|
+
|
|
1783
|
+
For general series, leading terms are first compared. In case
|
|
1784
|
+
of tie, second leading terms are compared, and so on::
|
|
1785
|
+
|
|
1786
|
+
sage: x^2*y^2 > x*y^3 + y^4
|
|
1787
|
+
True
|
|
1788
|
+
sage: x^2*y^2 > x^2*y^2 + x*y^3
|
|
1789
|
+
False
|
|
1790
|
+
|
|
1791
|
+
TESTS::
|
|
1792
|
+
|
|
1793
|
+
sage: f = x^4 + 4*x*y + 1; f
|
|
1794
|
+
...0000000001*x^4 + ...0000000001 + ...000000000100*x*y
|
|
1795
|
+
sage: g = f + 2
|
|
1796
|
+
sage: f == g
|
|
1797
|
+
False
|
|
1798
|
+
sage: f == g - 2
|
|
1799
|
+
True
|
|
1800
|
+
"""
|
|
1801
|
+
diff = self - other
|
|
1802
|
+
c = None
|
|
1803
|
+
if diff.is_zero():
|
|
1804
|
+
c = 0
|
|
1805
|
+
if op == Py_EQ:
|
|
1806
|
+
return c is not None
|
|
1807
|
+
if op == Py_NE:
|
|
1808
|
+
return c is None
|
|
1809
|
+
if c is None:
|
|
1810
|
+
ts = self.terms()
|
|
1811
|
+
to = other.terms()
|
|
1812
|
+
for s, o in zip(ts, to):
|
|
1813
|
+
c = (<TateAlgebraTerm>s)._cmp_c(<TateAlgebraTerm>o)
|
|
1814
|
+
if c: break
|
|
1815
|
+
else:
|
|
1816
|
+
c = len(ts) - len(to)
|
|
1817
|
+
return rich_to_bool_sgn(op, c)
|
|
1818
|
+
|
|
1819
|
+
def __call__(self, *args):
|
|
1820
|
+
"""
|
|
1821
|
+
Return this term evaluated at ``args``.
|
|
1822
|
+
|
|
1823
|
+
INPUT:
|
|
1824
|
+
|
|
1825
|
+
- ``args`` -- elements
|
|
1826
|
+
|
|
1827
|
+
EXAMPLES::
|
|
1828
|
+
|
|
1829
|
+
sage: R = Zp(2)
|
|
1830
|
+
sage: A.<u,v> = TateAlgebra(R, log_radii=[0,-1])
|
|
1831
|
+
sage: A
|
|
1832
|
+
Tate Algebra in u (val >= 0), v (val >= 1) over 2-adic Field with capped relative precision 20
|
|
1833
|
+
|
|
1834
|
+
sage: f = u^2 + v^2
|
|
1835
|
+
sage: f(1, 0)
|
|
1836
|
+
1 + O(2^20)
|
|
1837
|
+
|
|
1838
|
+
An error is raised if we ask for the evaluation at one
|
|
1839
|
+
point which is outside the domain of convergence::
|
|
1840
|
+
|
|
1841
|
+
sage: f(1, 1)
|
|
1842
|
+
Traceback (most recent call last):
|
|
1843
|
+
...
|
|
1844
|
+
ValueError: not in the domain of convergence
|
|
1845
|
+
|
|
1846
|
+
Evaluation at points in extensions is allowed::
|
|
1847
|
+
|
|
1848
|
+
sage: # needs sage.libs.ntl
|
|
1849
|
+
sage: S.<a> = Zq(2^3)
|
|
1850
|
+
sage: f(a, 2)
|
|
1851
|
+
a^2 + 2^2 + O(2^20)
|
|
1852
|
+
sage: x = polygen(ZZ, 'x')
|
|
1853
|
+
sage: T.<pi> = S.extension(x^2 - 2)
|
|
1854
|
+
sage: f(pi, 2)
|
|
1855
|
+
pi^2 + pi^4 + O(pi^42)
|
|
1856
|
+
sage: f(pi, pi)
|
|
1857
|
+
Traceback (most recent call last):
|
|
1858
|
+
...
|
|
1859
|
+
ValueError: not in the domain of convergence
|
|
1860
|
+
|
|
1861
|
+
This method can also be used to compose Tate series::
|
|
1862
|
+
|
|
1863
|
+
sage: f(u + v, 2*u) # needs sage.libs.ntl
|
|
1864
|
+
(1 + 2^2 + O(2^20))*u^2 + (2 + O(2^20))*u*v + (1 + O(2^20))*v^2
|
|
1865
|
+
|
|
1866
|
+
or for partial evaluation::
|
|
1867
|
+
|
|
1868
|
+
sage: f(pi, v) # needs sage.libs.ntl
|
|
1869
|
+
(pi^2 + O(pi^42)) + (1 + O(pi^40))*v^2
|
|
1870
|
+
"""
|
|
1871
|
+
cdef TateAlgebraTerm t
|
|
1872
|
+
parent = self._parent
|
|
1873
|
+
if len(args) != parent._ngens:
|
|
1874
|
+
raise TypeError("wrong number of arguments")
|
|
1875
|
+
A = _pushout_family(args, parent._field)
|
|
1876
|
+
args = [ A(arg) for arg in args ]
|
|
1877
|
+
ratio = A.absolute_e() // parent._base.absolute_e()
|
|
1878
|
+
for i in range(parent._ngens):
|
|
1879
|
+
if args[i].valuation() < -ratio * parent._log_radii[i]:
|
|
1880
|
+
raise ValueError("not in the domain of convergence")
|
|
1881
|
+
res = A(0, ratio * self._prec)
|
|
1882
|
+
for t in self._terms_c():
|
|
1883
|
+
if t._valuation_c() >= res.precision_absolute():
|
|
1884
|
+
break
|
|
1885
|
+
res += t._call_c(args)
|
|
1886
|
+
if parent._integral:
|
|
1887
|
+
try:
|
|
1888
|
+
res = res.parent().integer_ring()(res)
|
|
1889
|
+
except AttributeError:
|
|
1890
|
+
pass
|
|
1891
|
+
return res
|
|
1892
|
+
|
|
1893
|
+
cdef TateAlgebraElement _term_mul_c(self, TateAlgebraTerm term):
|
|
1894
|
+
r"""
|
|
1895
|
+
Return the product of this series by the term ``term``.
|
|
1896
|
+
|
|
1897
|
+
EXAMPLES::
|
|
1898
|
+
|
|
1899
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1900
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1901
|
+
sage: t = A.monoid_of_terms()(3*x^2); t
|
|
1902
|
+
...0000000011*x^2
|
|
1903
|
+
sage: f = x^4 + 4*x*y + 1; f
|
|
1904
|
+
...0000000001*x^4 + ...0000000001 + ...000000000100*x*y
|
|
1905
|
+
sage: t*f # indirect doctest
|
|
1906
|
+
...0000000011*x^6 + ...0000000011*x^2 + ...000000001100*x^3*y
|
|
1907
|
+
"""
|
|
1908
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1909
|
+
ans._poly = self._poly.term_lmult(term._exponent, term._coeff)
|
|
1910
|
+
ans._prec = self._prec + term._valuation_c()
|
|
1911
|
+
return ans
|
|
1912
|
+
|
|
1913
|
+
cdef TateAlgebraElement _positive_lshift_c(self, n):
|
|
1914
|
+
r"""
|
|
1915
|
+
Return the product of this series by the ``n``-th power
|
|
1916
|
+
of the uniformizer.
|
|
1917
|
+
|
|
1918
|
+
INPUT:
|
|
1919
|
+
|
|
1920
|
+
- ``n`` -- nonnegative integer
|
|
1921
|
+
|
|
1922
|
+
EXAMPLES::
|
|
1923
|
+
|
|
1924
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1925
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1926
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1927
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1928
|
+
sage: f << 2 # indirect doctest
|
|
1929
|
+
...000000000100*x^3 + ...000000000100*x + ...0000000001000*x^2
|
|
1930
|
+
"""
|
|
1931
|
+
cdef dict coeffs = { }
|
|
1932
|
+
cdef ETuple e
|
|
1933
|
+
cdef Element c
|
|
1934
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1935
|
+
for (e,c) in self._poly.__repn.items():
|
|
1936
|
+
coeffs[e] = c << n
|
|
1937
|
+
ans._poly = PolyDict(coeffs, None)
|
|
1938
|
+
ans._prec = self._prec + n
|
|
1939
|
+
return ans
|
|
1940
|
+
|
|
1941
|
+
cdef TateAlgebraElement _lshift_c(self, n):
|
|
1942
|
+
r"""
|
|
1943
|
+
Return the product of this series by the ``n``-th power
|
|
1944
|
+
of the uniformizer.
|
|
1945
|
+
|
|
1946
|
+
INPUT:
|
|
1947
|
+
|
|
1948
|
+
- ``n`` -- integer
|
|
1949
|
+
|
|
1950
|
+
EXAMPLES::
|
|
1951
|
+
|
|
1952
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
1953
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1954
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1955
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1956
|
+
sage: f << 2 # indirect doctest
|
|
1957
|
+
...000000000100*x^3 + ...000000000100*x + ...0000000001000*x^2
|
|
1958
|
+
sage: Ao = A.integer_ring()
|
|
1959
|
+
sage: g = Ao(f).add_bigoh(5); g
|
|
1960
|
+
...00001*x^3 + ...00001*x + ...00010*x^2 + O(2^5 * <x, y>)
|
|
1961
|
+
sage: g << 2
|
|
1962
|
+
...0000100*x^3 + ...0000100*x + ...0001000*x^2 + O(2^7 * <x, y>)
|
|
1963
|
+
"""
|
|
1964
|
+
cdef dict coeffs = { }
|
|
1965
|
+
cdef ETuple e
|
|
1966
|
+
cdef Element c
|
|
1967
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
1968
|
+
parent = self._parent
|
|
1969
|
+
base = parent.base_ring()
|
|
1970
|
+
if base.is_field():
|
|
1971
|
+
for (e,c) in self._poly.__repn.items():
|
|
1972
|
+
coeffs[e] = c << n
|
|
1973
|
+
ans._prec = self._prec + n
|
|
1974
|
+
else:
|
|
1975
|
+
field = base.fraction_field()
|
|
1976
|
+
ngens = parent.ngens()
|
|
1977
|
+
for (e,c) in self._poly.__repn.items():
|
|
1978
|
+
minval = ZZ(e.dotprod(<ETuple>parent._log_radii)).ceil()
|
|
1979
|
+
coeffs[e] = field(base(c) >> (minval-n)) << minval
|
|
1980
|
+
ans._prec = max(ZZ(0), self._prec + n)
|
|
1981
|
+
ans._poly = PolyDict(coeffs, None)
|
|
1982
|
+
return ans
|
|
1983
|
+
|
|
1984
|
+
def __lshift__(self, n):
|
|
1985
|
+
r"""
|
|
1986
|
+
Return the product of this series by the ``n``-th power
|
|
1987
|
+
of the uniformizer.
|
|
1988
|
+
|
|
1989
|
+
INPUT:
|
|
1990
|
+
|
|
1991
|
+
- ``n`` -- integer
|
|
1992
|
+
|
|
1993
|
+
EXAMPLES::
|
|
1994
|
+
|
|
1995
|
+
sage: R = Zp(2, print_mode='digits',prec=10)
|
|
1996
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
1997
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
1998
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
1999
|
+
sage: f << 2 # indirect doctest
|
|
2000
|
+
...000000000100*x^3 + ...000000000100*x + ...0000000001000*x^2
|
|
2001
|
+
sage: f << -1 # indirect doctest
|
|
2002
|
+
...000000000.1*x^3 + ...000000000.1*x + ...0000000001*x^2
|
|
2003
|
+
|
|
2004
|
+
If we're shifting by a negative number of digits over the ring of
|
|
2005
|
+
integers of a Tate algebra, the result is truncated -- that is, the
|
|
2006
|
+
output is the result of the integer division of the Tate series by
|
|
2007
|
+
`\pi^{-n}` where `\pi` is a uniformizer.
|
|
2008
|
+
|
|
2009
|
+
sage: Ao = A.integer_ring()
|
|
2010
|
+
sage: Ao(f) << -1
|
|
2011
|
+
...0000000001*x^2 + ...000000000*x^3 + ...000000000*x
|
|
2012
|
+
"""
|
|
2013
|
+
return (<TateAlgebraElement>self)._lshift_c(n)
|
|
2014
|
+
|
|
2015
|
+
def __rshift__(self, n):
|
|
2016
|
+
r"""
|
|
2017
|
+
Return the quotient in the division of this series by
|
|
2018
|
+
the ``n``-th power of the uniformizer.
|
|
2019
|
+
|
|
2020
|
+
INPUT:
|
|
2021
|
+
|
|
2022
|
+
- ``n`` -- integer
|
|
2023
|
+
|
|
2024
|
+
EXAMPLES::
|
|
2025
|
+
|
|
2026
|
+
sage: R = Zp(2, print_mode='digits',prec=10)
|
|
2027
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2028
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
2029
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
2030
|
+
sage: f << 2
|
|
2031
|
+
...000000000100*x^3 + ...000000000100*x + ...0000000001000*x^2
|
|
2032
|
+
sage: f << -1 # indirect doctest
|
|
2033
|
+
...000000000.1*x^3 + ...000000000.1*x + ...0000000001*x^2
|
|
2034
|
+
|
|
2035
|
+
If we're working over the ring of integers of a Tate algebra, the
|
|
2036
|
+
result is truncated -- that is, the output is the result of the integer
|
|
2037
|
+
division of the Tate series by `\pi^n` where `\pi` is a uniformizer.
|
|
2038
|
+
|
|
2039
|
+
sage: Ao = A.integer_ring()
|
|
2040
|
+
sage: Ao(f) << -1
|
|
2041
|
+
...0000000001*x^2 + ...000000000*x^3 + ...000000000*x
|
|
2042
|
+
"""
|
|
2043
|
+
return (<TateAlgebraElement>self)._lshift_c(-n)
|
|
2044
|
+
|
|
2045
|
+
def __bool__(self):
|
|
2046
|
+
r"""
|
|
2047
|
+
Return ``True`` if this term is nonzero, ``False`` otherwise.
|
|
2048
|
+
|
|
2049
|
+
TESTS::
|
|
2050
|
+
|
|
2051
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2052
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2053
|
+
sage: f = x + 2*x^2 + y^3
|
|
2054
|
+
sage: bool(f)
|
|
2055
|
+
True
|
|
2056
|
+
sage: bool(f-f)
|
|
2057
|
+
False
|
|
2058
|
+
"""
|
|
2059
|
+
cdef list terms = self._terms_c(include_zero=False)
|
|
2060
|
+
return bool(terms) and (<TateAlgebraTerm>terms[0])._valuation_c() < self._prec
|
|
2061
|
+
|
|
2062
|
+
def is_zero(self, prec=None):
|
|
2063
|
+
r"""
|
|
2064
|
+
Return ``True`` if this series is indistinguishable from zero.
|
|
2065
|
+
|
|
2066
|
+
INPUT:
|
|
2067
|
+
|
|
2068
|
+
- ``prec`` -- integer or ``None`` (default: ``None``),
|
|
2069
|
+
the precision at which the series should be compared to zero
|
|
2070
|
+
|
|
2071
|
+
EXAMPLES::
|
|
2072
|
+
|
|
2073
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2074
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2075
|
+
sage: f = x + 2*x^2 + x^3; f
|
|
2076
|
+
...0000000001*x^3 + ...0000000001*x + ...00000000010*x^2
|
|
2077
|
+
sage: f.is_zero()
|
|
2078
|
+
False
|
|
2079
|
+
|
|
2080
|
+
sage: g = f << 4; g
|
|
2081
|
+
...00000000010000*x^3 + ...00000000010000*x + ...000000000100000*x^2
|
|
2082
|
+
sage: g.is_zero()
|
|
2083
|
+
False
|
|
2084
|
+
sage: g.is_zero(5)
|
|
2085
|
+
False
|
|
2086
|
+
sage: g.is_zero(4)
|
|
2087
|
+
True
|
|
2088
|
+
"""
|
|
2089
|
+
cdef list terms = self._terms_c(include_zero=False)
|
|
2090
|
+
if prec is None:
|
|
2091
|
+
prec = self._prec
|
|
2092
|
+
if not terms:
|
|
2093
|
+
return True
|
|
2094
|
+
return (<TateAlgebraTerm>terms[0])._valuation_c() >= prec
|
|
2095
|
+
|
|
2096
|
+
def restriction(self, log_radii):
|
|
2097
|
+
r"""
|
|
2098
|
+
Return the restriction of this series to a smaller domain.
|
|
2099
|
+
|
|
2100
|
+
INPUT:
|
|
2101
|
+
|
|
2102
|
+
- ``log_radii`` -- integer or a tuple; the log-radii of
|
|
2103
|
+
convergence of the smaller domain (see :class:`TateAlgebra`
|
|
2104
|
+
for more details)
|
|
2105
|
+
|
|
2106
|
+
EXAMPLES::
|
|
2107
|
+
|
|
2108
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2109
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2110
|
+
sage: f = 2*x + y^2; f
|
|
2111
|
+
...0000000001*y^2 + ...00000000010*x
|
|
2112
|
+
|
|
2113
|
+
sage: g = f.restriction(-1); g
|
|
2114
|
+
...0000000001*y^2 + ...00000000010*x
|
|
2115
|
+
sage: g.parent()
|
|
2116
|
+
Tate Algebra in x (val >= 1), y (val >= 1)
|
|
2117
|
+
over 2-adic Field with capped relative precision 10
|
|
2118
|
+
|
|
2119
|
+
Note that restricting may change the order of the terms::
|
|
2120
|
+
|
|
2121
|
+
sage: f.restriction([-1,-2])
|
|
2122
|
+
...00000000010*x + ...0000000001*y^2
|
|
2123
|
+
"""
|
|
2124
|
+
parent = self._parent
|
|
2125
|
+
from sage.rings.tate_algebra import TateAlgebra
|
|
2126
|
+
ring = TateAlgebra(self.base_ring(), names=parent.variable_names(), log_radii=log_radii,
|
|
2127
|
+
prec=parent.precision_cap(), order=parent.term_order())
|
|
2128
|
+
return ring(self)
|
|
2129
|
+
|
|
2130
|
+
def terms(self):
|
|
2131
|
+
r"""
|
|
2132
|
+
Return a list of the terms of this series sorted in descending order.
|
|
2133
|
+
|
|
2134
|
+
.. NOTE::
|
|
2135
|
+
|
|
2136
|
+
The order on the terms is defined as follows: first we
|
|
2137
|
+
compare the valuation and, in case of equality, we compare
|
|
2138
|
+
the monomials with respect to the order given at the
|
|
2139
|
+
creation of the parent.
|
|
2140
|
+
|
|
2141
|
+
EXAMPLES::
|
|
2142
|
+
|
|
2143
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2144
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2145
|
+
sage: f = 2*x^2 + x
|
|
2146
|
+
sage: f.terms()
|
|
2147
|
+
[...0000000001*x, ...00000000010*x^2]
|
|
2148
|
+
"""
|
|
2149
|
+
if not self._is_normalized:
|
|
2150
|
+
self._normalize()
|
|
2151
|
+
self._terms = None
|
|
2152
|
+
return self._terms_c()
|
|
2153
|
+
|
|
2154
|
+
cdef list _terms_c(self, bint include_zero=True):
|
|
2155
|
+
r"""
|
|
2156
|
+
Return a list of the terms of this series sorted in descending order.
|
|
2157
|
+
|
|
2158
|
+
INPUT:
|
|
2159
|
+
|
|
2160
|
+
- ``include_zero`` -- boolean (default: ``True``); if ``True``,
|
|
2161
|
+
include terms which are indistinguishable from zero
|
|
2162
|
+
|
|
2163
|
+
EXAMPLES::
|
|
2164
|
+
|
|
2165
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2166
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2167
|
+
sage: f = 2*x^2 + x
|
|
2168
|
+
sage: f.terms() # indirect doctest
|
|
2169
|
+
[...0000000001*x, ...00000000010*x^2]
|
|
2170
|
+
"""
|
|
2171
|
+
cdef pAdicGenericElement c
|
|
2172
|
+
cdef ETuple e
|
|
2173
|
+
cdef TateAlgebraTerm oneterm = self._parent._oneterm
|
|
2174
|
+
cdef TateAlgebraTerm term
|
|
2175
|
+
if self._terms is None:
|
|
2176
|
+
self._terms = []
|
|
2177
|
+
for (e,c) in self._poly.__repn.items():
|
|
2178
|
+
term = oneterm._new_c()
|
|
2179
|
+
term._coeff = c
|
|
2180
|
+
term._exponent = e
|
|
2181
|
+
if term._valuation_c() < self._prec:
|
|
2182
|
+
self._terms.append(term)
|
|
2183
|
+
self._terms.sort(reverse=True)
|
|
2184
|
+
self._terms_nonzero = [ term for term in self._terms if not term.coefficient().is_zero() ]
|
|
2185
|
+
if include_zero:
|
|
2186
|
+
return self._terms
|
|
2187
|
+
else:
|
|
2188
|
+
return self._terms_nonzero
|
|
2189
|
+
|
|
2190
|
+
def monomials(self):
|
|
2191
|
+
r"""
|
|
2192
|
+
Return a list of the monomials of this series.
|
|
2193
|
+
|
|
2194
|
+
EXAMPLES::
|
|
2195
|
+
|
|
2196
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2197
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2198
|
+
sage: f = 2*x^2 + x
|
|
2199
|
+
sage: f.monomials() # indirect doctest
|
|
2200
|
+
[...0000000001*x, ...0000000001*x^2]
|
|
2201
|
+
"""
|
|
2202
|
+
return [ t.monomial() for t in self.terms() ]
|
|
2203
|
+
|
|
2204
|
+
def monomial_coefficients(self):
|
|
2205
|
+
"""
|
|
2206
|
+
Return a dictionary whose keys are the exponents and whose values
|
|
2207
|
+
are the corresponding coefficients of this series.
|
|
2208
|
+
|
|
2209
|
+
EXAMPLES::
|
|
2210
|
+
|
|
2211
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2212
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2213
|
+
sage: f = 2*x^2 + x
|
|
2214
|
+
sage: f.monomial_coefficients()
|
|
2215
|
+
{(1, 0): ...0000000001, (2, 0): ...00000000010}
|
|
2216
|
+
|
|
2217
|
+
``dict`` is an alias::
|
|
2218
|
+
|
|
2219
|
+
sage: f.dict()
|
|
2220
|
+
{(1, 0): ...0000000001, (2, 0): ...00000000010}
|
|
2221
|
+
"""
|
|
2222
|
+
self._normalize()
|
|
2223
|
+
return dict(self._poly.__repn)
|
|
2224
|
+
|
|
2225
|
+
dict = monomial_coefficients
|
|
2226
|
+
|
|
2227
|
+
def coefficient(self, exponent):
|
|
2228
|
+
r"""
|
|
2229
|
+
Return the coefficient corresponding to the given exponent.
|
|
2230
|
+
|
|
2231
|
+
INPUT:
|
|
2232
|
+
|
|
2233
|
+
- ``exponent`` -- tuple of integers
|
|
2234
|
+
|
|
2235
|
+
EXAMPLES::
|
|
2236
|
+
|
|
2237
|
+
sage: R = Zp(2, prec=10, print_mode='terse')
|
|
2238
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2239
|
+
sage: f = 2*x^2 + 53*x*y + y^3
|
|
2240
|
+
|
|
2241
|
+
sage: f.coefficient((2,0)) # coeff in x^2
|
|
2242
|
+
2 + O(2^11)
|
|
2243
|
+
sage: f.coefficient((1,1)) # coeff in x*y
|
|
2244
|
+
53 + O(2^10)
|
|
2245
|
+
sage: f.coefficient((3,0)) # coeff in x^3
|
|
2246
|
+
0
|
|
2247
|
+
|
|
2248
|
+
sage: g = f.add_bigoh(5)
|
|
2249
|
+
sage: g.coefficient((2,0)) # coeff in x^2
|
|
2250
|
+
2 + O(2^5)
|
|
2251
|
+
sage: g.coefficient((1,1)) # coeff in x*y
|
|
2252
|
+
21 + O(2^5)
|
|
2253
|
+
sage: g.coefficient((3,0)) # coeff in x^3
|
|
2254
|
+
O(2^5)
|
|
2255
|
+
"""
|
|
2256
|
+
if not self._is_normalized:
|
|
2257
|
+
self._normalize()
|
|
2258
|
+
try:
|
|
2259
|
+
e = ETuple(exponent)
|
|
2260
|
+
except TypeError:
|
|
2261
|
+
raise IndexError("%s is not a correct exponent" % exponent)
|
|
2262
|
+
if len(e) != self.parent().ngens():
|
|
2263
|
+
raise IndexError("lengths do not match")
|
|
2264
|
+
if e in self._poly.__repn:
|
|
2265
|
+
return self._poly.__repn[e]
|
|
2266
|
+
else:
|
|
2267
|
+
return self.base_ring()(0, self.precision_absolute())
|
|
2268
|
+
|
|
2269
|
+
def __getitem__(self, exponent):
|
|
2270
|
+
r"""
|
|
2271
|
+
Return the coefficient corresponding to the given exponent.
|
|
2272
|
+
|
|
2273
|
+
INPUT:
|
|
2274
|
+
|
|
2275
|
+
- ``exponent`` -- tuple of integers
|
|
2276
|
+
|
|
2277
|
+
TESTS::
|
|
2278
|
+
|
|
2279
|
+
sage: R = Zp(2, prec=10, print_mode='terse')
|
|
2280
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2281
|
+
sage: f = 2*x^2 + 53*x*y + y^3
|
|
2282
|
+
|
|
2283
|
+
sage: f['hello']
|
|
2284
|
+
Traceback (most recent call last):
|
|
2285
|
+
...
|
|
2286
|
+
IndexError: hello is not a correct exponent
|
|
2287
|
+
|
|
2288
|
+
sage: f[1,2,3]
|
|
2289
|
+
Traceback (most recent call last):
|
|
2290
|
+
...
|
|
2291
|
+
IndexError: lengths do not match
|
|
2292
|
+
"""
|
|
2293
|
+
return self.coefficient(exponent)
|
|
2294
|
+
|
|
2295
|
+
def coefficients(self):
|
|
2296
|
+
r"""
|
|
2297
|
+
Return the list of coefficients of this series.
|
|
2298
|
+
|
|
2299
|
+
EXAMPLES::
|
|
2300
|
+
|
|
2301
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2302
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2303
|
+
sage: f = x + 2*x^2
|
|
2304
|
+
sage: f.coefficients()
|
|
2305
|
+
[...0000000001, ...00000000010]
|
|
2306
|
+
"""
|
|
2307
|
+
return [ t.coefficient() for t in self.terms() ]
|
|
2308
|
+
|
|
2309
|
+
def add_bigoh(self, n):
|
|
2310
|
+
r"""
|
|
2311
|
+
Return this series truncated at precision ``n``.
|
|
2312
|
+
|
|
2313
|
+
INPUT:
|
|
2314
|
+
|
|
2315
|
+
- ``n`` -- integer
|
|
2316
|
+
|
|
2317
|
+
EXAMPLES::
|
|
2318
|
+
|
|
2319
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2320
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2321
|
+
sage: f = 32*x + 64*x^2; f
|
|
2322
|
+
...000000000100000*x + ...0000000001000000*x^2
|
|
2323
|
+
sage: f.add_bigoh(5)
|
|
2324
|
+
O(2^5 * <x, y>)
|
|
2325
|
+
|
|
2326
|
+
sage: g = f.add_bigoh(6); g
|
|
2327
|
+
...100000*x + O(2^6 * <x, y>)
|
|
2328
|
+
sage: g.precision_absolute()
|
|
2329
|
+
6
|
|
2330
|
+
"""
|
|
2331
|
+
return self._parent(self, prec=n)
|
|
2332
|
+
|
|
2333
|
+
def lift_to_precision(self, prec=None):
|
|
2334
|
+
"""
|
|
2335
|
+
Return a lift of this series at precision ``prec``.
|
|
2336
|
+
|
|
2337
|
+
INPUT:
|
|
2338
|
+
|
|
2339
|
+
- ``prec`` -- integer or ``None`` (default: ``None``); if
|
|
2340
|
+
``None``, the cap of the parent is used if it is higher than
|
|
2341
|
+
the current precision
|
|
2342
|
+
|
|
2343
|
+
EXAMPLES::
|
|
2344
|
+
|
|
2345
|
+
sage: R = Zp(2, prec=10)
|
|
2346
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2347
|
+
sage: f = R(1,4)*x*y + R(1,5)*x + R(1,8)*y
|
|
2348
|
+
sage: f
|
|
2349
|
+
(1 + O(2^4))*x*y + (1 + O(2^5))*x + (1 + O(2^8))*y
|
|
2350
|
+
|
|
2351
|
+
This method lifts the precision of the coefficients::
|
|
2352
|
+
|
|
2353
|
+
sage: f.lift_to_precision()
|
|
2354
|
+
(1 + O(2^10))*x*y + (1 + O(2^10))*x + (1 + O(2^10))*y
|
|
2355
|
+
|
|
2356
|
+
and also acts on the global ``O(.)`` of the series::
|
|
2357
|
+
|
|
2358
|
+
sage: g = f.add_bigoh(7)
|
|
2359
|
+
sage: g
|
|
2360
|
+
(1 + O(2^4))*x*y + (1 + O(2^5))*x + (1 + O(2^7))*y + O(2^7 * <x, y>)
|
|
2361
|
+
sage: g.lift_to_precision()
|
|
2362
|
+
(1 + O(2^10))*x*y + (1 + O(2^10))*x + (1 + O(2^10))*y + O(2^10 * <x, y>)
|
|
2363
|
+
|
|
2364
|
+
sage: g.lift_to_precision(9)
|
|
2365
|
+
(1 + O(2^9))*x*y + (1 + O(2^9))*x + (1 + O(2^9))*y + O(2^9 * <x, y>)
|
|
2366
|
+
|
|
2367
|
+
In the next example, the precision on the coefficient is only lifted
|
|
2368
|
+
to ``O(2^10)`` because it is limited by the cap of the underlying
|
|
2369
|
+
`p`-adic ring::
|
|
2370
|
+
|
|
2371
|
+
sage: g.lift_to_precision(20)
|
|
2372
|
+
(1 + O(2^10))*x*y + (1 + O(2^10))*x + (1 + O(2^10))*y + O(2^20 * <x, y>)
|
|
2373
|
+
"""
|
|
2374
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
2375
|
+
# Hmm, shouldn't we add a keyword argument to lift_to_precision()
|
|
2376
|
+
# to specify that we don't want it to raise an error
|
|
2377
|
+
|
|
2378
|
+
def lift_without_error(elt):
|
|
2379
|
+
try:
|
|
2380
|
+
return elt.lift_to_precision(prec)
|
|
2381
|
+
except PrecisionError:
|
|
2382
|
+
return elt.lift_to_precision()
|
|
2383
|
+
ans._poly = PolyDict({e: lift_without_error(c)
|
|
2384
|
+
for e, c in self._poly.__repn.items()},
|
|
2385
|
+
None)
|
|
2386
|
+
if prec is None:
|
|
2387
|
+
prec = self._parent.precision_cap()
|
|
2388
|
+
ans._prec = max(self._prec, prec)
|
|
2389
|
+
return ans
|
|
2390
|
+
|
|
2391
|
+
def precision_absolute(self):
|
|
2392
|
+
r"""
|
|
2393
|
+
Return the maximal precision at which a term of this series is known.
|
|
2394
|
+
|
|
2395
|
+
EXAMPLES::
|
|
2396
|
+
|
|
2397
|
+
sage: R = Zp(2, prec=10, print_mode='digits')
|
|
2398
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2399
|
+
sage: f = x + 2*x^2; f
|
|
2400
|
+
...0000000001*x + ...00000000010*x^2
|
|
2401
|
+
sage: f.precision_absolute()
|
|
2402
|
+
+Infinity
|
|
2403
|
+
|
|
2404
|
+
sage: g = f.add_bigoh(5); g
|
|
2405
|
+
...00001*x + ...00010*x^2 + O(2^5 * <x, y>)
|
|
2406
|
+
sage: g.precision_absolute()
|
|
2407
|
+
5
|
|
2408
|
+
|
|
2409
|
+
The absolute precision may be higher than the precision of some
|
|
2410
|
+
individual coefficients::
|
|
2411
|
+
|
|
2412
|
+
sage: g = f.add_bigoh(20); g
|
|
2413
|
+
...0000000001*x + ...00000000010*x^2 + O(2^20 * <x, y>)
|
|
2414
|
+
sage: g.precision_absolute()
|
|
2415
|
+
20
|
|
2416
|
+
"""
|
|
2417
|
+
return self._prec
|
|
2418
|
+
|
|
2419
|
+
cpdef valuation(self):
|
|
2420
|
+
r"""
|
|
2421
|
+
Return the valuation of this series.
|
|
2422
|
+
|
|
2423
|
+
.. NOTE::
|
|
2424
|
+
|
|
2425
|
+
The valuation of a series `f` is defined as the minimal
|
|
2426
|
+
valuation of `f(x)` for `x` varying in the domain of convergence
|
|
2427
|
+
(specified in the parent).
|
|
2428
|
+
|
|
2429
|
+
EXAMPLES::
|
|
2430
|
+
|
|
2431
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2432
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2433
|
+
sage: f = x^4 + 4*x*y + 1; f
|
|
2434
|
+
...0000000001*x^4 + ...0000000001 + ...000000000100*x*y
|
|
2435
|
+
sage: f.valuation()
|
|
2436
|
+
0
|
|
2437
|
+
|
|
2438
|
+
sage: g = 2*f; g
|
|
2439
|
+
...00000000010*x^4 + ...00000000010 + ...0000000001000*x*y
|
|
2440
|
+
sage: g.valuation()
|
|
2441
|
+
1
|
|
2442
|
+
|
|
2443
|
+
When the radius of convergence is not 1, the variables themselves
|
|
2444
|
+
have a nontrivial valuation::
|
|
2445
|
+
|
|
2446
|
+
sage: A.<x,y> = TateAlgebra(R, log_radii=(1,2))
|
|
2447
|
+
sage: x.valuation()
|
|
2448
|
+
-1
|
|
2449
|
+
sage: y.valuation()
|
|
2450
|
+
-2
|
|
2451
|
+
|
|
2452
|
+
sage: f = x^4 + 4*x*y + 1
|
|
2453
|
+
sage: f.valuation()
|
|
2454
|
+
-4
|
|
2455
|
+
"""
|
|
2456
|
+
cdef TateAlgebraTerm t
|
|
2457
|
+
cdef list terms = self._terms_c()
|
|
2458
|
+
if terms:
|
|
2459
|
+
return min(terms[0].valuation(), self._prec)
|
|
2460
|
+
else:
|
|
2461
|
+
return self._prec
|
|
2462
|
+
|
|
2463
|
+
def precision_relative(self):
|
|
2464
|
+
"""
|
|
2465
|
+
Return the relative precision of this series.
|
|
2466
|
+
|
|
2467
|
+
The relative precision is defined as the difference
|
|
2468
|
+
between the absolute precision and the valuation.
|
|
2469
|
+
|
|
2470
|
+
EXAMPLES::
|
|
2471
|
+
|
|
2472
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2473
|
+
sage: A.<x,y> = TateAlgebra(R.fraction_field())
|
|
2474
|
+
sage: f = x^4 + 4*x*y + 1; f
|
|
2475
|
+
...0000000001*x^4 + ...0000000001 + ...000000000100*x*y
|
|
2476
|
+
sage: f.precision_relative()
|
|
2477
|
+
+Infinity
|
|
2478
|
+
|
|
2479
|
+
sage: g = f.add_bigoh(5)
|
|
2480
|
+
sage: g.precision_relative()
|
|
2481
|
+
5
|
|
2482
|
+
sage: g.precision_absolute()
|
|
2483
|
+
5
|
|
2484
|
+
sage: g.valuation()
|
|
2485
|
+
0
|
|
2486
|
+
|
|
2487
|
+
sage: h = g + 1/2 ; h
|
|
2488
|
+
...00001.1 + ...00001*x^4 + ...00100*x*y + O(2^5 * <x, y>)
|
|
2489
|
+
sage: h.precision_relative()
|
|
2490
|
+
6
|
|
2491
|
+
sage: h.precision_absolute()
|
|
2492
|
+
5
|
|
2493
|
+
sage: h.valuation()
|
|
2494
|
+
-1
|
|
2495
|
+
"""
|
|
2496
|
+
return self._prec - self.valuation()
|
|
2497
|
+
|
|
2498
|
+
def log(self, prec=None):
|
|
2499
|
+
r"""
|
|
2500
|
+
Return the logarithm of this series.
|
|
2501
|
+
|
|
2502
|
+
INPUT:
|
|
2503
|
+
|
|
2504
|
+
- ``prec`` -- integer or ``None`` (default: ``None``); the
|
|
2505
|
+
absolute precision at which the result is computed, if ``None``
|
|
2506
|
+
the cap of the Tate algebra is used
|
|
2507
|
+
|
|
2508
|
+
EXAMPLES::
|
|
2509
|
+
|
|
2510
|
+
sage: R = Zp(3, 10, print_mode='digits')
|
|
2511
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2512
|
+
sage: f = 1 + 3*x + 9*y^2
|
|
2513
|
+
sage: f.log()
|
|
2514
|
+
...0000000010*x + ...0000000100*x^3 + ...1111111100*x^2 + ...0000000100*y^2
|
|
2515
|
+
+ ...2222222000*x*y^2 + ... + O(3^10 * <x, y>)
|
|
2516
|
+
|
|
2517
|
+
sage: f.log(prec=4)
|
|
2518
|
+
...0010*x + ...0100*x^3 + ...1100*x^2 + ...0100*y^2 + ...2000*x*y^2
|
|
2519
|
+
+ O(3^4 * <x, y>)
|
|
2520
|
+
|
|
2521
|
+
If the precision on the input is not enough to determine the
|
|
2522
|
+
result at precision ``prec``, a result with smaller precision
|
|
2523
|
+
is returned::
|
|
2524
|
+
|
|
2525
|
+
sage: g = f.add_bigoh(4); g
|
|
2526
|
+
...0001 + ...0010*x + ...0100*y^2 + O(3^4 * <x, y>)
|
|
2527
|
+
sage: g.log()
|
|
2528
|
+
...0010*x + ...0100*x^3 + ...1100*x^2 + ...0100*y^2 + ...2000*x*y^2
|
|
2529
|
+
+ O(3^4 * <x, y>)
|
|
2530
|
+
sage: g.log(prec=10)
|
|
2531
|
+
...0010*x + ...0100*x^3 + ...1100*x^2 + ...0100*y^2 + ...2000*x*y^2
|
|
2532
|
+
+ O(3^4 * <x, y>)
|
|
2533
|
+
|
|
2534
|
+
When the input value is outside the domain of convergence, an
|
|
2535
|
+
error is raised::
|
|
2536
|
+
|
|
2537
|
+
sage: f = 1 + x
|
|
2538
|
+
sage: f.log()
|
|
2539
|
+
Traceback (most recent call last):
|
|
2540
|
+
...
|
|
2541
|
+
ValueError: not in the domain of convergence
|
|
2542
|
+
|
|
2543
|
+
However `\log(1+x)` converges on a smaller disk::
|
|
2544
|
+
|
|
2545
|
+
sage: f.restriction(-1).log()
|
|
2546
|
+
...000000001*x + ...0000000.1*x^3 + ...111111*x^2 + ...
|
|
2547
|
+
+ O(3^10 * <3*x, 3*y>)
|
|
2548
|
+
|
|
2549
|
+
TESTS::
|
|
2550
|
+
|
|
2551
|
+
sage: f = 1 + 3 * A.random_element(integral=True)
|
|
2552
|
+
sage: logf = f.log()
|
|
2553
|
+
|
|
2554
|
+
sage: x0 = 3 * R.random_element()
|
|
2555
|
+
sage: y0 = 3 * R.random_element()
|
|
2556
|
+
sage: f(x0, y0).log() == logf(x0, y0)
|
|
2557
|
+
True
|
|
2558
|
+
|
|
2559
|
+
sage: logf.exp() == f
|
|
2560
|
+
True
|
|
2561
|
+
"""
|
|
2562
|
+
# This code is mostly copied from sage.rings.padics.padic_generic_element
|
|
2563
|
+
# (should we find a way to share it?)
|
|
2564
|
+
R = self.parent()
|
|
2565
|
+
p = R.base_ring().prime()
|
|
2566
|
+
e = R.absolute_e()
|
|
2567
|
+
x = 1 - self
|
|
2568
|
+
alpha = x.valuation()
|
|
2569
|
+
if alpha <= 0:
|
|
2570
|
+
raise ValueError("not in the domain of convergence")
|
|
2571
|
+
|
|
2572
|
+
aprec = self.precision_absolute()
|
|
2573
|
+
if prec is not None and prec < aprec:
|
|
2574
|
+
aprec = prec
|
|
2575
|
+
if aprec is Infinity:
|
|
2576
|
+
aprec = R.precision_cap()
|
|
2577
|
+
|
|
2578
|
+
mina = 0
|
|
2579
|
+
if e != 1:
|
|
2580
|
+
lamb = aprec - alpha
|
|
2581
|
+
if lamb > 0 and lamb*(p-1) <= e:
|
|
2582
|
+
# This is the precision region where the absolute
|
|
2583
|
+
# precision of the answer might be less than the
|
|
2584
|
+
# absolute precision of the input
|
|
2585
|
+
|
|
2586
|
+
# kink is the number of times we multiply the relative
|
|
2587
|
+
# precision by p before starting to add e instead.
|
|
2588
|
+
kink = (e // (lamb * (p-1))).exact_log(p) + 1
|
|
2589
|
+
|
|
2590
|
+
# deriv0 is within 1 of the n yielding the minimal
|
|
2591
|
+
# absolute precision
|
|
2592
|
+
tmp = (e / (aprec * p.log(prec=53))).floor()
|
|
2593
|
+
if tmp > 0:
|
|
2594
|
+
deriv0 = tmp.exact_log(p)
|
|
2595
|
+
else:
|
|
2596
|
+
deriv0 = 0
|
|
2597
|
+
|
|
2598
|
+
# These are the absolute precisions of x^(p^n) at potential minimum points
|
|
2599
|
+
L = [(aprec * p**n - n * e, n) for n in [0, kink, deriv0, deriv0+1]]
|
|
2600
|
+
L.sort()
|
|
2601
|
+
aprec = L[0][0]
|
|
2602
|
+
mina = L[0][1]
|
|
2603
|
+
|
|
2604
|
+
total = R.zero()
|
|
2605
|
+
if mina == 0 and alpha*p - e > aprec:
|
|
2606
|
+
# The value of x^p/p is not needed in that case
|
|
2607
|
+
x2p_p = R(0)
|
|
2608
|
+
else:
|
|
2609
|
+
x2p_p = x**p / p
|
|
2610
|
+
|
|
2611
|
+
# To get result right to precision aprec, we need all terms for which
|
|
2612
|
+
# the valuation of x^n/n is strictly smaller than aprec.
|
|
2613
|
+
# If we rewrite n=u*p^a with u a p-adic unit, then these are the terms
|
|
2614
|
+
# for which u<(aprec+a*v(p))/(v(x)*p^a).
|
|
2615
|
+
# Two sum over these terms, we run two nested loops, the outer one
|
|
2616
|
+
# iterates over the possible values for a, the inner one iterates over
|
|
2617
|
+
# the possible values for u.
|
|
2618
|
+
upper_u = (aprec/alpha).floor()
|
|
2619
|
+
if mina > 0 or upper_u > 0:
|
|
2620
|
+
a=0
|
|
2621
|
+
p2a=1 # p^a
|
|
2622
|
+
x2pa = x # x^(p^a)
|
|
2623
|
+
|
|
2624
|
+
# In the unramified case, we can stop summing terms as soon as
|
|
2625
|
+
# there are no u for a given a to sum over. In the ramified case,
|
|
2626
|
+
# it can happen that for some initial a there are no such u but
|
|
2627
|
+
# later in the series there are such u again. mina can be set to
|
|
2628
|
+
# take care of this by summing at least to a=mina-1
|
|
2629
|
+
while True:
|
|
2630
|
+
# we compute the sum for the possible values for u using Horner's method
|
|
2631
|
+
inner_sum = R.zero()
|
|
2632
|
+
for u in range(upper_u,0,-1):
|
|
2633
|
+
# We want u to be a p-adic unit
|
|
2634
|
+
if u % p==0:
|
|
2635
|
+
new_term = R.zero()
|
|
2636
|
+
else:
|
|
2637
|
+
new_term = ~R.base_ring()(u)
|
|
2638
|
+
|
|
2639
|
+
# This hack is to deal with rings that don't lift to fields
|
|
2640
|
+
if u > 1 or x2p_p.is_zero():
|
|
2641
|
+
inner_sum = (inner_sum+new_term)*x2pa
|
|
2642
|
+
else:
|
|
2643
|
+
inner_sum = (inner_sum+new_term)*(x2p_p**a)*(x**(p2a-a*p))
|
|
2644
|
+
|
|
2645
|
+
total -= inner_sum
|
|
2646
|
+
|
|
2647
|
+
# Now increase a and check if a new iteration of the loop is needed
|
|
2648
|
+
a += 1
|
|
2649
|
+
p2a *= p
|
|
2650
|
+
upper_u = ((aprec + a*e)/(alpha * p2a)).floor()
|
|
2651
|
+
if a >= mina and upper_u <= 0: break
|
|
2652
|
+
|
|
2653
|
+
# We perform this last operation after the test
|
|
2654
|
+
# because it is costly and may raise OverflowError
|
|
2655
|
+
x2pa = x2pa**p
|
|
2656
|
+
|
|
2657
|
+
return total.add_bigoh(aprec)
|
|
2658
|
+
|
|
2659
|
+
def exp(self, prec=None):
|
|
2660
|
+
r"""
|
|
2661
|
+
Return the exponential of this series.
|
|
2662
|
+
|
|
2663
|
+
INPUT:
|
|
2664
|
+
|
|
2665
|
+
- ``prec`` -- integer or ``None`` (default: ``None``); the
|
|
2666
|
+
absolute precision at which the result is computed, if ``None``
|
|
2667
|
+
the cap of the Tate algebra is used
|
|
2668
|
+
|
|
2669
|
+
EXAMPLES::
|
|
2670
|
+
|
|
2671
|
+
sage: R = Zp(3, 10, print_mode='digits')
|
|
2672
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2673
|
+
sage: f = 3*x^2 + 9*y
|
|
2674
|
+
sage: f.exp()
|
|
2675
|
+
...0000000001 + ...0000000010*x^2 + ...1111111200*x^6 + ...1111111200*x^4
|
|
2676
|
+
+ ...0000000100*y + ... + O(3^10 * <x, y>)
|
|
2677
|
+
|
|
2678
|
+
sage: f.exp(prec=3)
|
|
2679
|
+
...001 + ...010*x^2 + ...200*x^6 + ...200*x^4 + ...100*y + O(3^3 * <x, y>)
|
|
2680
|
+
|
|
2681
|
+
If the precision on the input is not enough to determine the
|
|
2682
|
+
result at precision ``prec``, a result with smaller precision
|
|
2683
|
+
is returned::
|
|
2684
|
+
|
|
2685
|
+
sage: g = f.add_bigoh(3); g
|
|
2686
|
+
...010*x^2 + ...100*y + O(3^3 * <x, y>)
|
|
2687
|
+
sage: g.exp()
|
|
2688
|
+
...001 + ...010*x^2 + ...200*x^6 + ...200*x^4 + ...100*y + O(3^3 * <x, y>)
|
|
2689
|
+
sage: g.exp(prec=10)
|
|
2690
|
+
...001 + ...010*x^2 + ...200*x^6 + ...200*x^4 + ...100*y + O(3^3 * <x, y>)
|
|
2691
|
+
|
|
2692
|
+
When the input value is outside the domain of convergence, an
|
|
2693
|
+
error is raised::
|
|
2694
|
+
|
|
2695
|
+
sage: f = x
|
|
2696
|
+
sage: f.exp()
|
|
2697
|
+
Traceback (most recent call last):
|
|
2698
|
+
...
|
|
2699
|
+
ValueError: not in the domain of convergence
|
|
2700
|
+
|
|
2701
|
+
However `\exp(x)` converges on a smaller disk::
|
|
2702
|
+
|
|
2703
|
+
sage: f.restriction(-1).exp()
|
|
2704
|
+
...0000000001 + ...000000001*x + ...1111111.2*x^3 + ...111112*x^2
|
|
2705
|
+
+ ... + O(3^10 * <3*x, 3*y>)
|
|
2706
|
+
|
|
2707
|
+
TESTS::
|
|
2708
|
+
|
|
2709
|
+
sage: f = 3 * A.random_element(integral=True)
|
|
2710
|
+
sage: expf = f.exp()
|
|
2711
|
+
|
|
2712
|
+
sage: x0 = 3 * R.random_element()
|
|
2713
|
+
sage: y0 = 3 * R.random_element()
|
|
2714
|
+
sage: f(x0, y0).exp() == expf(x0, y0)
|
|
2715
|
+
True
|
|
2716
|
+
|
|
2717
|
+
sage: expf.log() == f # long time
|
|
2718
|
+
True
|
|
2719
|
+
"""
|
|
2720
|
+
# This code is mostly copied from sage.rings.padics.padic_generic_element
|
|
2721
|
+
# (should we find a way to share it?)
|
|
2722
|
+
A = self.parent()
|
|
2723
|
+
R = A.base_ring()
|
|
2724
|
+
p = R.prime()
|
|
2725
|
+
e = R.absolute_e()
|
|
2726
|
+
x_val = self.valuation()
|
|
2727
|
+
|
|
2728
|
+
if (p-1) * x_val <= e:
|
|
2729
|
+
raise ValueError("not in the domain of convergence")
|
|
2730
|
+
|
|
2731
|
+
aprec = self.precision_absolute()
|
|
2732
|
+
if aprec is Infinity:
|
|
2733
|
+
aprec = R.precision_cap()
|
|
2734
|
+
if prec is not None and prec < aprec:
|
|
2735
|
+
aprec = prec
|
|
2736
|
+
|
|
2737
|
+
# the valuation of n! is bounded by e*n/(p-1), therefore the valuation
|
|
2738
|
+
# of self^n/n! is bigger or equal to n*x_val - e*n/(p-1). So, we only
|
|
2739
|
+
# have to sum terms for which n does not exceed N
|
|
2740
|
+
N = (aprec // (x_val - e/(p-1))).floor()
|
|
2741
|
+
|
|
2742
|
+
# We evaluate the exponential series:
|
|
2743
|
+
# We compute the value of x^N + N*x^(N-1) + ... + (N-1)!*x + N!
|
|
2744
|
+
# by Horner's method. Then, we divide by N!.
|
|
2745
|
+
series = A.one()
|
|
2746
|
+
nfactorial = R.one()
|
|
2747
|
+
x = self.add_bigoh(aprec)
|
|
2748
|
+
for n in range(N, 0, -1):
|
|
2749
|
+
series *= x
|
|
2750
|
+
nfactorial *= n
|
|
2751
|
+
series += nfactorial
|
|
2752
|
+
return series / nfactorial
|
|
2753
|
+
|
|
2754
|
+
def leading_term(self, secure=False):
|
|
2755
|
+
r"""
|
|
2756
|
+
Return the leading term of this series.
|
|
2757
|
+
|
|
2758
|
+
.. NOTE::
|
|
2759
|
+
|
|
2760
|
+
The order on the terms is defined as follows: first we
|
|
2761
|
+
compare the valuation and, in case of equality, we compare
|
|
2762
|
+
the monomials with respect to the order given at the
|
|
2763
|
+
creation of the parent.
|
|
2764
|
+
|
|
2765
|
+
INPUT:
|
|
2766
|
+
|
|
2767
|
+
- ``secure`` -- boolean (default: ``False``); if ``True``,
|
|
2768
|
+
raises an error if the leading term cannot be determined
|
|
2769
|
+
due to the existence of terms which are indistinguishable
|
|
2770
|
+
from zero. If ``False``, discard silently these terms.
|
|
2771
|
+
|
|
2772
|
+
EXAMPLES::
|
|
2773
|
+
|
|
2774
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2775
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2776
|
+
sage: f = x^4 + x*y + 1; f
|
|
2777
|
+
...0000000001*x^4 + ...0000000001*x*y + ...0000000001
|
|
2778
|
+
sage: f.leading_term()
|
|
2779
|
+
...0000000001*x^4
|
|
2780
|
+
|
|
2781
|
+
sage: g = f + x^4; g
|
|
2782
|
+
...0000000001*x*y + ...0000000001 + ...0000000010*x^4
|
|
2783
|
+
sage: g.leading_monomial()
|
|
2784
|
+
...0000000001*x*y
|
|
2785
|
+
|
|
2786
|
+
Observe that the leading term may change after restriction::
|
|
2787
|
+
|
|
2788
|
+
sage: f.restriction(-1).leading_term()
|
|
2789
|
+
...0000000001
|
|
2790
|
+
|
|
2791
|
+
TESTS::
|
|
2792
|
+
|
|
2793
|
+
sage: f = 1 + 64*x
|
|
2794
|
+
sage: f -= R(1, 5)
|
|
2795
|
+
sage: f
|
|
2796
|
+
...00000 + ...0000000001000000*x
|
|
2797
|
+
|
|
2798
|
+
sage: f.leading_term()
|
|
2799
|
+
...0000000001000000*x
|
|
2800
|
+
sage: f.leading_term(secure=True)
|
|
2801
|
+
Traceback (most recent call last):
|
|
2802
|
+
...
|
|
2803
|
+
PrecisionError: not enough precision to determine the leading term
|
|
2804
|
+
|
|
2805
|
+
sage: g = A(0, 10); g
|
|
2806
|
+
O(2^10 * <x, y>)
|
|
2807
|
+
sage: g.leading_term()
|
|
2808
|
+
Traceback (most recent call last):
|
|
2809
|
+
...
|
|
2810
|
+
ValueError: zero has no leading term
|
|
2811
|
+
sage: g.leading_term(secure=True)
|
|
2812
|
+
Traceback (most recent call last):
|
|
2813
|
+
...
|
|
2814
|
+
PrecisionError: not enough precision to determine the leading term
|
|
2815
|
+
|
|
2816
|
+
.. SEEALSO::
|
|
2817
|
+
|
|
2818
|
+
:meth:`leading_coefficient`, :meth:`leading_monomial`
|
|
2819
|
+
"""
|
|
2820
|
+
cdef list terms
|
|
2821
|
+
cdef TateAlgebraTerm term
|
|
2822
|
+
if secure:
|
|
2823
|
+
terms = self._terms_c()
|
|
2824
|
+
else:
|
|
2825
|
+
terms = self._terms_c(include_zero=False)
|
|
2826
|
+
if terms:
|
|
2827
|
+
term = terms[0]
|
|
2828
|
+
if term.coefficient().is_zero():
|
|
2829
|
+
raise PrecisionError("not enough precision to determine the leading term")
|
|
2830
|
+
return term
|
|
2831
|
+
if secure and self._prec is not Infinity:
|
|
2832
|
+
raise PrecisionError("not enough precision to determine the leading term")
|
|
2833
|
+
else:
|
|
2834
|
+
raise ValueError("zero has no leading term")
|
|
2835
|
+
|
|
2836
|
+
def leading_coefficient(self, secure=False):
|
|
2837
|
+
"""
|
|
2838
|
+
Return the leading coefficient of this series.
|
|
2839
|
+
|
|
2840
|
+
.. NOTE::
|
|
2841
|
+
|
|
2842
|
+
The leading coefficient is the coefficient of the leading term.
|
|
2843
|
+
|
|
2844
|
+
INPUT:
|
|
2845
|
+
|
|
2846
|
+
- ``secure`` -- boolean (default: ``False``); if ``True``,
|
|
2847
|
+
raises an error if the leading term cannot be determined
|
|
2848
|
+
due to the existence of terms which are indistinguishable
|
|
2849
|
+
from zero. If ``False``, discard silently these terms.
|
|
2850
|
+
|
|
2851
|
+
EXAMPLES::
|
|
2852
|
+
|
|
2853
|
+
sage: R = Zp(2, prec=10, print_mode='terse')
|
|
2854
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2855
|
+
sage: f = x^4 + 3*x*y + 1; f
|
|
2856
|
+
(1 + O(2^10))*x^4 + (3 + O(2^10))*x*y + (1 + O(2^10))
|
|
2857
|
+
sage: f.leading_coefficient()
|
|
2858
|
+
1 + O(2^10)
|
|
2859
|
+
|
|
2860
|
+
sage: g = f + x^4; g
|
|
2861
|
+
(3 + O(2^10))*x*y + (1 + O(2^10)) + (2 + O(2^10))*x^4
|
|
2862
|
+
sage: g.leading_coefficient()
|
|
2863
|
+
3 + O(2^10)
|
|
2864
|
+
|
|
2865
|
+
.. SEEALSO::
|
|
2866
|
+
|
|
2867
|
+
:meth:`leading_term`, :meth:`leading_monomial`
|
|
2868
|
+
"""
|
|
2869
|
+
return self.leading_term(secure=secure).coefficient()
|
|
2870
|
+
|
|
2871
|
+
def leading_monomial(self, secure=False):
|
|
2872
|
+
"""
|
|
2873
|
+
Return the leading coefficient of this series.
|
|
2874
|
+
|
|
2875
|
+
.. NOTE::
|
|
2876
|
+
|
|
2877
|
+
The leading monomial is the monomial of the leading term.
|
|
2878
|
+
|
|
2879
|
+
INPUT:
|
|
2880
|
+
|
|
2881
|
+
- ``secure`` -- boolean (default: ``False``); if ``True``,
|
|
2882
|
+
raises an error if the leading term cannot be determined
|
|
2883
|
+
due to the existence of terms which are indistinguishable
|
|
2884
|
+
from zero. If ``False``, discard silently these terms.
|
|
2885
|
+
|
|
2886
|
+
EXAMPLES::
|
|
2887
|
+
|
|
2888
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2889
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2890
|
+
sage: f = x^4 + x*y + 1; f
|
|
2891
|
+
...0000000001*x^4 + ...0000000001*x*y + ...0000000001
|
|
2892
|
+
sage: f.leading_monomial()
|
|
2893
|
+
...0000000001*x^4
|
|
2894
|
+
|
|
2895
|
+
sage: g = f + x^4; g
|
|
2896
|
+
...0000000001*x*y + ...0000000001 + ...0000000010*x^4
|
|
2897
|
+
sage: g.leading_monomial()
|
|
2898
|
+
...0000000001*x*y
|
|
2899
|
+
|
|
2900
|
+
.. SEEALSO::
|
|
2901
|
+
|
|
2902
|
+
:meth:`leading_term`, :meth:`leading_coefficient`
|
|
2903
|
+
"""
|
|
2904
|
+
return self.leading_term(secure=secure).monomial()
|
|
2905
|
+
|
|
2906
|
+
cpdef TateAlgebraElement monic(self):
|
|
2907
|
+
r"""
|
|
2908
|
+
Return this series normalized so that it has valuation 0
|
|
2909
|
+
and its leading coefficient is a power of the uniformizer.
|
|
2910
|
+
|
|
2911
|
+
EXAMPLES:
|
|
2912
|
+
|
|
2913
|
+
When the log radii of convergence are all zero, the
|
|
2914
|
+
leading coefficient of the returned series is `1`::
|
|
2915
|
+
|
|
2916
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2917
|
+
sage: A.<x,y> = TateAlgebra(R, order='lex')
|
|
2918
|
+
sage: f = 3*x^2*y^2 + 4*x^2*y^3 + y^5; f
|
|
2919
|
+
...0000000011*x^2*y^2 + ...0000000001*y^5 + ...000000000100*x^2*y^3
|
|
2920
|
+
sage: f.monic()
|
|
2921
|
+
...0000000001*x^2*y^2 + ...1010101011*y^5 + ...101010101100*x^2*y^3
|
|
2922
|
+
|
|
2923
|
+
However, when log radii do not vanish, behaviors might
|
|
2924
|
+
be different::
|
|
2925
|
+
|
|
2926
|
+
sage: g = f.restriction(-1); g
|
|
2927
|
+
...0000000011*x^2*y^2 + ...0000000001*y^5 + ...000000000100*x^2*y^3
|
|
2928
|
+
sage: g.monic()
|
|
2929
|
+
...000000.0001*x^2*y^2 + ...101010.1011*y^5 + ...10101010.11*x^2*y^3
|
|
2930
|
+
sage: g.monic().valuation()
|
|
2931
|
+
0
|
|
2932
|
+
|
|
2933
|
+
TESTS::
|
|
2934
|
+
|
|
2935
|
+
sage: A(0).monic()
|
|
2936
|
+
Traceback (most recent call last):
|
|
2937
|
+
...
|
|
2938
|
+
ZeroDivisionError: rational division by zero
|
|
2939
|
+
"""
|
|
2940
|
+
cdef TateAlgebraElement ans = self._new_c()
|
|
2941
|
+
cdef TateAlgebraTerm t
|
|
2942
|
+
cdef long shi
|
|
2943
|
+
cdef pAdicGenericElement u
|
|
2944
|
+
cdef list terms = self._terms_c()
|
|
2945
|
+
if not terms or terms[0].coefficient().is_zero():
|
|
2946
|
+
raise ZeroDivisionError("rational division by zero")
|
|
2947
|
+
t = terms[0]
|
|
2948
|
+
shi, u = t._coeff.val_unit()
|
|
2949
|
+
shi -= t._exponent.dotprod(self._parent._log_radii)
|
|
2950
|
+
ans._poly = self._poly.scalar_lmult((~u) >> shi)
|
|
2951
|
+
ans._prec = self._prec - shi
|
|
2952
|
+
return ans
|
|
2953
|
+
|
|
2954
|
+
def is_monic(self):
|
|
2955
|
+
"""
|
|
2956
|
+
Return ``True`` if this series is monic, in the sense
|
|
2957
|
+
that it has valuation 0 and its leading coefficient is
|
|
2958
|
+
a power of the uniformizer.
|
|
2959
|
+
|
|
2960
|
+
EXAMPLES::
|
|
2961
|
+
|
|
2962
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2963
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2964
|
+
sage: f = x*y + 2; f
|
|
2965
|
+
...0000000001*x*y + ...00000000010
|
|
2966
|
+
sage: f.is_monic()
|
|
2967
|
+
True
|
|
2968
|
+
|
|
2969
|
+
sage: g = f.restriction(-1); g
|
|
2970
|
+
...00000000010 + ...0000000001*x*y
|
|
2971
|
+
sage: g.is_monic()
|
|
2972
|
+
False
|
|
2973
|
+
"""
|
|
2974
|
+
if self.valuation() != 0:
|
|
2975
|
+
return False
|
|
2976
|
+
c = self.leading_coefficient()
|
|
2977
|
+
return c != 0 and c.unit_part() == 1
|
|
2978
|
+
|
|
2979
|
+
def weierstrass_degree(self):
|
|
2980
|
+
r"""
|
|
2981
|
+
Return the Weierstrass degree of this Tate series.
|
|
2982
|
+
|
|
2983
|
+
.. NOTE::
|
|
2984
|
+
|
|
2985
|
+
The Weierstrass degree is the total degree of the polynomial
|
|
2986
|
+
defined by the terms with least valuation in the series.
|
|
2987
|
+
|
|
2988
|
+
EXAMPLES::
|
|
2989
|
+
|
|
2990
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
2991
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
2992
|
+
sage: f = x*y + 2*x^4 + y; f
|
|
2993
|
+
...0000000001*x*y + ...0000000001*y + ...00000000010*x^4
|
|
2994
|
+
sage: f.weierstrass_degree()
|
|
2995
|
+
2
|
|
2996
|
+
"""
|
|
2997
|
+
v = self.valuation()
|
|
2998
|
+
return self.residue(v+1).degree()
|
|
2999
|
+
|
|
3000
|
+
def degree(self):
|
|
3001
|
+
r"""
|
|
3002
|
+
Return the Weierstrass degree of this Tate series.
|
|
3003
|
+
|
|
3004
|
+
.. NOTE::
|
|
3005
|
+
|
|
3006
|
+
The Weierstrass degree is the total degree of the polynomial
|
|
3007
|
+
defined by the terms with least valuation in the series.
|
|
3008
|
+
|
|
3009
|
+
EXAMPLES::
|
|
3010
|
+
|
|
3011
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
3012
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3013
|
+
sage: f = x*y + 2*x^4 + y; f
|
|
3014
|
+
...0000000001*x*y + ...0000000001*y + ...00000000010*x^4
|
|
3015
|
+
sage: f.degree()
|
|
3016
|
+
2
|
|
3017
|
+
"""
|
|
3018
|
+
return self.weierstrass_degree()
|
|
3019
|
+
|
|
3020
|
+
def weierstrass_degrees(self):
|
|
3021
|
+
r"""
|
|
3022
|
+
Return the Weierstrass degrees of this Tate series.
|
|
3023
|
+
|
|
3024
|
+
.. NOTE::
|
|
3025
|
+
|
|
3026
|
+
The Weierstrass degrees are the partial degrees of the polynomial
|
|
3027
|
+
defined by the terms with least valuation in the series.
|
|
3028
|
+
|
|
3029
|
+
EXAMPLES::
|
|
3030
|
+
|
|
3031
|
+
sage: R = Zp(2, print_mode='digits',prec=10)
|
|
3032
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3033
|
+
sage: f = x^2 + y^2 + 2*x^3 + y; f
|
|
3034
|
+
...0000000001*x^2 + ...0000000001*y^2 + ...0000000001*y + ...00000000010*x^3
|
|
3035
|
+
sage: f.weierstrass_degrees()
|
|
3036
|
+
(2, 2)
|
|
3037
|
+
"""
|
|
3038
|
+
v = self.valuation()
|
|
3039
|
+
return self.residue(v+1).degrees()
|
|
3040
|
+
|
|
3041
|
+
def degrees(self):
|
|
3042
|
+
r"""
|
|
3043
|
+
Return the Weierstrass degrees of this series.
|
|
3044
|
+
|
|
3045
|
+
.. NOTE::
|
|
3046
|
+
|
|
3047
|
+
The Weierstrass degrees are the partial degrees of the polynomial
|
|
3048
|
+
defined by the terms with least valuation in the series.
|
|
3049
|
+
|
|
3050
|
+
EXAMPLES::
|
|
3051
|
+
|
|
3052
|
+
sage: R = Zp(2, print_mode='digits',prec=10)
|
|
3053
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3054
|
+
sage: f = x^2 + y^2 + 2*x^3 + y; f
|
|
3055
|
+
...0000000001*x^2 + ...0000000001*y^2 + ...0000000001*y + ...00000000010*x^3
|
|
3056
|
+
sage: f.degrees()
|
|
3057
|
+
(2, 2)
|
|
3058
|
+
"""
|
|
3059
|
+
return self.weierstrass_degrees()
|
|
3060
|
+
|
|
3061
|
+
def residue(self, n=None):
|
|
3062
|
+
r"""
|
|
3063
|
+
Return this series modulo the ``n``-th power of the uniformizer.
|
|
3064
|
+
|
|
3065
|
+
Note that by definition of Tate series, the output is a polynomial.
|
|
3066
|
+
|
|
3067
|
+
INPUT:
|
|
3068
|
+
|
|
3069
|
+
- ``n`` -- integer (default: `1`)
|
|
3070
|
+
|
|
3071
|
+
EXAMPLES::
|
|
3072
|
+
|
|
3073
|
+
sage: R = Zp(2, print_mode='digits', prec=10)
|
|
3074
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3075
|
+
sage: f = x^2 + y^2 + 6*x^3 + 3*y
|
|
3076
|
+
sage: f.residue()
|
|
3077
|
+
x^2 + y^2 + y
|
|
3078
|
+
sage: f.residue().parent()
|
|
3079
|
+
Multivariate Polynomial Ring in x, y over Finite Field of size 2
|
|
3080
|
+
|
|
3081
|
+
sage: f.residue(2)
|
|
3082
|
+
2*x^3 + x^2 + y^2 - y
|
|
3083
|
+
sage: f.residue(2).parent()
|
|
3084
|
+
Multivariate Polynomial Ring in x, y over Ring of integers modulo 4
|
|
3085
|
+
|
|
3086
|
+
The residue can only be computed for series with nonnegative valuation.
|
|
3087
|
+
|
|
3088
|
+
sage: g = f >> 2; g
|
|
3089
|
+
...00000000.01*x^2 + ...00000000.01*y^2 + ...00000000.11*y + ...000000001.1*x^3
|
|
3090
|
+
sage: g.residue()
|
|
3091
|
+
Traceback (most recent call last):
|
|
3092
|
+
...
|
|
3093
|
+
ValueError: element must have nonnegative valuation in order to compute residue
|
|
3094
|
+
|
|
3095
|
+
The residue is not implemented for series with convergence radius different from 1.
|
|
3096
|
+
|
|
3097
|
+
sage: A.<x,y> = TateAlgebra(R, log_radii=(2,-1))
|
|
3098
|
+
sage: f = x^2 + y^2 + 6*x^3 + 3*y
|
|
3099
|
+
sage: f.residue()
|
|
3100
|
+
Traceback (most recent call last):
|
|
3101
|
+
...
|
|
3102
|
+
NotImplementedError: residues are only implemented for radius 1
|
|
3103
|
+
"""
|
|
3104
|
+
for r in self._parent.log_radii():
|
|
3105
|
+
if r != 0:
|
|
3106
|
+
raise NotImplementedError("residues are only implemented for radius 1")
|
|
3107
|
+
if n is None:
|
|
3108
|
+
Rn = self.base_ring().residue_field()
|
|
3109
|
+
else:
|
|
3110
|
+
try:
|
|
3111
|
+
Rn = self.base_ring().residue_ring(n)
|
|
3112
|
+
except (AttributeError, NotImplementedError):
|
|
3113
|
+
Rn = self.base_ring().change(field=False, type='fixed-mod', prec=n)
|
|
3114
|
+
poly = self._parent._polynomial_ring(self._poly)
|
|
3115
|
+
return poly.change_ring(Rn)
|
|
3116
|
+
|
|
3117
|
+
cdef _quo_rem_c(self, list divisors, bint quo, bint rem, bint integral):
|
|
3118
|
+
r"""
|
|
3119
|
+
Perform the division of this series by ``divisors``.
|
|
3120
|
+
|
|
3121
|
+
INPUT:
|
|
3122
|
+
|
|
3123
|
+
- ``divisors`` -- the list of divisors
|
|
3124
|
+
|
|
3125
|
+
- ``quo`` -- boolean; whether we should compute the quotients
|
|
3126
|
+
|
|
3127
|
+
- ``rem`` -- boolean; whether we should compute the remainder
|
|
3128
|
+
|
|
3129
|
+
TESTS::
|
|
3130
|
+
|
|
3131
|
+
sage: R = Zp(2, 5, print_mode='digits')
|
|
3132
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3133
|
+
sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2
|
|
3134
|
+
sage: g = x^2
|
|
3135
|
+
sage: q, r = f.quo_rem(g) # indirect doctest
|
|
3136
|
+
sage: q
|
|
3137
|
+
...00011*y
|
|
3138
|
+
sage: r
|
|
3139
|
+
...00001 + ...00010*x*y + ...00100*x*y^2 + O(2^5 * <x, y>)
|
|
3140
|
+
"""
|
|
3141
|
+
cdef dict coeffs = { }
|
|
3142
|
+
cdef TateAlgebraElement f
|
|
3143
|
+
cdef TateAlgebraTerm lt
|
|
3144
|
+
cdef list ltds = [ (<TateAlgebraElement>d)._terms_c()[0] for d in divisors ]
|
|
3145
|
+
cdef list quos = [ ]
|
|
3146
|
+
cdef list terms = self._terms_c()
|
|
3147
|
+
cdef int index = 0
|
|
3148
|
+
cdef bint in_rem
|
|
3149
|
+
|
|
3150
|
+
if quo:
|
|
3151
|
+
for d in divisors:
|
|
3152
|
+
f = self._new_c()
|
|
3153
|
+
f._poly = PolyDict({}, None)
|
|
3154
|
+
f._prec = d.precision_relative()
|
|
3155
|
+
quos.append(f)
|
|
3156
|
+
|
|
3157
|
+
f = self._new_c()
|
|
3158
|
+
f._poly = PolyDict(self._poly.__repn, None)
|
|
3159
|
+
f._prec = self._prec
|
|
3160
|
+
while len(terms) > index:
|
|
3161
|
+
lt = terms[index]
|
|
3162
|
+
if lt._valuation_c() >= f._prec:
|
|
3163
|
+
break
|
|
3164
|
+
in_rem = True
|
|
3165
|
+
if not lt._coeff.is_zero(): # is it a good idea?
|
|
3166
|
+
for i in range(len(divisors)):
|
|
3167
|
+
if (<TateAlgebraTerm>ltds[i])._divides_c(lt, integral=integral):
|
|
3168
|
+
factor = lt._floordiv_c(<TateAlgebraTerm>ltds[i])
|
|
3169
|
+
f = f - (<TateAlgebraElement>divisors[i])._term_mul_c(factor)
|
|
3170
|
+
terms = f._terms_c()
|
|
3171
|
+
index = 0
|
|
3172
|
+
if quo:
|
|
3173
|
+
quos[i] = (<TateAlgebraElement>quos[i]) + factor
|
|
3174
|
+
in_rem = False
|
|
3175
|
+
break
|
|
3176
|
+
if in_rem:
|
|
3177
|
+
if rem:
|
|
3178
|
+
if lt._exponent in coeffs:
|
|
3179
|
+
coeffs[lt._exponent] += lt._coeff
|
|
3180
|
+
else:
|
|
3181
|
+
coeffs[lt._exponent] = lt._coeff
|
|
3182
|
+
del f._poly.__repn[lt._exponent]
|
|
3183
|
+
index += 1
|
|
3184
|
+
if rem:
|
|
3185
|
+
f._poly += PolyDict(coeffs, None)
|
|
3186
|
+
f._terms = None
|
|
3187
|
+
return quos, f
|
|
3188
|
+
|
|
3189
|
+
cdef _quo_rem_check(self, divisors, bint quo, bint rem):
|
|
3190
|
+
"""
|
|
3191
|
+
Perform the division of this series by ``divisors``.
|
|
3192
|
+
|
|
3193
|
+
INPUT:
|
|
3194
|
+
|
|
3195
|
+
- ``divisors`` -- the list of divisors
|
|
3196
|
+
|
|
3197
|
+
- ``quo`` -- boolean; whether we should compute the quotients
|
|
3198
|
+
|
|
3199
|
+
- ``rem`` -- boolean; whether we should compute the remainder
|
|
3200
|
+
|
|
3201
|
+
TESTS::
|
|
3202
|
+
|
|
3203
|
+
sage: R = Zp(2, 10)
|
|
3204
|
+
sage: A.<u,v> = TateAlgebra(R)
|
|
3205
|
+
sage: Ao = A.integer_ring()
|
|
3206
|
+
|
|
3207
|
+
sage: f = Ao(u^2 + 2*v^2)
|
|
3208
|
+
sage: f.quo_rem(u) # indirect doctest
|
|
3209
|
+
((1 + O(2^10))*u, (2 + O(2^10))*v^2 + O(2^10 * <u, v>))
|
|
3210
|
+
|
|
3211
|
+
We check that coercion works::
|
|
3212
|
+
|
|
3213
|
+
sage: f % 2 # indirect doctest
|
|
3214
|
+
(1 + O(2^10))*u^2 + O(2^10 * <u, v>)
|
|
3215
|
+
sage: f % [2,u] # indirect doctest
|
|
3216
|
+
O(2^10 * <u, v>)
|
|
3217
|
+
|
|
3218
|
+
sage: # needs sage.libs.ntl
|
|
3219
|
+
sage: x = polygen(ZZ, 'x')
|
|
3220
|
+
sage: S.<pi> = R.extension(x^2 - 2)
|
|
3221
|
+
sage: f % (pi*u) # indirect doctest
|
|
3222
|
+
(pi^2 + O(pi^20))*v^2 + O(pi^20 * <u, v>)
|
|
3223
|
+
sage: (pi*f) // (pi*u) == f // u
|
|
3224
|
+
True
|
|
3225
|
+
|
|
3226
|
+
::
|
|
3227
|
+
|
|
3228
|
+
sage: s = Zp(3)(1)
|
|
3229
|
+
sage: f % s
|
|
3230
|
+
Traceback (most recent call last):
|
|
3231
|
+
...
|
|
3232
|
+
TypeError: cannot coerce all the elements to the same parent
|
|
3233
|
+
|
|
3234
|
+
sage: f % ZZ
|
|
3235
|
+
Traceback (most recent call last):
|
|
3236
|
+
...
|
|
3237
|
+
TypeError: cannot coerce all the elements to the same parent
|
|
3238
|
+
"""
|
|
3239
|
+
parent = self.parent()
|
|
3240
|
+
if self.precision_absolute() is Infinity:
|
|
3241
|
+
self = self.add_bigoh(self.valuation() + parent.precision_cap())
|
|
3242
|
+
if isinstance(divisors, (list, tuple)):
|
|
3243
|
+
onedivisor = False
|
|
3244
|
+
else:
|
|
3245
|
+
divisors = [divisors]
|
|
3246
|
+
onedivisor = True
|
|
3247
|
+
A = _pushout_family(divisors, self._parent)
|
|
3248
|
+
f = A(self)
|
|
3249
|
+
divisors = [A(d) for d in divisors]
|
|
3250
|
+
q, r = (<TateAlgebraElement>self)._quo_rem_c(divisors, quo, rem, False)
|
|
3251
|
+
if quo and onedivisor:
|
|
3252
|
+
q = q[0]
|
|
3253
|
+
if quo and rem:
|
|
3254
|
+
return q, r
|
|
3255
|
+
if quo:
|
|
3256
|
+
return q
|
|
3257
|
+
if rem:
|
|
3258
|
+
return r
|
|
3259
|
+
|
|
3260
|
+
def quo_rem(self, divisors):
|
|
3261
|
+
"""
|
|
3262
|
+
Return the quotient(s) and the remainder of the division of
|
|
3263
|
+
this series by ``divisors``.
|
|
3264
|
+
|
|
3265
|
+
INPUT:
|
|
3266
|
+
|
|
3267
|
+
- ``divisors`` -- a series, or a list of series
|
|
3268
|
+
|
|
3269
|
+
NOTE:
|
|
3270
|
+
|
|
3271
|
+
The condition on the remainder is that it has
|
|
3272
|
+
|
|
3273
|
+
- no term which is greater than the leading term of the
|
|
3274
|
+
numerator and
|
|
3275
|
+
|
|
3276
|
+
- no term which is divisible by the leading term of one
|
|
3277
|
+
divisor.
|
|
3278
|
+
|
|
3279
|
+
EXAMPLES::
|
|
3280
|
+
|
|
3281
|
+
sage: R = Zp(2, 5, print_mode='digits')
|
|
3282
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3283
|
+
sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2
|
|
3284
|
+
sage: g = x^2
|
|
3285
|
+
sage: q, r = f.quo_rem(g)
|
|
3286
|
+
sage: q
|
|
3287
|
+
...00011*y
|
|
3288
|
+
sage: r
|
|
3289
|
+
...00001 + ...00010*x*y + ...00100*x*y^2 + O(2^5 * <x, y>)
|
|
3290
|
+
sage: f == g*q + r
|
|
3291
|
+
True
|
|
3292
|
+
|
|
3293
|
+
We can also divide by a family of divisors::
|
|
3294
|
+
|
|
3295
|
+
sage: g0 = x^2
|
|
3296
|
+
sage: g1 = x*y + 2*x
|
|
3297
|
+
sage: q, r = f.quo_rem([g0, g1])
|
|
3298
|
+
sage: q
|
|
3299
|
+
[...00011*y, ...11010 + ...00100*y]
|
|
3300
|
+
sage: r
|
|
3301
|
+
...00001 + ...01100*x + O(2^5 * <x, y>)
|
|
3302
|
+
sage: f == g0*q[0] + g1*q[1] + r
|
|
3303
|
+
True
|
|
3304
|
+
"""
|
|
3305
|
+
return (<TateAlgebraElement>self)._quo_rem_check(divisors, True, True)
|
|
3306
|
+
|
|
3307
|
+
def __mod__(self, divisors):
|
|
3308
|
+
"""
|
|
3309
|
+
Return the remainder of the division of this series by
|
|
3310
|
+
``divisors``.
|
|
3311
|
+
|
|
3312
|
+
INPUT:
|
|
3313
|
+
|
|
3314
|
+
- ``divisors`` -- a series, or a list of series
|
|
3315
|
+
|
|
3316
|
+
EXAMPLES::
|
|
3317
|
+
|
|
3318
|
+
sage: R = Zp(2, 5, print_mode='digits')
|
|
3319
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3320
|
+
sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2
|
|
3321
|
+
sage: g = x^2
|
|
3322
|
+
sage: f % g
|
|
3323
|
+
...00001 + ...00010*x*y + ...00100*x*y^2 + O(2^5 * <x, y>)
|
|
3324
|
+
|
|
3325
|
+
We can also divide by a family of divisors::
|
|
3326
|
+
|
|
3327
|
+
sage: g0 = x^2
|
|
3328
|
+
sage: g1 = x*y + 2*x
|
|
3329
|
+
sage: f % [g0, g1]
|
|
3330
|
+
...00001 + ...01100*x + O(2^5 * <x, y>)
|
|
3331
|
+
"""
|
|
3332
|
+
return (<TateAlgebraElement>self)._quo_rem_check(divisors, False, True)
|
|
3333
|
+
|
|
3334
|
+
def __floordiv__(self, divisors):
|
|
3335
|
+
"""
|
|
3336
|
+
Return the quotient(s) of the division of this series by
|
|
3337
|
+
``divisors``.
|
|
3338
|
+
|
|
3339
|
+
INPUT:
|
|
3340
|
+
|
|
3341
|
+
- ``divisors`` -- a series, or a list of series
|
|
3342
|
+
|
|
3343
|
+
EXAMPLES::
|
|
3344
|
+
|
|
3345
|
+
sage: R = Zp(2, 5, print_mode='digits')
|
|
3346
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3347
|
+
sage: f = 1 + 2*x*y + 3*x^2*y + 4*x*y^2
|
|
3348
|
+
sage: g = x^2
|
|
3349
|
+
sage: f // g
|
|
3350
|
+
...00011*y
|
|
3351
|
+
|
|
3352
|
+
We can also divide by a family of divisors::
|
|
3353
|
+
|
|
3354
|
+
sage: g0 = x^2
|
|
3355
|
+
sage: g1 = x*y + 2*x
|
|
3356
|
+
sage: f // [g0, g1]
|
|
3357
|
+
[...00011*y, ...11010 + ...00100*y]
|
|
3358
|
+
"""
|
|
3359
|
+
return (<TateAlgebraElement>self)._quo_rem_check(divisors, True, False)
|
|
3360
|
+
|
|
3361
|
+
def reduce(self, I):
|
|
3362
|
+
"""
|
|
3363
|
+
Return a canonical representative of this series in the
|
|
3364
|
+
quotient of the Tate algebra (in which this series lives)
|
|
3365
|
+
by the ideal ``I``.
|
|
3366
|
+
|
|
3367
|
+
EXAMPLES::
|
|
3368
|
+
|
|
3369
|
+
sage: R = Zp(3, prec=10, print_mode='digits')
|
|
3370
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3371
|
+
sage: f = 3*x^2 + 5*x*y^2
|
|
3372
|
+
sage: g = 5*x^2*y + 3
|
|
3373
|
+
sage: I = A.ideal([f, g])
|
|
3374
|
+
|
|
3375
|
+
sage: f.reduce(I)
|
|
3376
|
+
O(3^9 * <x, y>)
|
|
3377
|
+
sage: h = (x^2 + 2*y)*f + (x^2*y^3 + 3*x*y^2 + 7)*g + 1
|
|
3378
|
+
sage: h.reduce(I)
|
|
3379
|
+
...000000001 + O(3^9 * <x, y>)
|
|
3380
|
+
|
|
3381
|
+
TESTS::
|
|
3382
|
+
|
|
3383
|
+
sage: s = I.random_element(integral=True)
|
|
3384
|
+
sage: s.reduce(I).precision_absolute() >= 9
|
|
3385
|
+
True
|
|
3386
|
+
|
|
3387
|
+
sage: h = A.random_element()
|
|
3388
|
+
sage: (h + s).reduce(I) == h.reduce(I)
|
|
3389
|
+
True
|
|
3390
|
+
"""
|
|
3391
|
+
return self % I.groebner_basis()
|
|
3392
|
+
|
|
3393
|
+
@coerce_binop
|
|
3394
|
+
def Spoly(self, other):
|
|
3395
|
+
"""
|
|
3396
|
+
Return the S-polynomial of this series and ``other``.
|
|
3397
|
+
|
|
3398
|
+
INPUT:
|
|
3399
|
+
|
|
3400
|
+
- ``other`` -- a Tate series
|
|
3401
|
+
|
|
3402
|
+
NOTE:
|
|
3403
|
+
|
|
3404
|
+
If `f` and `g` are two Tate series with leading term
|
|
3405
|
+
`t_f` and `t_g` respectively, the S-polynomial of `f`
|
|
3406
|
+
and `g` is defined by
|
|
3407
|
+
|
|
3408
|
+
.. MATH::
|
|
3409
|
+
|
|
3410
|
+
S(f,g) = \frac{\text{lcm}(t_f,t_g)}{t_f}} f - \frac{\text{lcm}(t_f,t_g)}{t_g}} g
|
|
3411
|
+
|
|
3412
|
+
By construction the terms in `\text{lcm}(t_f,t_g)` cancel,
|
|
3413
|
+
so that the leading term of `S(f,g)` is strictly smaller
|
|
3414
|
+
than `\text{lcm}(t_f,t_g)`.
|
|
3415
|
+
|
|
3416
|
+
EXAMPLES::
|
|
3417
|
+
|
|
3418
|
+
sage: R = Zp(2, 5, print_mode='digits')
|
|
3419
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3420
|
+
sage: f = x^3*y + 2*x*y + 4*x^2
|
|
3421
|
+
sage: g = 2*x*y^2 + 2*x
|
|
3422
|
+
sage: h = f.Spoly(g); h
|
|
3423
|
+
...111110*x^3 + ...0000100*x*y^2 + ...00001000*x^2*y
|
|
3424
|
+
|
|
3425
|
+
sage: h == 2*y*f - x^2*g
|
|
3426
|
+
True
|
|
3427
|
+
|
|
3428
|
+
TESTS::
|
|
3429
|
+
|
|
3430
|
+
sage: f.Spoly(0)
|
|
3431
|
+
Traceback (most recent call last):
|
|
3432
|
+
...
|
|
3433
|
+
ValueError: the S-polynomial of zero is not defined
|
|
3434
|
+
"""
|
|
3435
|
+
try:
|
|
3436
|
+
return self._Spoly_c(other)
|
|
3437
|
+
except IndexError:
|
|
3438
|
+
raise ValueError("the S-polynomial of zero is not defined")
|
|
3439
|
+
|
|
3440
|
+
cdef TateAlgebraElement _Spoly_c(self, TateAlgebraElement other):
|
|
3441
|
+
"""
|
|
3442
|
+
Return the S-polynomial of this series and ``other``.
|
|
3443
|
+
|
|
3444
|
+
INPUT:
|
|
3445
|
+
|
|
3446
|
+
- ``other`` -- a Tate series
|
|
3447
|
+
|
|
3448
|
+
TESTS:
|
|
3449
|
+
|
|
3450
|
+
We check that the S-polynomial of two monomials vanishes::
|
|
3451
|
+
|
|
3452
|
+
sage: R = Zp(3, 5, print_mode='digits')
|
|
3453
|
+
sage: A.<x,y> = TateAlgebra(R)
|
|
3454
|
+
sage: f = x^3*y^2
|
|
3455
|
+
sage: g = x^2*y^3
|
|
3456
|
+
sage: f.Spoly(g)
|
|
3457
|
+
0
|
|
3458
|
+
"""
|
|
3459
|
+
cdef TateAlgebraTerm st = self._terms_c()[0]
|
|
3460
|
+
cdef TateAlgebraTerm ot = other._terms_c()[0]
|
|
3461
|
+
cdef TateAlgebraTerm t = st._lcm_c(ot)
|
|
3462
|
+
cdef TateAlgebraElement ans = self._term_mul_c(t._floordiv_c(st)) - other._term_mul_c(t._floordiv_c(ot))
|
|
3463
|
+
ans._poly.__repn.pop(t._exponent, None)
|
|
3464
|
+
return ans
|