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,934 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
# sage.doctest: needs numpy sage.libs.singular
|
|
3
|
+
r"""
|
|
4
|
+
Witt vector rings
|
|
5
|
+
|
|
6
|
+
This module provides the class :class:`WittVectorRing` of rings of truncated
|
|
7
|
+
Witt vectors.
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- Jacob Dennerlein (2022-11-28): initial version
|
|
12
|
+
- Rubén Muñoz-\-Bertrand (2025-02-13): major refactoring and clean-up
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# ****************************************************************************
|
|
17
|
+
# Copyright (C) 2025 Rubén Muñoz--Bertrand
|
|
18
|
+
# <ruben.munoz--bertrand@univ-fcomte.fr>
|
|
19
|
+
#
|
|
20
|
+
# This program is free software: you can redistribute it and/or modify
|
|
21
|
+
# it under the terms of the GNU General Public License as published by
|
|
22
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
23
|
+
# (at your option) any later version.
|
|
24
|
+
# https://www.gnu.org/licenses/
|
|
25
|
+
# ****************************************************************************
|
|
26
|
+
from itertools import product
|
|
27
|
+
from typing import Iterator
|
|
28
|
+
|
|
29
|
+
from sage.categories.commutative_rings import CommutativeRings
|
|
30
|
+
from sage.categories.integral_domains import IntegralDomains
|
|
31
|
+
from sage.categories.fields import Fields
|
|
32
|
+
from sage.misc.latex import latex
|
|
33
|
+
from sage.rings.integer import Integer
|
|
34
|
+
from sage.rings.integer_ring import ZZ
|
|
35
|
+
from sage.rings.padics.factory import Zp
|
|
36
|
+
from sage.rings.padics.witt_vector import (
|
|
37
|
+
WittVector_finotti,
|
|
38
|
+
WittVector_phantom,
|
|
39
|
+
WittVector_pinvertible,
|
|
40
|
+
WittVector_standard,
|
|
41
|
+
)
|
|
42
|
+
from sage.rings.polynomial.multi_polynomial import MPolynomial
|
|
43
|
+
from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base
|
|
44
|
+
from sage.rings.polynomial.polynomial_element import Polynomial
|
|
45
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
46
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
47
|
+
from sage.structure.parent import Parent
|
|
48
|
+
from sage.sets.primes import Primes
|
|
49
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def fast_char_p_power(x, n, p=None):
|
|
53
|
+
r"""
|
|
54
|
+
Return `x^n` assuming that `x` lives in a ring of characteristic `p`.
|
|
55
|
+
|
|
56
|
+
If `x` is not an element of a ring of characteristic `p`,
|
|
57
|
+
this throws an error.
|
|
58
|
+
|
|
59
|
+
EXAMPLES::
|
|
60
|
+
|
|
61
|
+
sage: from sage.rings.padics.witt_vector_ring import fast_char_p_power
|
|
62
|
+
sage: t = GF(1913)(33)
|
|
63
|
+
sage: fast_char_p_power(t, 77)
|
|
64
|
+
1371
|
|
65
|
+
|
|
66
|
+
::
|
|
67
|
+
|
|
68
|
+
sage: K.<t> = GF(5^3)
|
|
69
|
+
sage: fast_char_p_power(t, 385)
|
|
70
|
+
4*t^2 + 1
|
|
71
|
+
sage: t^385
|
|
72
|
+
4*t^2 + 1
|
|
73
|
+
|
|
74
|
+
::
|
|
75
|
+
|
|
76
|
+
sage: A.<x> = K[]
|
|
77
|
+
sage: fast_char_p_power(x + 1, 10)
|
|
78
|
+
x^10 + 2*x^5 + 1
|
|
79
|
+
|
|
80
|
+
::
|
|
81
|
+
|
|
82
|
+
sage: B.<u,v> = K[]
|
|
83
|
+
sage: fast_char_p_power(u + v, 1250)
|
|
84
|
+
u^1250 + 2*u^625*v^625 + v^1250
|
|
85
|
+
"""
|
|
86
|
+
x_is_Polynomial = isinstance(x, Polynomial)
|
|
87
|
+
x_is_MPolynomial = isinstance(x, MPolynomial)
|
|
88
|
+
|
|
89
|
+
if not (x_is_Polynomial or x_is_MPolynomial):
|
|
90
|
+
return x**n
|
|
91
|
+
if x.is_gen():
|
|
92
|
+
return x**n
|
|
93
|
+
if n < 0:
|
|
94
|
+
x = ~x
|
|
95
|
+
n = -n
|
|
96
|
+
|
|
97
|
+
P = x.parent()
|
|
98
|
+
if p is None:
|
|
99
|
+
p = P.characteristic()
|
|
100
|
+
base_p_digits = ZZ(n).digits(base=p)
|
|
101
|
+
|
|
102
|
+
xn = 1
|
|
103
|
+
|
|
104
|
+
for p_exp, digit in enumerate(base_p_digits):
|
|
105
|
+
if digit == 0:
|
|
106
|
+
continue
|
|
107
|
+
inner_term = x**digit
|
|
108
|
+
term_dict = {}
|
|
109
|
+
for e_int_or_tuple, c in inner_term.dict().items():
|
|
110
|
+
power = p**p_exp
|
|
111
|
+
new_c = fast_char_p_power(c, power)
|
|
112
|
+
new_e_tuple = None
|
|
113
|
+
if x_is_Polynomial: # Then the dict keys are ints
|
|
114
|
+
new_e_tuple = e_int_or_tuple * power
|
|
115
|
+
elif x_is_MPolynomial: # Then the dict keys are ETuples
|
|
116
|
+
new_e_tuple = e_int_or_tuple.emul(power)
|
|
117
|
+
term_dict[new_e_tuple] = new_c
|
|
118
|
+
term = P(term_dict)
|
|
119
|
+
xn *= term
|
|
120
|
+
|
|
121
|
+
return xn
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class WittVectorRing(Parent, UniqueRepresentation):
|
|
125
|
+
r"""
|
|
126
|
+
Return the appropriate `p`-typical truncated Witt vector ring.
|
|
127
|
+
|
|
128
|
+
INPUT:
|
|
129
|
+
|
|
130
|
+
- ``coefficient_ring`` -- commutative ring of coefficients
|
|
131
|
+
|
|
132
|
+
- ``prec`` -- integer (default: `1`), length of the truncated Witt
|
|
133
|
+
vectors in the ring
|
|
134
|
+
|
|
135
|
+
- ``p`` -- a prime number (default: ``None``); when it is not set, it
|
|
136
|
+
defaults to the characteristic of ``coefficient_ring`` when it is prime.
|
|
137
|
+
|
|
138
|
+
- ``algorithm`` -- the name of the algorithm to use for the ring laws
|
|
139
|
+
(default: ``None``); when it is not set, the most adequate algorithm
|
|
140
|
+
is chosen
|
|
141
|
+
|
|
142
|
+
Available algorithms are:
|
|
143
|
+
|
|
144
|
+
- ``standard`` -- the schoolbook algorithm;
|
|
145
|
+
|
|
146
|
+
- ``finotti`` -- Finotti's algorithm; it can be used when the coefficient
|
|
147
|
+
ring has characteristic `p`;
|
|
148
|
+
|
|
149
|
+
- ``phantom`` -- computes the ring laws using the phantom components
|
|
150
|
+
using a lift of ``coefficient_ring``, assuming that it is either
|
|
151
|
+
`\mathbb F_q` for a power `q` of `p`, or a polynomial ring on that field;
|
|
152
|
+
|
|
153
|
+
- ``p_invertible`` -- uses some optimisations when `p` is invertible
|
|
154
|
+
in the coefficient ring.
|
|
155
|
+
|
|
156
|
+
EXAMPLES::
|
|
157
|
+
|
|
158
|
+
sage: WittVectorRing(QQ, p=5)
|
|
159
|
+
Ring of truncated 5-typical Witt vectors of length 1 over
|
|
160
|
+
Rational Field
|
|
161
|
+
|
|
162
|
+
::
|
|
163
|
+
|
|
164
|
+
sage: WittVectorRing(GF(3))
|
|
165
|
+
Ring of truncated 3-typical Witt vectors of length 1 over
|
|
166
|
+
Finite Field of size 3
|
|
167
|
+
|
|
168
|
+
::
|
|
169
|
+
|
|
170
|
+
sage: WittVectorRing(GF(3)['t'])
|
|
171
|
+
Ring of truncated 3-typical Witt vectors of length 1 over
|
|
172
|
+
Univariate Polynomial Ring in t over Finite Field of size 3
|
|
173
|
+
|
|
174
|
+
::
|
|
175
|
+
|
|
176
|
+
sage: WittVectorRing(Qp(7), prec=30, p=5)
|
|
177
|
+
Ring of truncated 5-typical Witt vectors of length 30 over
|
|
178
|
+
7-adic Field with capped relative precision 20
|
|
179
|
+
|
|
180
|
+
TESTS::
|
|
181
|
+
|
|
182
|
+
sage: # needs sage.combinat sage.groups sage.modules
|
|
183
|
+
sage: A = SymmetricGroup(3).algebra(QQ)
|
|
184
|
+
sage: WittVectorRing(A)
|
|
185
|
+
Traceback (most recent call last):
|
|
186
|
+
...
|
|
187
|
+
TypeError: Symmetric group algebra of order 3 over Rational Field is not a commutative ring
|
|
188
|
+
|
|
189
|
+
sage: WittVectorRing(QQ)
|
|
190
|
+
Traceback (most recent call last):
|
|
191
|
+
...
|
|
192
|
+
ValueError: Rational Field has non-prime characteristic and no prime was supplied
|
|
193
|
+
|
|
194
|
+
sage: WittVectorRing(QQ, p=5, algorithm='moon')
|
|
195
|
+
Traceback (most recent call last):
|
|
196
|
+
...
|
|
197
|
+
ValueError: algorithm must be one of None, 'standard', 'p_invertible', 'finotti', 'phantom'
|
|
198
|
+
|
|
199
|
+
sage: W = WittVectorRing(ZZ, p=53)
|
|
200
|
+
sage: type(W)
|
|
201
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_standard_with_category'>
|
|
202
|
+
|
|
203
|
+
sage: W = WittVectorRing(PolynomialRing(GF(13), 't'))
|
|
204
|
+
sage: type(W)
|
|
205
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_phantom_with_category'>
|
|
206
|
+
|
|
207
|
+
sage: W = WittVectorRing(PolynomialRing(GF(5), 't,u'))
|
|
208
|
+
sage: type(W)
|
|
209
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_finotti_with_category'>
|
|
210
|
+
"""
|
|
211
|
+
def __classcall_private__(cls, coefficient_ring, prec=1, p=None, algorithm=None):
|
|
212
|
+
r"""
|
|
213
|
+
Construct the ring of truncated Witt vectors from the parameters.
|
|
214
|
+
|
|
215
|
+
TESTS::
|
|
216
|
+
|
|
217
|
+
sage: W = WittVectorRing(QQ, p=5)
|
|
218
|
+
sage: W
|
|
219
|
+
Ring of truncated 5-typical Witt vectors of length 1 over Rational Field
|
|
220
|
+
"""
|
|
221
|
+
if coefficient_ring not in CommutativeRings():
|
|
222
|
+
raise TypeError(f"{coefficient_ring} is not a commutative ring")
|
|
223
|
+
elif not (isinstance(prec, int) or isinstance(prec, Integer)):
|
|
224
|
+
raise TypeError(f"{prec} is not an integer")
|
|
225
|
+
elif prec <= 0:
|
|
226
|
+
raise ValueError(f"{prec} must be positive")
|
|
227
|
+
|
|
228
|
+
prec = Integer(prec)
|
|
229
|
+
char = coefficient_ring.characteristic()
|
|
230
|
+
|
|
231
|
+
if p is None:
|
|
232
|
+
if char not in Primes():
|
|
233
|
+
raise ValueError(f"{coefficient_ring} has non-prime "
|
|
234
|
+
"characteristic and no prime was supplied")
|
|
235
|
+
p = char
|
|
236
|
+
elif p not in Primes():
|
|
237
|
+
raise ValueError(f"p must be a prime number, here {p} was given")
|
|
238
|
+
|
|
239
|
+
match algorithm:
|
|
240
|
+
case None:
|
|
241
|
+
if p == char:
|
|
242
|
+
if (coefficient_ring in Fields().Finite()
|
|
243
|
+
or isinstance(coefficient_ring,
|
|
244
|
+
PolynomialRing_generic)
|
|
245
|
+
and coefficient_ring.base()
|
|
246
|
+
in Fields().Finite()):
|
|
247
|
+
child = WittVectorRing_phantom
|
|
248
|
+
else:
|
|
249
|
+
child = WittVectorRing_finotti
|
|
250
|
+
elif coefficient_ring(p).is_unit():
|
|
251
|
+
child = WittVectorRing_pinvertible
|
|
252
|
+
else:
|
|
253
|
+
child = WittVectorRing_standard
|
|
254
|
+
case 'finotti':
|
|
255
|
+
child = WittVectorRing_finotti
|
|
256
|
+
case 'phantom':
|
|
257
|
+
child = WittVectorRing_phantom
|
|
258
|
+
case 'p_invertible':
|
|
259
|
+
child = WittVectorRing_pinvertible
|
|
260
|
+
case 'standard':
|
|
261
|
+
child = WittVectorRing_standard
|
|
262
|
+
case _:
|
|
263
|
+
raise ValueError("algorithm must be one of None, 'standard', "
|
|
264
|
+
"'p_invertible', 'finotti', 'phantom'")
|
|
265
|
+
|
|
266
|
+
return child.__classcall__(child, coefficient_ring, prec, p)
|
|
267
|
+
|
|
268
|
+
def __init__(self, coefficient_ring, prec, prime) -> None:
|
|
269
|
+
r"""
|
|
270
|
+
Initialise ``self``.
|
|
271
|
+
|
|
272
|
+
EXAMPLES::
|
|
273
|
+
|
|
274
|
+
sage: W = WittVectorRing(PolynomialRing(GF(5), 't'), prec=4); W
|
|
275
|
+
Ring of truncated 5-typical Witt vectors of length 4 over Univariate Polynomial Ring in t over Finite Field of size 5
|
|
276
|
+
sage: type(W)
|
|
277
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_phantom_with_category'>
|
|
278
|
+
|
|
279
|
+
sage: TestSuite(W).run()
|
|
280
|
+
"""
|
|
281
|
+
cring = coefficient_ring
|
|
282
|
+
self._coefficient_ring = cring
|
|
283
|
+
self._prec = prec
|
|
284
|
+
self._prime = prime
|
|
285
|
+
|
|
286
|
+
if prec == 1 and cring in IntegralDomains():
|
|
287
|
+
cat = IntegralDomains()
|
|
288
|
+
else:
|
|
289
|
+
cat = CommutativeRings()
|
|
290
|
+
|
|
291
|
+
Parent.__init__(self, base=ZZ, category=cat)
|
|
292
|
+
|
|
293
|
+
def __iter__(self) -> Iterator:
|
|
294
|
+
"""
|
|
295
|
+
Iterator for truncated Witt vector rings.
|
|
296
|
+
|
|
297
|
+
EXAMPLES::
|
|
298
|
+
|
|
299
|
+
sage: W = WittVectorRing(GF(3), p=3, prec=2)
|
|
300
|
+
sage: [w for w in W]
|
|
301
|
+
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1),
|
|
302
|
+
(2, 2)]
|
|
303
|
+
"""
|
|
304
|
+
for t in product(self._coefficient_ring, repeat=self._prec):
|
|
305
|
+
yield self(t)
|
|
306
|
+
|
|
307
|
+
def _coerce_map_from_(self, S):
|
|
308
|
+
""""
|
|
309
|
+
Check whether there is a coerce map from ``S``.
|
|
310
|
+
|
|
311
|
+
EXAMPLES::
|
|
312
|
+
|
|
313
|
+
sage: K = GF(7)
|
|
314
|
+
sage: WK = WittVectorRing(K, prec=3)
|
|
315
|
+
sage: W = WittVectorRing(PolynomialRing(K, 't'), prec=3)
|
|
316
|
+
sage: Wf = WittVectorRing(PolynomialRing(K, 't'), prec=3, algorithm='finotti')
|
|
317
|
+
sage: WW = WittVectorRing(PolynomialRing(K, 't,u'), prec=3)
|
|
318
|
+
sage: Wf.has_coerce_map_from(WK) # indirect doctest
|
|
319
|
+
True
|
|
320
|
+
sage: Wf.has_coerce_map_from(W) # indirect doctest
|
|
321
|
+
False
|
|
322
|
+
sage: WW.has_coerce_map_from(W) # indirect doctest
|
|
323
|
+
True
|
|
324
|
+
sage: WW.has_coerce_map_from(Wf) # indirect doctest
|
|
325
|
+
True
|
|
326
|
+
sage: WW.has_coerce_map_from(WK) # indirect doctest
|
|
327
|
+
True
|
|
328
|
+
|
|
329
|
+
sage: W = WittVectorRing(GF(25), prec=2)
|
|
330
|
+
sage: W.has_coerce_map_from(WittVectorRing(GF(5), prec=3)) # indirect doctest
|
|
331
|
+
True
|
|
332
|
+
sage: W.has_coerce_map_from(WittVectorRing(ZZ, p=5, prec=3)) # indirect doctest
|
|
333
|
+
True
|
|
334
|
+
sage: W.has_coerce_map_from(WittVectorRing(PolynomialRing(GF(5), 't,u'), prec=3)) # indirect doctest
|
|
335
|
+
False
|
|
336
|
+
sage: WW = WittVectorRing(PolynomialRing(GF(5), 't'), prec=3)
|
|
337
|
+
sage: WW.has_coerce_map_from(W) # indirect doctest
|
|
338
|
+
False
|
|
339
|
+
sage: W.has_coerce_map_from(WW) # indirect doctest
|
|
340
|
+
False
|
|
341
|
+
|
|
342
|
+
sage: W = WittVectorRing(QQ, p=3, prec=3)
|
|
343
|
+
sage: W.has_coerce_map_from(WittVectorRing(ZZ, p=3, prec=3)) # indirect doctest
|
|
344
|
+
True
|
|
345
|
+
sage: W.has_coerce_map_from(WittVectorRing(QQ, p=3, prec=2)) # indirect doctest
|
|
346
|
+
False
|
|
347
|
+
|
|
348
|
+
sage: W = WittVectorRing(PolynomialRing(ZZ, 'x'), p=5, prec=2)
|
|
349
|
+
sage: W.has_coerce_map_from(WittVectorRing(ZZ, p=5, prec=3)) # indirect doctest
|
|
350
|
+
True
|
|
351
|
+
sage: W.has_coerce_map_from(WittVectorRing(ZZ, p=3, prec=3)) # indirect doctest
|
|
352
|
+
False
|
|
353
|
+
"""
|
|
354
|
+
if (isinstance(S, WittVectorRing)
|
|
355
|
+
and S.precision() >= self._prec and S.prime() == self._prime
|
|
356
|
+
and self._coefficient_ring.has_coerce_map_from(
|
|
357
|
+
S.coefficient_ring())):
|
|
358
|
+
return (any(isinstance(S, rng) for rng in self._always_coerce)
|
|
359
|
+
or (S.precision() != self._prec
|
|
360
|
+
or S.coefficient_ring() is not self._coefficient_ring)
|
|
361
|
+
and any(isinstance(S, rng)
|
|
362
|
+
for rng in self._coerce_when_different))
|
|
363
|
+
if S is ZZ:
|
|
364
|
+
return True
|
|
365
|
+
|
|
366
|
+
def _generate_sum_and_product_polynomials(self, coefficient_ring, prec, p):
|
|
367
|
+
"""
|
|
368
|
+
Generate the sum and product polynomials defining the ring laws of
|
|
369
|
+
truncated Witt vectors for the ``standard`` algorithm.
|
|
370
|
+
|
|
371
|
+
EXAMPLES::
|
|
372
|
+
|
|
373
|
+
sage: P.<X1,X2,Y1,Y2> = PolynomialRing(GF(3),'X1,X2,Y1,Y2')
|
|
374
|
+
sage: W = WittVectorRing(P, p=3, prec=2, algorithm='standard')
|
|
375
|
+
sage: W([X1,X2]) + W([Y1,Y2]) # indirect doctest
|
|
376
|
+
(X1 + Y1, -X1^2*Y1 - X1*Y1^2 + X2 + Y2)
|
|
377
|
+
sage: W([X1,X2]) * W([Y1,Y2]) # indirect doctest
|
|
378
|
+
(X1*Y1, X2*Y1^3 + X1^3*Y2)
|
|
379
|
+
"""
|
|
380
|
+
x_var_names = [f'X{i}' for i in range(prec)]
|
|
381
|
+
y_var_names = [f'Y{i}' for i in range(prec)]
|
|
382
|
+
var_names = x_var_names + y_var_names
|
|
383
|
+
|
|
384
|
+
# Okay, what's going on here? Sage, by default, relies on
|
|
385
|
+
# Singular for Multivariate Polynomial Rings, but Singular uses
|
|
386
|
+
# only SIXTEEN bits (unsigned) to store its exponents. So if we
|
|
387
|
+
# want exponents larger than 2^16 - 1, we have to use the
|
|
388
|
+
# generic implementation. However, after some experimentation,
|
|
389
|
+
# it seems like the generic implementation is faster?
|
|
390
|
+
#
|
|
391
|
+
# After trying to compute S_4 for p=5, it looks like generic is
|
|
392
|
+
# faster for very small polys, and MUCH slower for large polys.
|
|
393
|
+
# So we'll default to singular unless we can't use it.
|
|
394
|
+
#
|
|
395
|
+
# Remark: Since when is SIXTEEN bits sufficient for anyone???
|
|
396
|
+
#
|
|
397
|
+
if p**(prec - 1) >= 2**16:
|
|
398
|
+
implementation = 'generic'
|
|
399
|
+
else:
|
|
400
|
+
implementation = 'singular'
|
|
401
|
+
|
|
402
|
+
# We first generate the "universal" polynomials and then project
|
|
403
|
+
# to the coefficient ring.
|
|
404
|
+
R = PolynomialRing(ZZ, var_names, implementation=implementation)
|
|
405
|
+
x_y_vars = R.gens()
|
|
406
|
+
x_vars = x_y_vars[:prec]
|
|
407
|
+
y_vars = x_y_vars[prec:]
|
|
408
|
+
|
|
409
|
+
self._sum_polynomials = [0]*(prec)
|
|
410
|
+
for n in range(prec):
|
|
411
|
+
s_n = x_vars[n] + y_vars[n]
|
|
412
|
+
for i in range(n):
|
|
413
|
+
s_n += ((x_vars[i]**(p**(n-i)) + y_vars[i]**(p**(n-i))
|
|
414
|
+
- self._sum_polynomials[i]**(p**(n-i))) / p**(n-i))
|
|
415
|
+
self._sum_polynomials[n] = R(s_n)
|
|
416
|
+
|
|
417
|
+
self._prod_polynomials = [x_vars[0] * y_vars[0]] + [0]*(prec-1)
|
|
418
|
+
for n in range(1, prec):
|
|
419
|
+
x_poly = sum([p**i * x_vars[i]**(p**(n-i)) for i in range(n+1)])
|
|
420
|
+
y_poly = sum([p**i * y_vars[i]**(p**(n-i)) for i in range(n+1)])
|
|
421
|
+
p_poly = sum([p**i * self._prod_polynomials[i]**(p**(n-i))
|
|
422
|
+
for i in range(n)])
|
|
423
|
+
p_n = (x_poly*y_poly - p_poly) // p**n
|
|
424
|
+
self._prod_polynomials[n] = p_n
|
|
425
|
+
|
|
426
|
+
S = PolynomialRing(coefficient_ring, x_y_vars)
|
|
427
|
+
for n in range(prec):
|
|
428
|
+
self._sum_polynomials[n] = S(self._sum_polynomials[n])
|
|
429
|
+
self._prod_polynomials[n] = S(self._prod_polynomials[n])
|
|
430
|
+
|
|
431
|
+
def _latex_(self) -> str:
|
|
432
|
+
r"""
|
|
433
|
+
Return a `\LaTeX` representation of ``self``.
|
|
434
|
+
|
|
435
|
+
.. WARNING::
|
|
436
|
+
|
|
437
|
+
This representation follows the standard representation in the
|
|
438
|
+
literature which does not mention `p`.
|
|
439
|
+
|
|
440
|
+
EXAMPLES::
|
|
441
|
+
|
|
442
|
+
sage: W = WittVectorRing(PolynomialRing(GF(3),'t'))
|
|
443
|
+
sage: latex(W)
|
|
444
|
+
W_{1}\left(\Bold{F}_{3}[t]\right)
|
|
445
|
+
"""
|
|
446
|
+
return "W_{%s}\\left(%s\\right)" % (latex(self._prec),
|
|
447
|
+
latex(self._coefficient_ring))
|
|
448
|
+
|
|
449
|
+
def _repr_(self) -> str:
|
|
450
|
+
"""
|
|
451
|
+
Return a string representation of the ring.
|
|
452
|
+
|
|
453
|
+
EXAMPLES::
|
|
454
|
+
|
|
455
|
+
sage: WittVectorRing(QQ, p=2, prec=5)
|
|
456
|
+
Ring of truncated 2-typical Witt vectors of length 5 over Rational Field
|
|
457
|
+
"""
|
|
458
|
+
return f"Ring of truncated {self._prime}-typical Witt vectors of "\
|
|
459
|
+
f"length {self._prec} over {self._coefficient_ring}"
|
|
460
|
+
|
|
461
|
+
def cardinality(self):
|
|
462
|
+
"""
|
|
463
|
+
Return the cardinality of ``self``.
|
|
464
|
+
|
|
465
|
+
EXAMPLES::
|
|
466
|
+
|
|
467
|
+
sage: WittVectorRing(GF(17), prec=2).cardinality()
|
|
468
|
+
289
|
|
469
|
+
sage: WittVectorRing(QQ, p=2).cardinality()
|
|
470
|
+
+Infinity
|
|
471
|
+
"""
|
|
472
|
+
return self._coefficient_ring.cardinality()**(self._prec)
|
|
473
|
+
|
|
474
|
+
def characteristic(self):
|
|
475
|
+
"""
|
|
476
|
+
Return the characteristic of ``self``.
|
|
477
|
+
|
|
478
|
+
EXAMPLES::
|
|
479
|
+
|
|
480
|
+
sage: WittVectorRing(GF(25), p=5, prec=3).characteristic()
|
|
481
|
+
125
|
|
482
|
+
sage: WittVectorRing(ZZ, p=2, prec=4).characteristic()
|
|
483
|
+
0
|
|
484
|
+
sage: WittVectorRing(Integers(18), p=3, prec=3).characteristic()
|
|
485
|
+
162
|
|
486
|
+
"""
|
|
487
|
+
p = self._prime
|
|
488
|
+
if self._coefficient_ring(p).is_unit():
|
|
489
|
+
# If p is invertible, W_n(R) is isomorphic to R^n.
|
|
490
|
+
return self._coefficient_ring.characteristic()
|
|
491
|
+
|
|
492
|
+
# This is Jacob Dennerlein's Corollary 3.3. in "Computational
|
|
493
|
+
# Aspects of Mixed Characteristic Witt Vectors" (preprint)
|
|
494
|
+
return p**(self._prec-1) * self._coefficient_ring.characteristic()
|
|
495
|
+
|
|
496
|
+
def coefficient_ring(self):
|
|
497
|
+
"""
|
|
498
|
+
Return the coefficient ring of ``self``.
|
|
499
|
+
|
|
500
|
+
EXAMPLES::
|
|
501
|
+
|
|
502
|
+
sage: W = WittVectorRing(Zp(5), p=5)
|
|
503
|
+
sage: W.coefficient_ring()
|
|
504
|
+
5-adic Ring with capped relative precision 20
|
|
505
|
+
"""
|
|
506
|
+
return self._coefficient_ring
|
|
507
|
+
|
|
508
|
+
def is_finite(self) -> bool:
|
|
509
|
+
"""
|
|
510
|
+
Return whether ``self`` is a finite ring.
|
|
511
|
+
|
|
512
|
+
EXAMPLES::
|
|
513
|
+
|
|
514
|
+
sage: WittVectorRing(GF(23)).is_finite()
|
|
515
|
+
True
|
|
516
|
+
sage: WittVectorRing(ZZ, p=2).is_finite()
|
|
517
|
+
False
|
|
518
|
+
"""
|
|
519
|
+
return self._coefficient_ring.is_finite()
|
|
520
|
+
|
|
521
|
+
def precision(self):
|
|
522
|
+
"""
|
|
523
|
+
Return the length of the truncated Witt vectors in ``length``.
|
|
524
|
+
|
|
525
|
+
EXAMPLES::
|
|
526
|
+
|
|
527
|
+
sage: WittVectorRing(GF(9), p=3, prec=3).precision()
|
|
528
|
+
3
|
|
529
|
+
"""
|
|
530
|
+
return self._prec
|
|
531
|
+
|
|
532
|
+
def prime(self):
|
|
533
|
+
"""
|
|
534
|
+
Return the prime from which the truncated Witt vector ring has been
|
|
535
|
+
constructed.
|
|
536
|
+
|
|
537
|
+
EXAMPLES::
|
|
538
|
+
|
|
539
|
+
sage: W = WittVectorRing(GF(81), prec=3)
|
|
540
|
+
sage: W.prime()
|
|
541
|
+
3
|
|
542
|
+
|
|
543
|
+
sage: W = WittVectorRing(ZZ, p=7, prec=2)
|
|
544
|
+
sage: W.prime()
|
|
545
|
+
7
|
|
546
|
+
"""
|
|
547
|
+
return self._prime
|
|
548
|
+
|
|
549
|
+
def prod_polynomials(self, variables=None):
|
|
550
|
+
"""
|
|
551
|
+
Return the Witt product polynomials.
|
|
552
|
+
|
|
553
|
+
INPUT:
|
|
554
|
+
|
|
555
|
+
- ``variables`` -- names of the indeterminates (default: ``None``),
|
|
556
|
+
given as a string, or as a list of strings, whose length must be the
|
|
557
|
+
double of the precision of the ring. When nothing is given,
|
|
558
|
+
variables indexed by `X` and `Y` are used.
|
|
559
|
+
|
|
560
|
+
EXAMPLES::
|
|
561
|
+
|
|
562
|
+
sage: W = WittVectorRing(GF(5), prec=3)
|
|
563
|
+
sage: W.prod_polynomials()
|
|
564
|
+
[X0*Y0,
|
|
565
|
+
X1*Y0^5 + X0^5*Y1,
|
|
566
|
+
-X0^5*X1^4*Y0^20*Y1 - 2*X0^10*X1^3*Y0^15*Y1^2 - 2*X0^15*X1^2*Y0^10*Y1^3 - X0^20*X1*Y0^5*Y1^4 + X2*Y0^25 + X0^25*Y2 + X1^5*Y1^5]
|
|
567
|
+
|
|
568
|
+
sage: W = WittVectorRing(ZZ, p=2, prec=2)
|
|
569
|
+
sage: W.prod_polynomials('T0, T1, U0, U1')
|
|
570
|
+
[T0*U0, T1*U0^2 + T0^2*U1 + 2*T1*U1]
|
|
571
|
+
"""
|
|
572
|
+
if not hasattr(self, '_prod_polynomials'):
|
|
573
|
+
self._generate_sum_and_product_polynomials(self._coefficient_ring,
|
|
574
|
+
self._prec, self._prime)
|
|
575
|
+
if variables is None:
|
|
576
|
+
return self._prod_polynomials.copy()
|
|
577
|
+
R = PolynomialRing(self._coefficient_ring, variables)
|
|
578
|
+
return [R(self._prod_polynomials[i]) for i in range(self._prec)]
|
|
579
|
+
|
|
580
|
+
def random_element(self, *args, **kwds):
|
|
581
|
+
"""
|
|
582
|
+
Return a random truncated Witt vector.
|
|
583
|
+
|
|
584
|
+
Extra arguments are passed to
|
|
585
|
+
the random generator of the coefficient ring.
|
|
586
|
+
|
|
587
|
+
EXAMPLES::
|
|
588
|
+
|
|
589
|
+
sage: WittVectorRing(GF(27,'t'), prec=2).random_element() # random
|
|
590
|
+
(z3, 2*z3^2 + 1)
|
|
591
|
+
|
|
592
|
+
sage: W = WittVectorRing(PolynomialRing(ZZ,'x'), p=3, prec=3)
|
|
593
|
+
sage: W.random_element(5) # random
|
|
594
|
+
(x^5 - 2*x^4 - 4*x^3 - 2*x^2 + 1, -x^5 + 2*x^4 - x - 1,
|
|
595
|
+
-x^5 + 7*x^4 + 3*x^3 - 24*x^2 - 1)
|
|
596
|
+
"""
|
|
597
|
+
return self(tuple(self._coefficient_ring.random_element(*args, **kwds)
|
|
598
|
+
for _ in range(self._prec)))
|
|
599
|
+
|
|
600
|
+
def sum_polynomials(self, variables=None):
|
|
601
|
+
"""
|
|
602
|
+
Return the Witt sum polynomials.
|
|
603
|
+
|
|
604
|
+
INPUT:
|
|
605
|
+
|
|
606
|
+
- ``variables`` -- names of the indeterminates (default: ``None``),
|
|
607
|
+
given as a string, or as a list of strings, whose length must be the
|
|
608
|
+
double of the precision of the ring. When nothing is given,
|
|
609
|
+
variables indexed by `X` and `Y` are used.
|
|
610
|
+
|
|
611
|
+
EXAMPLES::
|
|
612
|
+
|
|
613
|
+
sage: W = WittVectorRing(GF(5), prec=2)
|
|
614
|
+
sage: W.sum_polynomials(['T0', 'T1', 'U0', 'U1'])
|
|
615
|
+
[T0 + U0, -T0^4*U0 - 2*T0^3*U0^2 - 2*T0^2*U0^3 - T0*U0^4 + T1 + U1]
|
|
616
|
+
|
|
617
|
+
sage: W = WittVectorRing(ZZ, p=2, prec=3)
|
|
618
|
+
sage: W.sum_polynomials()
|
|
619
|
+
[X0 + Y0,
|
|
620
|
+
-X0*Y0 + X1 + Y1,
|
|
621
|
+
-X0^3*Y0 - 2*X0^2*Y0^2 - X0*Y0^3 + X0*X1*Y0 + X0*Y0*Y1 - X1*Y1 + X2 + Y2]
|
|
622
|
+
"""
|
|
623
|
+
if not hasattr(self, '_sum_polynomials'):
|
|
624
|
+
self._generate_sum_and_product_polynomials(self._coefficient_ring,
|
|
625
|
+
self._prec, self._prime)
|
|
626
|
+
if variables is None:
|
|
627
|
+
return self._sum_polynomials.copy()
|
|
628
|
+
R = PolynomialRing(self._coefficient_ring, variables)
|
|
629
|
+
return [R(self._sum_polynomials[i]) for i in range(self._prec)]
|
|
630
|
+
|
|
631
|
+
def teichmuller_lift(self, x):
|
|
632
|
+
"""
|
|
633
|
+
Return the Teichmüller lift of ``x`` in ``self``.
|
|
634
|
+
|
|
635
|
+
This lift is sometimes known as the multiplicative lift of ``x``.
|
|
636
|
+
|
|
637
|
+
EXAMPLES::
|
|
638
|
+
|
|
639
|
+
sage: WittVectorRing(GF(125,'t'), prec=2).teichmuller_lift(3)
|
|
640
|
+
(3, 0)
|
|
641
|
+
"""
|
|
642
|
+
if x not in self._coefficient_ring:
|
|
643
|
+
raise TypeError(f"{x} not in {self._coefficient_ring}")
|
|
644
|
+
return self((x,) + tuple(0 for _ in range(self._prec-1)))
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
class WittVectorRing_finotti(WittVectorRing):
|
|
648
|
+
"""
|
|
649
|
+
Child class for truncated Witt vectors using Finotti's algorithm.
|
|
650
|
+
|
|
651
|
+
.. WARNING::
|
|
652
|
+
|
|
653
|
+
This class should never be called directly, use ``WittVectorRing``
|
|
654
|
+
instead.
|
|
655
|
+
|
|
656
|
+
EXAMPLES::
|
|
657
|
+
|
|
658
|
+
sage: W = WittVectorRing(GF(49), prec=3, algorithm='finotti')
|
|
659
|
+
sage: W
|
|
660
|
+
Ring of truncated 7-typical Witt vectors of length 3 over Finite Field in z2 of size 7^2
|
|
661
|
+
|
|
662
|
+
sage: W = WittVectorRing(ZZ, p=11, prec=3, algorithm='finotti')
|
|
663
|
+
Traceback (most recent call last):
|
|
664
|
+
...
|
|
665
|
+
ValueError: the 'finotti' algorithm only works for coefficients rings of characteristic p
|
|
666
|
+
"""
|
|
667
|
+
Element = WittVector_finotti
|
|
668
|
+
|
|
669
|
+
def __init__(self, coefficient_ring, prec, prime) -> None:
|
|
670
|
+
r"""
|
|
671
|
+
Initialise ``self``.
|
|
672
|
+
|
|
673
|
+
EXAMPLES::
|
|
674
|
+
|
|
675
|
+
sage: W = WittVectorRing(PowerSeriesRing(GF(3), 't'), p=3, prec=3)
|
|
676
|
+
sage: W
|
|
677
|
+
Ring of truncated 3-typical Witt vectors of length 3 over Power Series Ring in t over Finite Field of size 3
|
|
678
|
+
sage: type(W)
|
|
679
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_finotti_with_category'>
|
|
680
|
+
|
|
681
|
+
sage: TestSuite(W).run()
|
|
682
|
+
"""
|
|
683
|
+
if coefficient_ring.characteristic() != prime:
|
|
684
|
+
raise ValueError("the 'finotti' algorithm only works for "
|
|
685
|
+
"coefficients rings of characteristic p")
|
|
686
|
+
|
|
687
|
+
if isinstance(coefficient_ring, MPolynomialRing_base):
|
|
688
|
+
self._always_coerce = [WittVectorRing_finotti,
|
|
689
|
+
WittVectorRing_phantom,
|
|
690
|
+
WittVectorRing_standard]
|
|
691
|
+
self._coerce_when_different = []
|
|
692
|
+
else:
|
|
693
|
+
self._always_coerce = [WittVectorRing_finotti,
|
|
694
|
+
WittVectorRing_standard]
|
|
695
|
+
self._coerce_when_different = [WittVectorRing_phantom]
|
|
696
|
+
|
|
697
|
+
import numpy as np
|
|
698
|
+
R = Zp(prime, prec=prec+1, type='fixed-mod')
|
|
699
|
+
v_p = ZZ.valuation(prime)
|
|
700
|
+
table = [[0]]
|
|
701
|
+
for k in range(1, prec+1):
|
|
702
|
+
pk = prime**k
|
|
703
|
+
row = np.empty(pk, dtype=int)
|
|
704
|
+
row[0] = 0
|
|
705
|
+
prev_bin = 1
|
|
706
|
+
for i in range(1, pk // 2 + 1):
|
|
707
|
+
val = v_p(i)
|
|
708
|
+
# Instead of calling binomial each time, we compute the
|
|
709
|
+
# coefficients recursively. This is MUCH faster.
|
|
710
|
+
next_bin = prev_bin * (pk - (i-1)) // i
|
|
711
|
+
prev_bin = next_bin
|
|
712
|
+
series = R(-next_bin // prime**(k-val))
|
|
713
|
+
for _ in range(val):
|
|
714
|
+
temp = series % prime
|
|
715
|
+
series = (series - R.teichmuller(temp)) // prime
|
|
716
|
+
row[i] = ZZ(series % prime)
|
|
717
|
+
row[pk - i] = row[i] # binomial coefficients are symmetric
|
|
718
|
+
table.append(row)
|
|
719
|
+
self._binomial_table = table
|
|
720
|
+
|
|
721
|
+
super().__init__(coefficient_ring, prec, prime)
|
|
722
|
+
|
|
723
|
+
def _eta_bar(self, vec, eta_index):
|
|
724
|
+
r"""
|
|
725
|
+
Generate the `\eta_i` for ``finotti``'s algorithm.
|
|
726
|
+
|
|
727
|
+
EXAMPLES::
|
|
728
|
+
|
|
729
|
+
sage: R.<x,y,z,t> = PolynomialRing(GF(5))
|
|
730
|
+
sage: W = WittVectorRing(R, prec=2, algorithm='finotti')
|
|
731
|
+
sage: (W([x,y]) + W([z,t]))[1] # indirect doctest
|
|
732
|
+
-x^4*z - 2*x^3*z^2 - 2*x^2*z^3 - x*z^4 + y + t
|
|
733
|
+
"""
|
|
734
|
+
vec = tuple(x for x in vec if x != 0) # strip zeroes
|
|
735
|
+
|
|
736
|
+
# special cases
|
|
737
|
+
if len(vec) <= 1:
|
|
738
|
+
return 0
|
|
739
|
+
if eta_index == 0:
|
|
740
|
+
return sum(vec)
|
|
741
|
+
|
|
742
|
+
# renaming to match notation in Finotti's "Computations with Witt
|
|
743
|
+
# vectors and the Greenberg transform", doi:10.1142/S1793042114500377
|
|
744
|
+
k = eta_index
|
|
745
|
+
p = self._prime
|
|
746
|
+
# if vec = (x,y), we know what to do: Theorem 8.6
|
|
747
|
+
if len(vec) == 2:
|
|
748
|
+
# Here we have to check if we've pre-computed already
|
|
749
|
+
x, y = vec
|
|
750
|
+
scriptN = [[None] for _ in range(k+1)] # each list starts with
|
|
751
|
+
# None, so that indexing matches paper
|
|
752
|
+
|
|
753
|
+
# calculate first N_t scriptN's
|
|
754
|
+
for t in range(1, k+1):
|
|
755
|
+
for i in range(1, p**t):
|
|
756
|
+
scriptN[t].append(self._binomial_table[t][i]
|
|
757
|
+
* fast_char_p_power(x, i)
|
|
758
|
+
* fast_char_p_power(y, p**t - i))
|
|
759
|
+
indexN = [p**i - 1 for i in range(k+1)]
|
|
760
|
+
for t in range(2, k+1):
|
|
761
|
+
for i in range(1, t):
|
|
762
|
+
# append scriptN_{t, N_t+l}
|
|
763
|
+
next_scriptN = self._eta_bar(
|
|
764
|
+
scriptN[t-i][1:indexN[t-i]+t-i], i
|
|
765
|
+
)
|
|
766
|
+
scriptN[t].append(next_scriptN)
|
|
767
|
+
return sum(scriptN[k][1:])
|
|
768
|
+
|
|
769
|
+
# if vec is longer, we split and recurse: Proposition 5.4
|
|
770
|
+
# This is where we need to using multiprocessing.
|
|
771
|
+
else:
|
|
772
|
+
m = len(vec) // 2
|
|
773
|
+
v_1 = vec[:m]
|
|
774
|
+
v_2 = vec[m:]
|
|
775
|
+
s_1 = sum(v_1)
|
|
776
|
+
s_2 = sum(v_2)
|
|
777
|
+
scriptM = [[] for _ in range(k+1)]
|
|
778
|
+
for t in range(1, k+1):
|
|
779
|
+
scriptM[t].append(self._eta_bar(v_1, t))
|
|
780
|
+
scriptM[t].append(self._eta_bar(v_2, t))
|
|
781
|
+
scriptM[t].append(self._eta_bar((s_1, s_2), t))
|
|
782
|
+
for t in range(2, k+1):
|
|
783
|
+
for s in range(1, t):
|
|
784
|
+
result = self._eta_bar(scriptM[t-s], s)
|
|
785
|
+
scriptM[t].append(result)
|
|
786
|
+
return sum(scriptM[k])
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
class WittVectorRing_phantom(WittVectorRing):
|
|
790
|
+
"""
|
|
791
|
+
Child class for truncated Witt vectors using the ``phantom`` algorithm.
|
|
792
|
+
|
|
793
|
+
.. WARNING::
|
|
794
|
+
|
|
795
|
+
This class should never be called directly, use ``WittVectorRing``
|
|
796
|
+
instead.
|
|
797
|
+
|
|
798
|
+
EXAMPLES::
|
|
799
|
+
|
|
800
|
+
sage: W = WittVectorRing(GF(19), prec=20)
|
|
801
|
+
sage: W
|
|
802
|
+
Ring of truncated 19-typical Witt vectors of length 20 over Finite Field of size 19
|
|
803
|
+
|
|
804
|
+
sage: W = WittVectorRing(QQ, p=23, prec=3, algorithm='phantom')
|
|
805
|
+
Traceback (most recent call last):
|
|
806
|
+
...
|
|
807
|
+
ValueError: the 'phantom' algorithm only works when the coefficient ring is a finite field of p, or a polynomial ring on that field
|
|
808
|
+
"""
|
|
809
|
+
Element = WittVector_phantom
|
|
810
|
+
|
|
811
|
+
def __init__(self, coefficient_ring, prec, prime) -> None:
|
|
812
|
+
r"""
|
|
813
|
+
Initialise ``self``.
|
|
814
|
+
|
|
815
|
+
EXAMPLES::
|
|
816
|
+
|
|
817
|
+
sage: W = WittVectorRing(GF(23,'t'), p=23, prec=2)
|
|
818
|
+
sage: W
|
|
819
|
+
Ring of truncated 23-typical Witt vectors of length 2 over Finite Field of size 23
|
|
820
|
+
sage: type(W)
|
|
821
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_phantom_with_category'>
|
|
822
|
+
|
|
823
|
+
sage: TestSuite(W).run()
|
|
824
|
+
"""
|
|
825
|
+
if not (coefficient_ring.characteristic() == prime
|
|
826
|
+
and (coefficient_ring in Fields().Finite()
|
|
827
|
+
or ((isinstance(coefficient_ring, PolynomialRing_generic)
|
|
828
|
+
or isinstance(coefficient_ring,
|
|
829
|
+
MPolynomialRing_base))
|
|
830
|
+
and coefficient_ring.base() in Fields().Finite()))):
|
|
831
|
+
raise ValueError("the 'phantom' algorithm only works when the "
|
|
832
|
+
"coefficient ring is a finite field of "
|
|
833
|
+
"p, or a polynomial ring on that field")
|
|
834
|
+
|
|
835
|
+
if (coefficient_ring in Fields().Finite()
|
|
836
|
+
or isinstance(coefficient_ring,
|
|
837
|
+
PolynomialRing_generic)):
|
|
838
|
+
self._always_coerce = [WittVectorRing_finotti,
|
|
839
|
+
WittVectorRing_phantom,
|
|
840
|
+
WittVectorRing_standard]
|
|
841
|
+
self._coerce_when_different = []
|
|
842
|
+
else:
|
|
843
|
+
self._always_coerce = [WittVectorRing_phantom,
|
|
844
|
+
WittVectorRing_standard]
|
|
845
|
+
self._coerce_when_different = [WittVectorRing_finotti]
|
|
846
|
+
|
|
847
|
+
super().__init__(coefficient_ring, prec, prime)
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
class WittVectorRing_pinvertible(WittVectorRing):
|
|
851
|
+
"""
|
|
852
|
+
Child class for truncated Witt vectors using the ``p_invertible`` algorithm.
|
|
853
|
+
|
|
854
|
+
.. WARNING::
|
|
855
|
+
|
|
856
|
+
This class should never be called directly, use ``WittVectorRing``
|
|
857
|
+
instead.
|
|
858
|
+
|
|
859
|
+
EXAMPLES::
|
|
860
|
+
|
|
861
|
+
sage: W = WittVectorRing(QQ, p=31, prec=20)
|
|
862
|
+
sage: W
|
|
863
|
+
Ring of truncated 31-typical Witt vectors of length 20 over Rational Field
|
|
864
|
+
|
|
865
|
+
sage: W = WittVectorRing(GF(3), prec=3, algorithm='p_invertible')
|
|
866
|
+
Traceback (most recent call last):
|
|
867
|
+
...
|
|
868
|
+
ValueError: the 'p_invertible' algorithm only works when p is a unit in the ring of coefficients
|
|
869
|
+
"""
|
|
870
|
+
Element = WittVector_pinvertible
|
|
871
|
+
|
|
872
|
+
def __init__(self, coefficient_ring, prec, prime) -> None:
|
|
873
|
+
r"""
|
|
874
|
+
Initialise ``self``.
|
|
875
|
+
|
|
876
|
+
EXAMPLES::
|
|
877
|
+
|
|
878
|
+
sage: W = WittVectorRing(QQ, p=11, prec=3)
|
|
879
|
+
sage: W
|
|
880
|
+
Ring of truncated 11-typical Witt vectors of length 3 over Rational Field
|
|
881
|
+
sage: type(W)
|
|
882
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_pinvertible_with_category'>
|
|
883
|
+
|
|
884
|
+
sage: TestSuite(W).run()
|
|
885
|
+
"""
|
|
886
|
+
if not coefficient_ring(prime).is_unit():
|
|
887
|
+
raise ValueError("the 'p_invertible' algorithm only works when p "
|
|
888
|
+
"is a unit in the ring of coefficients")
|
|
889
|
+
|
|
890
|
+
self._always_coerce = [WittVectorRing_pinvertible,
|
|
891
|
+
WittVectorRing_standard]
|
|
892
|
+
self._coerce_when_different = []
|
|
893
|
+
|
|
894
|
+
super().__init__(coefficient_ring, prec, prime)
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
class WittVectorRing_standard(WittVectorRing):
|
|
898
|
+
"""
|
|
899
|
+
Child class for truncated Witt vectors using the ``standard`` algorithm.
|
|
900
|
+
|
|
901
|
+
.. WARNING::
|
|
902
|
+
|
|
903
|
+
This class should never be called directly, use ``WittVectorRing``
|
|
904
|
+
instead.
|
|
905
|
+
|
|
906
|
+
EXAMPLES::
|
|
907
|
+
|
|
908
|
+
sage: W = WittVectorRing(GF(3), prec=3, algorithm='standard')
|
|
909
|
+
sage: W
|
|
910
|
+
Ring of truncated 3-typical Witt vectors of length 3 over Finite Field of size 3
|
|
911
|
+
"""
|
|
912
|
+
Element = WittVector_standard
|
|
913
|
+
|
|
914
|
+
def __init__(self, coefficient_ring, prec, prime) -> None:
|
|
915
|
+
r"""
|
|
916
|
+
Initialise ``self``.
|
|
917
|
+
|
|
918
|
+
EXAMPLES::
|
|
919
|
+
|
|
920
|
+
sage: W = WittVectorRing(ZZ, p=5, prec=2)
|
|
921
|
+
sage: W
|
|
922
|
+
Ring of truncated 5-typical Witt vectors of length 2 over Integer Ring
|
|
923
|
+
sage: type(W)
|
|
924
|
+
<class 'sage.rings.padics.witt_vector_ring.WittVectorRing_standard_with_category'>
|
|
925
|
+
|
|
926
|
+
sage: TestSuite(W).run()
|
|
927
|
+
"""
|
|
928
|
+
self._always_coerce = []
|
|
929
|
+
self._coerce_when_different = [WittVectorRing]
|
|
930
|
+
|
|
931
|
+
self._generate_sum_and_product_polynomials(coefficient_ring, prec,
|
|
932
|
+
prime)
|
|
933
|
+
|
|
934
|
+
super().__init__(coefficient_ring, prec, prime)
|