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,917 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
r"""
|
|
3
|
+
Witt vectors
|
|
4
|
+
|
|
5
|
+
Implementation of the class :class:`WittVector` of truncated Witt vectors.
|
|
6
|
+
|
|
7
|
+
AUTHORS:
|
|
8
|
+
|
|
9
|
+
- Jacob Dennerlein (2022-11-28): initial version
|
|
10
|
+
- Rubén Muñoz-\-Bertrand (2025-02-13): major refactoring and clean-up
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# ****************************************************************************
|
|
14
|
+
# Copyright (C) 2025 Rubén Muñoz--Bertrand
|
|
15
|
+
# <ruben.munoz--bertrand@univ-fcomte.fr>
|
|
16
|
+
#
|
|
17
|
+
# This program is free software: you can redistribute it and/or modify
|
|
18
|
+
# it under the terms of the GNU General Public License as published by
|
|
19
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
20
|
+
# (at your option) any later version.
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# ****************************************************************************
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
from sage.misc.functional import log
|
|
26
|
+
from sage.misc.latex import tuple_function
|
|
27
|
+
from sage.misc.lazy_import import lazy_import
|
|
28
|
+
from sage.rings.integer import Integer
|
|
29
|
+
from sage.rings.padics.factory import QqFP, Zp
|
|
30
|
+
from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base
|
|
31
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
32
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
33
|
+
from sage.structure.element import CommutativeRingElement
|
|
34
|
+
from sage.structure.richcmp import op_EQ, op_NE
|
|
35
|
+
|
|
36
|
+
lazy_import('sage.modules.free_module_element', 'vector')
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class WittVector(CommutativeRingElement):
|
|
40
|
+
"""
|
|
41
|
+
Base class for truncated Witt vectors.
|
|
42
|
+
|
|
43
|
+
EXAMPLES::
|
|
44
|
+
|
|
45
|
+
sage: W = WittVectorRing(GF(25), p=5, prec=3)
|
|
46
|
+
sage: W(12)
|
|
47
|
+
(2, 1, 3)
|
|
48
|
+
|
|
49
|
+
sage: W = WittVectorRing(Integers(6), p=3, prec=4)
|
|
50
|
+
sage: w = W([1,2,3,4]) * W([4,5,0,0])
|
|
51
|
+
sage: w
|
|
52
|
+
(4, 1, 3, 4)
|
|
53
|
+
|
|
54
|
+
sage: TestSuite(w).run()
|
|
55
|
+
"""
|
|
56
|
+
def __init__(self, parent, vec=None):
|
|
57
|
+
"""
|
|
58
|
+
Common class for all kinds of Witt vectors.
|
|
59
|
+
|
|
60
|
+
EXAMPLES::
|
|
61
|
+
|
|
62
|
+
sage: W = WittVectorRing(GF(3))
|
|
63
|
+
sage: e = W.one(); e
|
|
64
|
+
(1)
|
|
65
|
+
sage: e^2
|
|
66
|
+
(1)
|
|
67
|
+
sage: -e
|
|
68
|
+
(2)
|
|
69
|
+
|
|
70
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
71
|
+
sage: t = W([1,2,0,1])
|
|
72
|
+
sage: t^2
|
|
73
|
+
(1, 1, 0, 2)
|
|
74
|
+
sage: -t
|
|
75
|
+
(2, 1, 0, 2)
|
|
76
|
+
sage: 1/t
|
|
77
|
+
(1, 1, 1, 0)
|
|
78
|
+
|
|
79
|
+
sage: W = WittVectorRing(ZZ, p=5, prec=2)
|
|
80
|
+
sage: WW = WittVectorRing(ZZ, p=5, prec=2)
|
|
81
|
+
sage: W((4,10)) * WW((-5,12,1))
|
|
82
|
+
(-20, -18362)
|
|
83
|
+
sage: WW((1,2,3)) + W((1,2))
|
|
84
|
+
(2, -2)
|
|
85
|
+
"""
|
|
86
|
+
self._prec = parent.precision()
|
|
87
|
+
B = parent.coefficient_ring()
|
|
88
|
+
if vec is not None:
|
|
89
|
+
if isinstance(vec, int) or isinstance(vec, Integer):
|
|
90
|
+
self._int_to_vector(vec, parent)
|
|
91
|
+
elif (isinstance(vec, tuple) or isinstance(vec, list)
|
|
92
|
+
or isinstance(vec, WittVector)):
|
|
93
|
+
if len(vec) < self._prec:
|
|
94
|
+
raise ValueError(f"{vec} has not the correct length, "
|
|
95
|
+
"expected length has to be at least "
|
|
96
|
+
f"{self._prec}")
|
|
97
|
+
self._coordinates = tuple(B(vec[i]) for i in range(self._prec))
|
|
98
|
+
else:
|
|
99
|
+
raise ValueError(f"{vec} cannot be interpreted as a Witt "
|
|
100
|
+
"vector")
|
|
101
|
+
else:
|
|
102
|
+
self._coordinates = (B(0) for i in range(self._prec))
|
|
103
|
+
CommutativeRingElement.__init__(self, parent)
|
|
104
|
+
|
|
105
|
+
def __getitem__(self, i):
|
|
106
|
+
"""
|
|
107
|
+
Return the ``i``-th coordinate of ``self``.
|
|
108
|
+
|
|
109
|
+
EXAMPLES::
|
|
110
|
+
|
|
111
|
+
sage: W = WittVectorRing(ZZ, p=2, prec=4)
|
|
112
|
+
sage: t = W([-1,2,-4,8])
|
|
113
|
+
sage: t[2]
|
|
114
|
+
-4
|
|
115
|
+
"""
|
|
116
|
+
if i < 0 or i >= self._prec:
|
|
117
|
+
raise IndexError("index out of the truncated Witt vector range")
|
|
118
|
+
return self._coordinates[i]
|
|
119
|
+
|
|
120
|
+
def __hash__(self) -> int:
|
|
121
|
+
"""
|
|
122
|
+
Return the hash of ``self``.
|
|
123
|
+
|
|
124
|
+
EXAMPLES::
|
|
125
|
+
|
|
126
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
127
|
+
sage: t = W([1,2,0,1])
|
|
128
|
+
sage: hash(t) # random
|
|
129
|
+
-2438844084280889141
|
|
130
|
+
"""
|
|
131
|
+
return hash(self._coordinates)
|
|
132
|
+
|
|
133
|
+
def __invert__(self):
|
|
134
|
+
"""
|
|
135
|
+
Return the inverse of ``self``.
|
|
136
|
+
|
|
137
|
+
EXAMPLES::
|
|
138
|
+
|
|
139
|
+
sage: # needs sage.symbolic
|
|
140
|
+
sage: W = WittVectorRing(GF(3), prec=3)
|
|
141
|
+
sage: w = W([1,1,1])
|
|
142
|
+
sage: ~w
|
|
143
|
+
(1, 2, 0)
|
|
144
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
145
|
+
sage: w = W([1,2,0,1])
|
|
146
|
+
sage: ~w
|
|
147
|
+
(1, 1, 1, 0)
|
|
148
|
+
sage: W = WittVectorRing(QQ, p=3, prec=4)
|
|
149
|
+
sage: w = W([1,1,1,1])
|
|
150
|
+
sage: ~w
|
|
151
|
+
(1, -1/4, -81/832, -12887559/359956480)
|
|
152
|
+
"""
|
|
153
|
+
if not self[0].is_unit():
|
|
154
|
+
raise ZeroDivisionError(f"inverse of {self} does not exist")
|
|
155
|
+
P = self.parent()
|
|
156
|
+
|
|
157
|
+
if self == P.one():
|
|
158
|
+
return self
|
|
159
|
+
if self._prec == 1:
|
|
160
|
+
return P((self[0]**-1,))
|
|
161
|
+
|
|
162
|
+
if P.coefficient_ring().characteristic() == P.prime():
|
|
163
|
+
res = P([self[0]**-1]
|
|
164
|
+
+ [P.coefficient_ring().zero()
|
|
165
|
+
for _ in range(self._prec - 1)])
|
|
166
|
+
|
|
167
|
+
for _ in range(log(self._prec, 2).n().ceil()):
|
|
168
|
+
res = 2*res - self*res*res
|
|
169
|
+
|
|
170
|
+
return res
|
|
171
|
+
|
|
172
|
+
# Strategy: Multiply ``self`` by an unknown Witt vector, set equal
|
|
173
|
+
# to (1, 0, 0, ...), and solve.
|
|
174
|
+
poly_ring = PolynomialRing(P.coefficient_ring(), 'x')
|
|
175
|
+
x = poly_ring.gen()
|
|
176
|
+
inv_vec = ([self[0]**-1]
|
|
177
|
+
+ [poly_ring.zero() for _ in range(self._prec - 1)])
|
|
178
|
+
# We'll fill this in one-by-one
|
|
179
|
+
|
|
180
|
+
from sage.rings.padics.witt_vector_ring import WittVectorRing
|
|
181
|
+
W = WittVectorRing(poly_ring, p=P.prime(), prec=self._prec)
|
|
182
|
+
for i in range(1, self._prec):
|
|
183
|
+
inv_vec[i] = x
|
|
184
|
+
prod_vec = (W(self._coordinates) * W(inv_vec)).coordinates()
|
|
185
|
+
poly = prod_vec[i]
|
|
186
|
+
try:
|
|
187
|
+
inv_vec[i] = (-poly.constant_coefficient()
|
|
188
|
+
/ poly.monomial_coefficient(x))
|
|
189
|
+
except ZeroDivisionError:
|
|
190
|
+
raise ZeroDivisionError(f"inverse of {self} does not exist")
|
|
191
|
+
try:
|
|
192
|
+
inv_vec[i] = P.coefficient_ring()(inv_vec[i])
|
|
193
|
+
except ValueError:
|
|
194
|
+
raise ZeroDivisionError(f"inverse of {self} does not exist")
|
|
195
|
+
|
|
196
|
+
return P(inv_vec)
|
|
197
|
+
|
|
198
|
+
def __len__(self):
|
|
199
|
+
"""
|
|
200
|
+
Return the length of ``self``.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: W = WittVectorRing(QQ, p=11, prec=100)
|
|
205
|
+
sage: t = W.zero()
|
|
206
|
+
sage: len(t)
|
|
207
|
+
100
|
|
208
|
+
"""
|
|
209
|
+
return self._prec
|
|
210
|
+
|
|
211
|
+
def _div_(self, other):
|
|
212
|
+
"""
|
|
213
|
+
Return the quotient of ``self`` and ``other``.
|
|
214
|
+
|
|
215
|
+
EXAMPLES::
|
|
216
|
+
|
|
217
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
218
|
+
sage: t = W([1,2,0,1])
|
|
219
|
+
sage: u = 1/t + 1
|
|
220
|
+
sage: u / t
|
|
221
|
+
(2, 1, 2, 1)
|
|
222
|
+
"""
|
|
223
|
+
P = self.parent()
|
|
224
|
+
# As a slight optimization, we'll check for one ahead of time.
|
|
225
|
+
if other == P.one():
|
|
226
|
+
return self
|
|
227
|
+
elif self == P.one():
|
|
228
|
+
return ~other
|
|
229
|
+
|
|
230
|
+
return self * ~other
|
|
231
|
+
|
|
232
|
+
def _int_to_vector(self, k, parent):
|
|
233
|
+
"""
|
|
234
|
+
Return the image of ``k`` in ``self`` with coefficients in ``parent``.
|
|
235
|
+
|
|
236
|
+
EXAMPLES::
|
|
237
|
+
|
|
238
|
+
sage: W = WittVectorRing(ZZ, p=23, prec=2)
|
|
239
|
+
sage: W(-123) # indirect doctest
|
|
240
|
+
(-123, 50826444131062300759362981690761165250849615528)
|
|
241
|
+
"""
|
|
242
|
+
p = parent.prime()
|
|
243
|
+
R = parent.coefficient_ring()
|
|
244
|
+
|
|
245
|
+
if p == R.characteristic():
|
|
246
|
+
if k == 0:
|
|
247
|
+
self._coordinates = tuple(R.zero() for i in range(self._prec))
|
|
248
|
+
else:
|
|
249
|
+
Z = Zp(p, prec=self._prec, type='fixed-mod')
|
|
250
|
+
self._coordinates = tuple(R(
|
|
251
|
+
Z(k).teichmuller_expansion(i).residue().polynomial())
|
|
252
|
+
** (p**i)
|
|
253
|
+
for i in range(self._prec))
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
should_negate = False
|
|
257
|
+
if k < 0:
|
|
258
|
+
k = -k
|
|
259
|
+
should_negate = True
|
|
260
|
+
|
|
261
|
+
vec_k = [k]
|
|
262
|
+
for n in range(1, self._prec):
|
|
263
|
+
total = (
|
|
264
|
+
k - k**(p**n)
|
|
265
|
+
- sum(p**(n-i) * vec_k[n-i]**(p**i) for i in range(1, n))
|
|
266
|
+
)
|
|
267
|
+
total //= p**n
|
|
268
|
+
vec_k.append(total)
|
|
269
|
+
|
|
270
|
+
if should_negate:
|
|
271
|
+
if p == 2:
|
|
272
|
+
vec_k = (
|
|
273
|
+
parent(vec_k)
|
|
274
|
+
* parent((tuple(-1 for _ in range(self._prec))))
|
|
275
|
+
).coordinates()
|
|
276
|
+
else:
|
|
277
|
+
vec_k = (-x for x in vec_k)
|
|
278
|
+
|
|
279
|
+
self._coordinates = tuple([R(x) for x in vec_k])
|
|
280
|
+
|
|
281
|
+
def _latex_(self):
|
|
282
|
+
r"""
|
|
283
|
+
Return a `\LaTeX` representation of ``self``.
|
|
284
|
+
|
|
285
|
+
EXAMPLES::
|
|
286
|
+
|
|
287
|
+
sage: W = WittVectorRing(ZZ, p=7, prec=3)
|
|
288
|
+
sage: t = W([6,1,6])
|
|
289
|
+
sage: latex(t)
|
|
290
|
+
\left(6, 1, 6\right)
|
|
291
|
+
"""
|
|
292
|
+
return tuple_function(self._coordinates)
|
|
293
|
+
|
|
294
|
+
def _neg_(self):
|
|
295
|
+
"""
|
|
296
|
+
Return the opposite of ``self``.
|
|
297
|
+
|
|
298
|
+
EXAMPLES::
|
|
299
|
+
|
|
300
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
301
|
+
sage: t = W([1,2,0,1])
|
|
302
|
+
sage: -t
|
|
303
|
+
(2, 1, 0, 2)
|
|
304
|
+
"""
|
|
305
|
+
P = self.parent()
|
|
306
|
+
# If p == 2, -1 == (-1, -1, -1, ...)
|
|
307
|
+
# Otherwise, -1 == (-1, 0, 0, ...)
|
|
308
|
+
if P.prime() == 2:
|
|
309
|
+
all_ones = P(tuple(-1 for _ in range(self._prec)))
|
|
310
|
+
return all_ones * self
|
|
311
|
+
neg_vec = tuple(-self[i] for i in range(self._prec))
|
|
312
|
+
return P(neg_vec)
|
|
313
|
+
|
|
314
|
+
def _repr_(self) -> str:
|
|
315
|
+
"""
|
|
316
|
+
Return a string representation.
|
|
317
|
+
|
|
318
|
+
EXAMPLES::
|
|
319
|
+
|
|
320
|
+
sage: W = WittVectorRing(ZZ, p=3, prec=4)
|
|
321
|
+
sage: t = W([1,2,0,1]); t
|
|
322
|
+
(1, 2, 0, 1)
|
|
323
|
+
"""
|
|
324
|
+
return '(' + ', '.join(map(str, self._coordinates)) + ')'
|
|
325
|
+
|
|
326
|
+
def _richcmp_(self, other, op) -> bool:
|
|
327
|
+
"""
|
|
328
|
+
Compare ``self`` and ``other``.
|
|
329
|
+
|
|
330
|
+
EXAMPLES::
|
|
331
|
+
|
|
332
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
333
|
+
sage: t = W([1,2,0,1])
|
|
334
|
+
sage: u = 1/t
|
|
335
|
+
sage: u == t
|
|
336
|
+
False
|
|
337
|
+
sage: t != t
|
|
338
|
+
False
|
|
339
|
+
"""
|
|
340
|
+
if not isinstance(other, WittVector):
|
|
341
|
+
return NotImplemented
|
|
342
|
+
if op == op_EQ:
|
|
343
|
+
return self._coordinates == other.coordinates()
|
|
344
|
+
if op == op_NE:
|
|
345
|
+
return self._coordinates != other.coordinates()
|
|
346
|
+
return NotImplemented
|
|
347
|
+
|
|
348
|
+
def _vector_(self, R=None):
|
|
349
|
+
"""
|
|
350
|
+
Return the underlying vector from ``self``.
|
|
351
|
+
|
|
352
|
+
INPUT:
|
|
353
|
+
|
|
354
|
+
- ``R`` -- the base ring (default: ``None``) of the returned vector,
|
|
355
|
+
when no ring is given the coefficient ring of ``self`` is used.
|
|
356
|
+
|
|
357
|
+
EXAMPLES::
|
|
358
|
+
|
|
359
|
+
sage: W = WittVectorRing(QQ, p=29, prec=3)
|
|
360
|
+
sage: t = W([-10,50,2/5])
|
|
361
|
+
sage: vector(t)
|
|
362
|
+
(-10, 50, 2/5)
|
|
363
|
+
sage: vector(GF(3), t)
|
|
364
|
+
(2, 2, 1)
|
|
365
|
+
"""
|
|
366
|
+
if R is None:
|
|
367
|
+
return vector(self._coordinates)
|
|
368
|
+
return vector(R, self._coordinates)
|
|
369
|
+
|
|
370
|
+
def coordinates(self):
|
|
371
|
+
"""
|
|
372
|
+
Return the underlying tuple of the truncated Witt vector.
|
|
373
|
+
|
|
374
|
+
EXAMPLES::
|
|
375
|
+
|
|
376
|
+
sage: W = WittVectorRing(GF(7), p=7, prec=3)
|
|
377
|
+
sage: v = W([1,2,3])
|
|
378
|
+
sage: v.coordinates()
|
|
379
|
+
(1, 2, 3)
|
|
380
|
+
"""
|
|
381
|
+
return self._coordinates
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
class WittVector_phantom(WittVector):
|
|
385
|
+
r"""
|
|
386
|
+
Child class for truncated Witt vectors using the ``phantom``
|
|
387
|
+
algorithm.
|
|
388
|
+
|
|
389
|
+
Here, a Witt vector with coefficients in `\mathbb F_q` (respectively in a
|
|
390
|
+
polynomial ring over that field), is lifted to another Witt vector with
|
|
391
|
+
coefficients in `\mathbb Q_q` (respectively in the corresponding
|
|
392
|
+
polynomial ring with coefficients in that field), whose phantom components
|
|
393
|
+
are stored. Computations are done with these phantom components, and the
|
|
394
|
+
corresponding Witt vectors in `\mathbb F_q` (respectively in the
|
|
395
|
+
polynomial ring) are computed from them only when needed.
|
|
396
|
+
|
|
397
|
+
EXAMPLES::
|
|
398
|
+
|
|
399
|
+
sage: W = WittVectorRing(GF(7), prec=5)
|
|
400
|
+
sage: t = W.one()
|
|
401
|
+
sage: t
|
|
402
|
+
(1, 0, 0, 0, 0)
|
|
403
|
+
sage: t.phantom()
|
|
404
|
+
(1, 1, 1, 1, 1)
|
|
405
|
+
sage: u = 7*t
|
|
406
|
+
sage: u.phantom(lift=True)
|
|
407
|
+
(7, 7, 7, 7, 7)
|
|
408
|
+
sage: u[1]
|
|
409
|
+
1
|
|
410
|
+
"""
|
|
411
|
+
def __init__(self, parent, vec=None, phantom=None):
|
|
412
|
+
"""
|
|
413
|
+
Initialises ``self`` from the data.
|
|
414
|
+
|
|
415
|
+
EXAMPLES::
|
|
416
|
+
|
|
417
|
+
sage: W = WittVectorRing(GF(7), prec=3)
|
|
418
|
+
sage: e = W.one(); e
|
|
419
|
+
(1, 0, 0)
|
|
420
|
+
sage: 7*e
|
|
421
|
+
(0, 1, 0)
|
|
422
|
+
"""
|
|
423
|
+
self._prec = parent.precision()
|
|
424
|
+
R = parent.coefficient_ring()
|
|
425
|
+
p = parent.prime()
|
|
426
|
+
base = R
|
|
427
|
+
if (isinstance(R, PolynomialRing_generic)
|
|
428
|
+
or isinstance(R, MPolynomialRing_base)):
|
|
429
|
+
base = R.base()
|
|
430
|
+
base_lift = QqFP(base.cardinality(), prec=self._prec,
|
|
431
|
+
modulus=base.modulus(), names=(base.variable_name(),),
|
|
432
|
+
res_name=base.variable_name())
|
|
433
|
+
lift = base_lift
|
|
434
|
+
if (isinstance(R, PolynomialRing_generic)
|
|
435
|
+
or isinstance(R, MPolynomialRing_base)):
|
|
436
|
+
lift = R.change_ring(base_lift)
|
|
437
|
+
if phantom is not None:
|
|
438
|
+
self._phantom = phantom
|
|
439
|
+
self._coordinates = (R(phantom[0]),)
|
|
440
|
+
self._powers = [phantom[0]]
|
|
441
|
+
elif vec is None:
|
|
442
|
+
zero = R.zero()
|
|
443
|
+
self._coordinates = (zero for i in range(self._prec))
|
|
444
|
+
self._phantom = self._prec * [zero]
|
|
445
|
+
elif isinstance(vec, WittVector_phantom):
|
|
446
|
+
self._coordinates = vec.coordinates()
|
|
447
|
+
self._phantom = vec._phantom
|
|
448
|
+
self._powers = vec._powers
|
|
449
|
+
elif isinstance(vec, int) or isinstance(vec, Integer):
|
|
450
|
+
self._int_to_vector(vec, parent)
|
|
451
|
+
y = base_lift(vec)
|
|
452
|
+
self._powers = [y]
|
|
453
|
+
self._phantom = self._prec * [y]
|
|
454
|
+
elif (isinstance(vec, tuple) or isinstance(vec, list)
|
|
455
|
+
or isinstance(vec, WittVector)):
|
|
456
|
+
if len(vec) < self._prec:
|
|
457
|
+
raise ValueError(f"{vec} has not the correct length, "
|
|
458
|
+
"expected length has to be at least "
|
|
459
|
+
f"{self._prec}")
|
|
460
|
+
# We compute the phantom components
|
|
461
|
+
self._coordinates = tuple(R(vec[i]) for i in range(self._prec))
|
|
462
|
+
x = [lift(v) for v in self._coordinates]
|
|
463
|
+
self._phantom = [x[0]]
|
|
464
|
+
for n in range(1, self._prec):
|
|
465
|
+
for i in range(n):
|
|
466
|
+
x[i] = x[i] ** p
|
|
467
|
+
self._phantom.append(sum(x[i] * p**i for i in range(n+1)))
|
|
468
|
+
self._powers = None
|
|
469
|
+
else:
|
|
470
|
+
raise ValueError(f"{vec} cannot be interpreted as a Witt vector")
|
|
471
|
+
CommutativeRingElement.__init__(self, parent)
|
|
472
|
+
|
|
473
|
+
def __getitem__(self, i):
|
|
474
|
+
"""
|
|
475
|
+
Return the ``i``-th coordinate of ``self``.
|
|
476
|
+
|
|
477
|
+
EXAMPLES::
|
|
478
|
+
|
|
479
|
+
sage: W = WittVectorRing(GF(13,'t'), prec=3)
|
|
480
|
+
sage: t = W([10,5,2])
|
|
481
|
+
sage: t[1]
|
|
482
|
+
5
|
|
483
|
+
"""
|
|
484
|
+
if i < 0 or i >= self._prec:
|
|
485
|
+
raise IndexError("index out of the truncated Witt vector range")
|
|
486
|
+
self._compute_vector(i+1)
|
|
487
|
+
return self._coordinates[i]
|
|
488
|
+
|
|
489
|
+
def _add_(self, other):
|
|
490
|
+
"""
|
|
491
|
+
Return the sum of the phantom components of the lift of ``self`` and
|
|
492
|
+
``other``.
|
|
493
|
+
|
|
494
|
+
EXAMPLES::
|
|
495
|
+
|
|
496
|
+
sage: W = WittVectorRing(GF(11,'t'), prec=3)
|
|
497
|
+
sage: t = W([6,1,6])
|
|
498
|
+
sage: u = W([0,5,0])
|
|
499
|
+
sage: r = t + u
|
|
500
|
+
sage: r.phantom(lift=True)
|
|
501
|
+
(6, 6 + 3*11 + 9*11^2, 6 + 3*11 + 3*11^2)
|
|
502
|
+
"""
|
|
503
|
+
phantom = [self._phantom[i] + other._phantom[i] for i in range(self._prec)]
|
|
504
|
+
return self.__class__(self.parent(), phantom=phantom)
|
|
505
|
+
|
|
506
|
+
def _compute_vector(self, prec=None):
|
|
507
|
+
"""
|
|
508
|
+
Computes the Witt vector ``self`` from the ghost components of its
|
|
509
|
+
lift.
|
|
510
|
+
|
|
511
|
+
INPUT:
|
|
512
|
+
|
|
513
|
+
- ``prec`` -- the precision (default: ``None``) up to which the vector
|
|
514
|
+
is computed. When no integer is given, the whole truncated Witt
|
|
515
|
+
vector is computed.
|
|
516
|
+
|
|
517
|
+
EXAMPLES::
|
|
518
|
+
|
|
519
|
+
sage: W = WittVectorRing(GF(17), prec=3)
|
|
520
|
+
sage: t = W(phantom=[1,1,290]); t # indirect doctest
|
|
521
|
+
(1, 0, 1)
|
|
522
|
+
"""
|
|
523
|
+
maxprec = self._prec
|
|
524
|
+
if prec is None:
|
|
525
|
+
prec = maxprec
|
|
526
|
+
else:
|
|
527
|
+
prec = min(prec, maxprec)
|
|
528
|
+
phantom = self._phantom
|
|
529
|
+
powers = self._powers
|
|
530
|
+
p = self.parent()._prime
|
|
531
|
+
mod = self.parent().coefficient_ring()
|
|
532
|
+
for n in range(len(self._coordinates), prec):
|
|
533
|
+
for i in range(n):
|
|
534
|
+
powers[i] = powers[i] ** p
|
|
535
|
+
c = (phantom[n] - sum(powers[i] * p**i for i in range(n))) // p**n
|
|
536
|
+
self._coordinates += (mod(c),)
|
|
537
|
+
self._powers.append(c)
|
|
538
|
+
|
|
539
|
+
def _latex_(self):
|
|
540
|
+
r"""
|
|
541
|
+
Return a `\LaTeX` representation of ``self``.
|
|
542
|
+
|
|
543
|
+
EXAMPLES::
|
|
544
|
+
|
|
545
|
+
sage: W = WittVectorRing(GF(2), prec=4)
|
|
546
|
+
sage: t = W(phantom=[1,1,1,9])
|
|
547
|
+
sage: latex(t)
|
|
548
|
+
\left(1, 0, 0, 1\right)
|
|
549
|
+
"""
|
|
550
|
+
self._compute_vector()
|
|
551
|
+
return super()._latex_()
|
|
552
|
+
|
|
553
|
+
def _mul_(self, other):
|
|
554
|
+
"""
|
|
555
|
+
Return the product of the phantom components of the lift of ``self``
|
|
556
|
+
and ``other``.
|
|
557
|
+
|
|
558
|
+
EXAMPLES::
|
|
559
|
+
|
|
560
|
+
sage: W = WittVectorRing(GF(7,'t'), prec=3)
|
|
561
|
+
sage: t = W([1,0,5])
|
|
562
|
+
sage: u = W([0,1,3])
|
|
563
|
+
sage: r = t * u
|
|
564
|
+
sage: r.phantom(lift=True)
|
|
565
|
+
(0, 7, 7 + 3*7^2 + 5*7^3)
|
|
566
|
+
"""
|
|
567
|
+
phantom = [self._phantom[i] * other._phantom[i] for i in range(self._prec)]
|
|
568
|
+
return self.__class__(self.parent(), phantom=phantom)
|
|
569
|
+
|
|
570
|
+
def _neg_(self):
|
|
571
|
+
"""
|
|
572
|
+
Return the opposite of the phantom component of the lift of ``self``.
|
|
573
|
+
|
|
574
|
+
EXAMPLES::
|
|
575
|
+
|
|
576
|
+
sage: W = WittVectorRing(GF(23,'t'), prec=4)
|
|
577
|
+
sage: t = W([1,0,1,17])
|
|
578
|
+
sage: r = -t
|
|
579
|
+
sage: r.phantom(lift=True)
|
|
580
|
+
(22 + 22*23 + 22*23^2 + 22*23^3, 22 + 22*23 + 22*23^2 + 22*23^3,
|
|
581
|
+
22 + 22*23 + 21*23^2 + 22*23^3, 22 + 22*23 + 21*23^2 + 5*23^3)
|
|
582
|
+
"""
|
|
583
|
+
phantom = [-v for v in self._phantom]
|
|
584
|
+
return self.__class__(self.parent(), phantom=phantom)
|
|
585
|
+
|
|
586
|
+
def _repr_(self):
|
|
587
|
+
"""
|
|
588
|
+
Return a string representation.
|
|
589
|
+
|
|
590
|
+
EXAMPLES::
|
|
591
|
+
|
|
592
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
593
|
+
sage: t = W([1,2,0,1]); t
|
|
594
|
+
(1, 2, 0, 1)
|
|
595
|
+
"""
|
|
596
|
+
self._compute_vector()
|
|
597
|
+
return super()._repr_()
|
|
598
|
+
|
|
599
|
+
def _richcmp_(self, other, op) -> bool:
|
|
600
|
+
"""
|
|
601
|
+
Compare ``self`` and ``other``.
|
|
602
|
+
|
|
603
|
+
EXAMPLES::
|
|
604
|
+
|
|
605
|
+
sage: W = WittVectorRing(GF(3), prec=4)
|
|
606
|
+
sage: t = W([1,2,0,1])
|
|
607
|
+
sage: u = 1/t
|
|
608
|
+
sage: u == t
|
|
609
|
+
False
|
|
610
|
+
sage: t != t
|
|
611
|
+
False
|
|
612
|
+
|
|
613
|
+
sage: W_standard = WittVectorRing(GF(3), prec=4, algorithm='standard')
|
|
614
|
+
sage: u + t == W_standard(u) + W_standard(t)
|
|
615
|
+
True
|
|
616
|
+
sage: W_finotti = WittVectorRing(GF(3), prec=4, algorithm='finotti')
|
|
617
|
+
sage: u * t == W_finotti(u) * W_standard(t)
|
|
618
|
+
True
|
|
619
|
+
"""
|
|
620
|
+
self._compute_vector()
|
|
621
|
+
return super()._richcmp_(other, op)
|
|
622
|
+
|
|
623
|
+
def _sub_(self, other):
|
|
624
|
+
"""
|
|
625
|
+
Return the difference of the phantom components of the lift of
|
|
626
|
+
``self`` and ``other``.
|
|
627
|
+
|
|
628
|
+
EXAMPLES::
|
|
629
|
+
|
|
630
|
+
sage: W = WittVectorRing(GF(3,'t'), prec=3)
|
|
631
|
+
sage: t = W([1,2,2])
|
|
632
|
+
sage: u = W([1,0,2])
|
|
633
|
+
sage: r = t - u
|
|
634
|
+
sage: r.phantom(lift=True)
|
|
635
|
+
(0, 2*3, 2*3 + 2*3^2)
|
|
636
|
+
"""
|
|
637
|
+
phantom = [self._phantom[i] - other._phantom[i] for i in range(self._prec)]
|
|
638
|
+
return self.__class__(self.parent(), phantom=phantom)
|
|
639
|
+
|
|
640
|
+
def _vector_(self, R):
|
|
641
|
+
"""
|
|
642
|
+
Return the underlying vector from ``self``.
|
|
643
|
+
|
|
644
|
+
EXAMPLES::
|
|
645
|
+
|
|
646
|
+
sage: W = WittVectorRing(GF(13), prec=2)
|
|
647
|
+
sage: t = W([1, 3])
|
|
648
|
+
sage: vector(t)
|
|
649
|
+
(1, 3)
|
|
650
|
+
"""
|
|
651
|
+
self._compute_vector()
|
|
652
|
+
return super()._vector_(R)
|
|
653
|
+
|
|
654
|
+
def coordinates(self):
|
|
655
|
+
"""
|
|
656
|
+
Return the underlying tuple of the truncated Witt vector.
|
|
657
|
+
|
|
658
|
+
EXAMPLES::
|
|
659
|
+
|
|
660
|
+
sage: W = WittVectorRing(GF(7), p=7, prec=3)
|
|
661
|
+
sage: v = W([1,2,3])
|
|
662
|
+
sage: v.coordinates()
|
|
663
|
+
(1, 2, 3)
|
|
664
|
+
"""
|
|
665
|
+
self._compute_vector()
|
|
666
|
+
|
|
667
|
+
return self._coordinates
|
|
668
|
+
|
|
669
|
+
def phantom(self, lift=False):
|
|
670
|
+
"""
|
|
671
|
+
Return the phantom components of the lift of ``self``.
|
|
672
|
+
|
|
673
|
+
INPUT:
|
|
674
|
+
|
|
675
|
+
- ``lift`` -- a Boolean (default: ``False``). When ``True``, return
|
|
676
|
+
the phantom components in the lift of the coefficient ring.
|
|
677
|
+
|
|
678
|
+
EXAMPLES::
|
|
679
|
+
|
|
680
|
+
sage: W = WittVectorRing(GF(5,'t'), prec=3)
|
|
681
|
+
sage: t = W([1,1,3])
|
|
682
|
+
sage: t.phantom()
|
|
683
|
+
(1, 1, 1)
|
|
684
|
+
sage: t.phantom(lift=True)
|
|
685
|
+
(1, 1 + 5, 1 + 5 + 3*5^2)
|
|
686
|
+
"""
|
|
687
|
+
if lift:
|
|
688
|
+
return tuple(self._phantom)
|
|
689
|
+
return tuple(self.parent().coefficient_ring()(x)
|
|
690
|
+
for x in self._phantom)
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
class WittVector_finotti(WittVector):
|
|
694
|
+
"""
|
|
695
|
+
Child class for truncated Witt vectors using Finotti's algorithm.
|
|
696
|
+
|
|
697
|
+
EXAMPLES::
|
|
698
|
+
|
|
699
|
+
sage: W = WittVectorRing(GF(7), prec=4, algorithm='finotti')
|
|
700
|
+
sage: 49*W.one()
|
|
701
|
+
(0, 0, 1, 0)
|
|
702
|
+
"""
|
|
703
|
+
def _add_(self, other):
|
|
704
|
+
"""
|
|
705
|
+
Return the sum of ``self`` and ``other``.
|
|
706
|
+
|
|
707
|
+
EXAMPLES::
|
|
708
|
+
|
|
709
|
+
sage: R.<x> = PolynomialRing(GF(7))
|
|
710
|
+
sage: W = WittVectorRing(R, prec=2, algorithm='finotti')
|
|
711
|
+
sage: t = W([x + 3, x + 2])
|
|
712
|
+
sage: u = W([6, x])
|
|
713
|
+
sage: t + u
|
|
714
|
+
(x + 2, x^6 + x^5 + 4*x^4 + 3*x^3 + 3*x^2 + 2*x + 2)
|
|
715
|
+
"""
|
|
716
|
+
P = self.parent()
|
|
717
|
+
|
|
718
|
+
# As a slight optimization, we'll check for zero ahead of time.
|
|
719
|
+
if other == P.zero():
|
|
720
|
+
return self
|
|
721
|
+
elif self == P.zero():
|
|
722
|
+
return other
|
|
723
|
+
|
|
724
|
+
G = []
|
|
725
|
+
for n in range(self._prec):
|
|
726
|
+
G_n = [self[n], other[n]]
|
|
727
|
+
for i in range(n):
|
|
728
|
+
G_n.append(P._eta_bar(G[i], n - i))
|
|
729
|
+
G.append(G_n)
|
|
730
|
+
sum_vec = tuple(sum(G[i]) for i in range(self._prec))
|
|
731
|
+
|
|
732
|
+
return P(sum_vec)
|
|
733
|
+
|
|
734
|
+
def _mul_(self, other):
|
|
735
|
+
"""
|
|
736
|
+
Return the product of ``self`` and ``other``.
|
|
737
|
+
|
|
738
|
+
EXAMPLES::
|
|
739
|
+
|
|
740
|
+
sage: R.<x> = PolynomialRing(GF(5))
|
|
741
|
+
sage: W = WittVectorRing(R, prec=3, algorithm='finotti')
|
|
742
|
+
sage: t = W([1, 2, 3])
|
|
743
|
+
sage: u = W([x, x^2, x^3])
|
|
744
|
+
sage: t * u
|
|
745
|
+
(x, 2*x^5 + x^2, 3*x^25 + 4*x^22 + 4*x^19 + 2*x^16 + 3*x^13 + 2*x^10 + x^3)
|
|
746
|
+
"""
|
|
747
|
+
P = self.parent()
|
|
748
|
+
|
|
749
|
+
# As a slight optimization, we'll check for zero or one ahead of time.
|
|
750
|
+
if self == P.zero() or other == P.zero():
|
|
751
|
+
return P.zero()
|
|
752
|
+
if other == P.one():
|
|
753
|
+
return self
|
|
754
|
+
if self == P.one():
|
|
755
|
+
return other
|
|
756
|
+
|
|
757
|
+
from sage.rings.padics.witt_vector_ring import fast_char_p_power
|
|
758
|
+
p = P.prime()
|
|
759
|
+
G = [[self[0] * other[0]]]
|
|
760
|
+
for n in range(1, self._prec):
|
|
761
|
+
G_n = [fast_char_p_power(self[0], p**n) * other[n],
|
|
762
|
+
fast_char_p_power(other[0], p**n) * self[n]]
|
|
763
|
+
G_n.extend(fast_char_p_power(self[i], p**(n - i))
|
|
764
|
+
* fast_char_p_power(other[n - i], p**i)
|
|
765
|
+
for i in range(1, n))
|
|
766
|
+
for i in range(n):
|
|
767
|
+
G_n.append(P._eta_bar(G[i], n - i))
|
|
768
|
+
G.append(G_n)
|
|
769
|
+
prod_vec = tuple(sum(G[i]) for i in range(self._prec))
|
|
770
|
+
|
|
771
|
+
return P(prod_vec)
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
class WittVector_pinvertible(WittVector):
|
|
775
|
+
"""
|
|
776
|
+
Child class for truncated Witt vectors using the ``p_invertible``
|
|
777
|
+
algorithm.
|
|
778
|
+
|
|
779
|
+
EXAMPLES::
|
|
780
|
+
|
|
781
|
+
sage: W = WittVectorRing(QQ, p=3, prec=3)
|
|
782
|
+
sage: t = W.random_element()
|
|
783
|
+
sage: t-t
|
|
784
|
+
(0, 0, 0)
|
|
785
|
+
"""
|
|
786
|
+
def _add_(self, other):
|
|
787
|
+
"""
|
|
788
|
+
Return the sum of ``self`` and ``other``.
|
|
789
|
+
|
|
790
|
+
EXAMPLES::
|
|
791
|
+
|
|
792
|
+
sage: W = WittVectorRing(QQ, p=11, prec=2)
|
|
793
|
+
sage: t = W([1/2,3/4])
|
|
794
|
+
sage: u = W([5/6,7/8])
|
|
795
|
+
sage: t + u
|
|
796
|
+
(4/3, -7787621/15116544)
|
|
797
|
+
"""
|
|
798
|
+
P = self.parent()
|
|
799
|
+
|
|
800
|
+
# As a slight optimization, we'll check for zero ahead of time.
|
|
801
|
+
if other == P.zero():
|
|
802
|
+
return self
|
|
803
|
+
elif self == P.zero():
|
|
804
|
+
return other
|
|
805
|
+
|
|
806
|
+
p = P.prime() # we know p is a unit in this case!
|
|
807
|
+
sum_vec = [self[0] + other[0]]
|
|
808
|
+
for n in range(1, self._prec):
|
|
809
|
+
next_sum = self[n] + other[n] + \
|
|
810
|
+
sum((self[i]**(p**(n - i)) + other[i]**(p**(n - i))
|
|
811
|
+
- sum_vec[i]**(p**(n - i)))
|
|
812
|
+
/ p**(n - i)
|
|
813
|
+
for i in range(n))
|
|
814
|
+
sum_vec.append(next_sum)
|
|
815
|
+
|
|
816
|
+
return P(sum_vec)
|
|
817
|
+
|
|
818
|
+
def _mul_(self, other):
|
|
819
|
+
"""
|
|
820
|
+
Return the product of ``self`` and ``other``.
|
|
821
|
+
|
|
822
|
+
EXAMPLES::
|
|
823
|
+
|
|
824
|
+
sage: W = WittVectorRing(QQ, p=3, prec=3)
|
|
825
|
+
sage: t = W([1/2,3/4,5/6])
|
|
826
|
+
sage: u = W([7/8,9/10,11/12])
|
|
827
|
+
sage: t * u
|
|
828
|
+
(7/16, 27033/10240, 5808213977/1342177280)
|
|
829
|
+
"""
|
|
830
|
+
P = self.parent()
|
|
831
|
+
|
|
832
|
+
# As a slight optimization, we'll check for zero or one ahead of time.
|
|
833
|
+
if self == P.zero() or other == P.zero():
|
|
834
|
+
return P.zero()
|
|
835
|
+
if other == P.one():
|
|
836
|
+
return self
|
|
837
|
+
if self == P.one():
|
|
838
|
+
return other
|
|
839
|
+
|
|
840
|
+
p = P.prime() # we know p is a unit in this case!
|
|
841
|
+
prod_vec = [self[0] * other[0]]
|
|
842
|
+
for n in range(1, self._prec):
|
|
843
|
+
next_prod = (
|
|
844
|
+
sum(p**i * self[i]**(p**(n - i)) for i in range(n + 1)) *
|
|
845
|
+
sum(p**i * other[i]**(p**(n - i)) for i in range(n + 1)) -
|
|
846
|
+
sum(p**i * prod_vec[i]**(p**(n - i)) for i in range(n))
|
|
847
|
+
) / p**n
|
|
848
|
+
prod_vec.append(next_prod)
|
|
849
|
+
|
|
850
|
+
return P(prod_vec)
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
class WittVector_standard(WittVector):
|
|
854
|
+
"""
|
|
855
|
+
Child class for truncated Witt vectors using the ``standard`` algorithm.
|
|
856
|
+
|
|
857
|
+
EXAMPLES::
|
|
858
|
+
|
|
859
|
+
sage: W = WittVectorRing(GF(5), prec=3, algorithm='standard')
|
|
860
|
+
sage: 5*W.one()
|
|
861
|
+
(0, 1, 0)
|
|
862
|
+
"""
|
|
863
|
+
def _add_(self, other):
|
|
864
|
+
"""
|
|
865
|
+
Return the sum of ``self`` and ``other``.
|
|
866
|
+
|
|
867
|
+
EXAMPLES::
|
|
868
|
+
|
|
869
|
+
sage: W = WittVectorRing(Integers(25), p=5, prec=3)
|
|
870
|
+
sage: t = W([1,2,3])
|
|
871
|
+
sage: u = W([4,5,6])
|
|
872
|
+
sage: t + u
|
|
873
|
+
(5, 12, 4)
|
|
874
|
+
"""
|
|
875
|
+
P = self.parent()
|
|
876
|
+
|
|
877
|
+
# As a slight optimization, we'll check for zero ahead of time.
|
|
878
|
+
if other == P.zero():
|
|
879
|
+
return self
|
|
880
|
+
elif self == P.zero():
|
|
881
|
+
return other
|
|
882
|
+
|
|
883
|
+
s = P.sum_polynomials()
|
|
884
|
+
# note here this is tuple addition, i.e. concatenation
|
|
885
|
+
sum_vec = tuple(s[i](*(self._coordinates + other.coordinates()))
|
|
886
|
+
for i in range(self._prec))
|
|
887
|
+
|
|
888
|
+
return P(sum_vec)
|
|
889
|
+
|
|
890
|
+
def _mul_(self, other):
|
|
891
|
+
"""
|
|
892
|
+
Return the product of ``self`` and ``other``.
|
|
893
|
+
|
|
894
|
+
EXAMPLES::
|
|
895
|
+
|
|
896
|
+
sage: W = WittVectorRing(Integers(13), p=2, prec=3)
|
|
897
|
+
sage: t = W([1,2,3])
|
|
898
|
+
sage: u = W([4,5,6])
|
|
899
|
+
sage: t * u
|
|
900
|
+
(4, 5, 5)
|
|
901
|
+
"""
|
|
902
|
+
P = self.parent()
|
|
903
|
+
|
|
904
|
+
# As a slight optimization, we'll check for zero or one ahead of time.
|
|
905
|
+
if self == P.zero() or other == P.zero():
|
|
906
|
+
return P.zero()
|
|
907
|
+
if other == P.one():
|
|
908
|
+
return self
|
|
909
|
+
if self == P.one():
|
|
910
|
+
return other
|
|
911
|
+
|
|
912
|
+
p = P.prod_polynomials()
|
|
913
|
+
# note here this is tuple addition, i.e. concatenation
|
|
914
|
+
prod_vec = tuple(p[i](*(self._coordinates + other.coordinates()))
|
|
915
|
+
for i in range(self._prec))
|
|
916
|
+
|
|
917
|
+
return P(prod_vec)
|