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,1505 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
# distutils: libraries = NTL_LIBRARIES gmp M_LIBRARIES
|
|
3
|
+
# distutils: extra_compile_args = NTL_CFLAGS
|
|
4
|
+
# distutils: include_dirs = NTL_INCDIR
|
|
5
|
+
# distutils: library_dirs = NTL_LIBDIR
|
|
6
|
+
# distutils: extra_link_args = NTL_LIBEXTRA
|
|
7
|
+
# distutils: language = c++
|
|
8
|
+
"""
|
|
9
|
+
`p`-adic Printing
|
|
10
|
+
|
|
11
|
+
This file contains code for printing `p`-adic elements.
|
|
12
|
+
|
|
13
|
+
It has been moved here to prevent code duplication and make finding
|
|
14
|
+
the relevant code easier.
|
|
15
|
+
|
|
16
|
+
AUTHORS:
|
|
17
|
+
|
|
18
|
+
- David Roe
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
#*****************************************************************************
|
|
22
|
+
# Copyright (C) 2008-2013 David Roe <roed.math@gmail.com>
|
|
23
|
+
# William Stein <wstein@gmail.com>
|
|
24
|
+
#
|
|
25
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
26
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
27
|
+
# the License, or (at your option) any later version.
|
|
28
|
+
#
|
|
29
|
+
# http://www.gnu.org/licenses/
|
|
30
|
+
#*****************************************************************************
|
|
31
|
+
|
|
32
|
+
from cpython.list cimport *
|
|
33
|
+
from sage.libs.gmp.mpz cimport *
|
|
34
|
+
from sage.structure.richcmp cimport richcmp_not_equal, rich_to_bool
|
|
35
|
+
from sage.rings.padics.misc import trim_zeros
|
|
36
|
+
from sage.misc.latex import latex_variable_name
|
|
37
|
+
|
|
38
|
+
import sys
|
|
39
|
+
|
|
40
|
+
from sage.rings.integer cimport Integer
|
|
41
|
+
|
|
42
|
+
cdef enum print_modes:
|
|
43
|
+
terse
|
|
44
|
+
series
|
|
45
|
+
val_unit
|
|
46
|
+
digits
|
|
47
|
+
bars
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def pAdicPrinter(ring, options={}):
|
|
51
|
+
"""
|
|
52
|
+
Create a :class:`pAdicPrinter`.
|
|
53
|
+
|
|
54
|
+
INPUT:
|
|
55
|
+
|
|
56
|
+
- ``ring`` -- a `p`-adic ring or field
|
|
57
|
+
|
|
58
|
+
- ``options`` -- dictionary, with keys in ``'mode'``, ``'pos'``,
|
|
59
|
+
``'ram_name'``, ``'unram_name'``, ``'var_name'``, ``'max_ram_terms'``,
|
|
60
|
+
``'max_unram_terms'``, ``'max_terse_terms'``, ``'sep'``, ``'alphabet'``; see
|
|
61
|
+
:class:`pAdicPrinter_class` for the meanings of these keywords.
|
|
62
|
+
|
|
63
|
+
EXAMPLES::
|
|
64
|
+
|
|
65
|
+
sage: from sage.rings.padics.padic_printing import pAdicPrinter
|
|
66
|
+
sage: R = Zp(5)
|
|
67
|
+
sage: pAdicPrinter(R, {'sep': '&'})
|
|
68
|
+
series printer for 5-adic Ring with capped relative precision 20
|
|
69
|
+
"""
|
|
70
|
+
for option in ['mode', 'pos', 'ram_name', 'unram_name', 'var_name', 'max_ram_terms', 'max_unram_terms', 'max_terse_terms', 'sep', 'alphabet', 'show_prec']:
|
|
71
|
+
if option not in options:
|
|
72
|
+
options[option] = None
|
|
73
|
+
return pAdicPrinter_class(ring, **options)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class pAdicPrinterDefaults(SageObject):
|
|
77
|
+
"""
|
|
78
|
+
This class stores global defaults for `p`-adic printing.
|
|
79
|
+
"""
|
|
80
|
+
def __init__(self, mode='series', pos=True, max_ram_terms=-1, max_unram_terms=-1, max_terse_terms=-1, sep="|", alphabet=None):
|
|
81
|
+
r"""
|
|
82
|
+
Instances of this class store global defaults used in
|
|
83
|
+
determining printing options during the creation of `p`-adic
|
|
84
|
+
rings and fields. One instance stored in padic_printing
|
|
85
|
+
stores the globally relevant default values.
|
|
86
|
+
|
|
87
|
+
See pAdicPrinter_class for details on the meanings of these
|
|
88
|
+
inputs.
|
|
89
|
+
|
|
90
|
+
TESTS::
|
|
91
|
+
|
|
92
|
+
sage: from sage.rings.padics.padic_printing import pAdicPrinterDefaults
|
|
93
|
+
sage: D = pAdicPrinterDefaults(sep='&'); D.sep()
|
|
94
|
+
'&'
|
|
95
|
+
"""
|
|
96
|
+
self._mode = mode
|
|
97
|
+
self._pos = bool(pos)
|
|
98
|
+
if not -1 <= max_ram_terms <= sys.maxsize:
|
|
99
|
+
raise ValueError("max_ram_terms must be positive and fit in a long")
|
|
100
|
+
self._max_ram_terms = int(max_ram_terms)
|
|
101
|
+
if not -1 <= max_unram_terms <= sys.maxsize:
|
|
102
|
+
raise ValueError("max_unram_terms must be positive and fit in a long")
|
|
103
|
+
self._max_unram_terms = int(max_unram_terms)
|
|
104
|
+
if not -1 <= max_terse_terms <= sys.maxsize:
|
|
105
|
+
raise ValueError("max_terse_terms must be positive and fit in a long")
|
|
106
|
+
self._max_terse_terms = int(max_terse_terms)
|
|
107
|
+
self._sep = sep
|
|
108
|
+
if alphabet is None:
|
|
109
|
+
self._alphabet = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z')
|
|
110
|
+
else:
|
|
111
|
+
self._alphabet = alphabet
|
|
112
|
+
|
|
113
|
+
def mode(self, mode=None):
|
|
114
|
+
r"""
|
|
115
|
+
Set the default printing mode.
|
|
116
|
+
|
|
117
|
+
``mode=None`` returns the current value.
|
|
118
|
+
|
|
119
|
+
The allowed values for mode are: ``'val-unit'``, ``'series'``,
|
|
120
|
+
``'terse'``, ``'digits'`` and ``'bars'``.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: padic_printing.mode('terse')
|
|
125
|
+
sage: padic_printing.mode()
|
|
126
|
+
'terse'
|
|
127
|
+
sage: Qp(7)(100)
|
|
128
|
+
100 + O(7^20)
|
|
129
|
+
sage: padic_printing.mode('series')
|
|
130
|
+
sage: Qp(11)(100)
|
|
131
|
+
1 + 9*11 + O(11^20)
|
|
132
|
+
sage: padic_printing.mode('val-unit')
|
|
133
|
+
sage: Qp(13)(130)
|
|
134
|
+
13 * 10 + O(13^21)
|
|
135
|
+
sage: padic_printing.mode('digits')
|
|
136
|
+
sage: repr(Qp(17)(100))
|
|
137
|
+
'...5F'
|
|
138
|
+
sage: repr(Qp(17)(1000))
|
|
139
|
+
'...37E'
|
|
140
|
+
sage: padic_printing.mode('bars')
|
|
141
|
+
sage: repr(Qp(19)(1000))
|
|
142
|
+
'...2|14|12'
|
|
143
|
+
|
|
144
|
+
sage: padic_printing.mode('series')
|
|
145
|
+
"""
|
|
146
|
+
if mode is None:
|
|
147
|
+
return self._mode
|
|
148
|
+
else:
|
|
149
|
+
if mode in ['val-unit','series','terse','digits','bars']:
|
|
150
|
+
self._mode = mode
|
|
151
|
+
else:
|
|
152
|
+
raise ValueError("invalid printing mode")
|
|
153
|
+
|
|
154
|
+
def allow_negatives(self, neg=None):
|
|
155
|
+
r"""
|
|
156
|
+
Controls whether or not to display a balanced representation.
|
|
157
|
+
|
|
158
|
+
``neg=None`` returns the current value.
|
|
159
|
+
|
|
160
|
+
EXAMPLES::
|
|
161
|
+
|
|
162
|
+
sage: padic_printing.allow_negatives(True)
|
|
163
|
+
sage: padic_printing.allow_negatives()
|
|
164
|
+
True
|
|
165
|
+
sage: Qp(29)(-1)
|
|
166
|
+
-1 + O(29^20)
|
|
167
|
+
sage: Qp(29)(-1000)
|
|
168
|
+
-14 - 5*29 - 29^2 + O(29^20)
|
|
169
|
+
sage: padic_printing.allow_negatives(False)
|
|
170
|
+
"""
|
|
171
|
+
if neg is None:
|
|
172
|
+
return not self._pos
|
|
173
|
+
else:
|
|
174
|
+
self._pos = not neg
|
|
175
|
+
|
|
176
|
+
def max_series_terms(self, max=None):
|
|
177
|
+
r"""
|
|
178
|
+
Controls the maximum number of terms shown when printing in
|
|
179
|
+
``'series'``, ``'digits'`` or ``'bars'`` mode.
|
|
180
|
+
|
|
181
|
+
``max=None`` returns the current value.
|
|
182
|
+
|
|
183
|
+
``max=-1`` encodes 'no limit.'
|
|
184
|
+
|
|
185
|
+
EXAMPLES::
|
|
186
|
+
|
|
187
|
+
sage: padic_printing.max_series_terms(2)
|
|
188
|
+
sage: padic_printing.max_series_terms()
|
|
189
|
+
2
|
|
190
|
+
sage: Qp(31)(1000)
|
|
191
|
+
8 + 31 + ... + O(31^20)
|
|
192
|
+
sage: padic_printing.max_series_terms(-1)
|
|
193
|
+
sage: Qp(37)(100000)
|
|
194
|
+
26 + 37 + 36*37^2 + 37^3 + O(37^20)
|
|
195
|
+
"""
|
|
196
|
+
if max is None:
|
|
197
|
+
return self._max_ram_terms
|
|
198
|
+
else:
|
|
199
|
+
self._max_ram_terms = int(max)
|
|
200
|
+
|
|
201
|
+
def max_unram_terms(self, max=None):
|
|
202
|
+
r"""
|
|
203
|
+
For rings with non-prime residue fields, controls how many
|
|
204
|
+
terms appear in the coefficient of each ``pi^n`` when printing in
|
|
205
|
+
``'series'`` or ``'bar'`` modes.
|
|
206
|
+
|
|
207
|
+
``max=None`` returns the current value.
|
|
208
|
+
|
|
209
|
+
``max=-1`` encodes 'no limit.'
|
|
210
|
+
|
|
211
|
+
EXAMPLES::
|
|
212
|
+
|
|
213
|
+
sage: padic_printing.max_unram_terms(2)
|
|
214
|
+
sage: padic_printing.max_unram_terms()
|
|
215
|
+
2
|
|
216
|
+
sage: Zq(5^6, 5, names='a')([1,2,3,-1])^17 # needs sage.libs.ntl
|
|
217
|
+
(3*a^4 + ... + 3) + (a^5 + ... + a)*5 + (3*a^3 + ... + 2)*5^2 + (3*a^5 + ... + 2)*5^3 + (4*a^5 + ... + 4)*5^4 + O(5^5)
|
|
218
|
+
|
|
219
|
+
sage: padic_printing.max_unram_terms(-1)
|
|
220
|
+
"""
|
|
221
|
+
if max is None:
|
|
222
|
+
return self._max_unram_terms
|
|
223
|
+
else:
|
|
224
|
+
self._max_unram_terms = int(max)
|
|
225
|
+
|
|
226
|
+
def max_poly_terms(self, max=None):
|
|
227
|
+
r"""
|
|
228
|
+
Controls the number of terms appearing when printing
|
|
229
|
+
polynomial representations in ``'terse'`` or ``'val-unit'`` modes.
|
|
230
|
+
|
|
231
|
+
``max=None`` returns the current value.
|
|
232
|
+
|
|
233
|
+
``max=-1`` encodes 'no limit.'
|
|
234
|
+
|
|
235
|
+
EXAMPLES::
|
|
236
|
+
|
|
237
|
+
sage: padic_printing.max_poly_terms(3)
|
|
238
|
+
sage: padic_printing.max_poly_terms()
|
|
239
|
+
3
|
|
240
|
+
sage: padic_printing.mode('terse')
|
|
241
|
+
sage: Zq(7^5, 5, names='a')([2,3,4])^8 # needs sage.libs.ntl
|
|
242
|
+
2570 + 15808*a + 9018*a^2 + ... + O(7^5)
|
|
243
|
+
|
|
244
|
+
sage: padic_printing.max_poly_terms(-1)
|
|
245
|
+
sage: padic_printing.mode('series')
|
|
246
|
+
"""
|
|
247
|
+
if max is None:
|
|
248
|
+
return self._max_terse_terms
|
|
249
|
+
else:
|
|
250
|
+
self._max_terse_terms = int(max)
|
|
251
|
+
|
|
252
|
+
def sep(self, sep=None):
|
|
253
|
+
r"""
|
|
254
|
+
Controls the separator used in ``'bars'`` mode.
|
|
255
|
+
|
|
256
|
+
``sep=None`` returns the current value.
|
|
257
|
+
|
|
258
|
+
EXAMPLES::
|
|
259
|
+
|
|
260
|
+
sage: padic_printing.sep('][')
|
|
261
|
+
sage: padic_printing.sep()
|
|
262
|
+
']['
|
|
263
|
+
sage: padic_printing.mode('bars')
|
|
264
|
+
sage: repr(Qp(61)(-1))
|
|
265
|
+
'...60][60][60][60][60][60][60][60][60][60][60][60][60][60][60][60][60][60][60][60'
|
|
266
|
+
|
|
267
|
+
sage: padic_printing.sep('|')
|
|
268
|
+
sage: padic_printing.mode('series')
|
|
269
|
+
"""
|
|
270
|
+
if sep is None:
|
|
271
|
+
return self._sep
|
|
272
|
+
else:
|
|
273
|
+
self._sep = str(sep)
|
|
274
|
+
|
|
275
|
+
def alphabet(self, alphabet=None):
|
|
276
|
+
r"""
|
|
277
|
+
Controls the alphabet used to translate `p`-adic digits into
|
|
278
|
+
strings (so that no separator need be used in ``'digits'`` mode).
|
|
279
|
+
|
|
280
|
+
``alphabet`` should be passed in as a list or tuple.
|
|
281
|
+
|
|
282
|
+
``alphabet=None`` returns the current value.
|
|
283
|
+
|
|
284
|
+
EXAMPLES::
|
|
285
|
+
|
|
286
|
+
sage: padic_printing.alphabet("abc")
|
|
287
|
+
sage: padic_printing.mode('digits')
|
|
288
|
+
sage: repr(Qp(3)(1234))
|
|
289
|
+
'...bcaacab'
|
|
290
|
+
|
|
291
|
+
sage: padic_printing.mode('series')
|
|
292
|
+
sage: padic_printing.alphabet(('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'))
|
|
293
|
+
"""
|
|
294
|
+
if alphabet is None:
|
|
295
|
+
return self._alphabet
|
|
296
|
+
else:
|
|
297
|
+
self._alphabet = tuple(alphabet)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
_printer_defaults = pAdicPrinterDefaults()
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
cdef class pAdicPrinter_class(SageObject):
|
|
304
|
+
"""
|
|
305
|
+
This class stores the printing options for a specific `p`-adic ring
|
|
306
|
+
or field, and uses these to compute the representations of
|
|
307
|
+
elements.
|
|
308
|
+
"""
|
|
309
|
+
def __init__(self, ring, mode, pos, ram_name, unram_name, var_name, max_ram_terms, max_unram_terms, max_terse_terms, sep, alphabet, show_prec):
|
|
310
|
+
"""
|
|
311
|
+
Initialize a :class:`pAdicPrinter`.
|
|
312
|
+
|
|
313
|
+
INPUT:
|
|
314
|
+
|
|
315
|
+
- ``ring`` -- the ring or field to which this :class:`pAdicPrinter` is
|
|
316
|
+
attached
|
|
317
|
+
|
|
318
|
+
- ``mode`` -- the allowed values for mode are: ``'val-unit'``,
|
|
319
|
+
``'series'``, ``'terse'``, ``'digits'`` and ``'bars'``:
|
|
320
|
+
|
|
321
|
+
- ``'val-unit'`` -- elements are displayed as a power of the
|
|
322
|
+
uniformizer times a unit, which is displayed in terse mode
|
|
323
|
+
|
|
324
|
+
- ``'series'`` -- elements are displayed as power series in the
|
|
325
|
+
uniformizer
|
|
326
|
+
|
|
327
|
+
- ``'terse'`` -- for base rings and fields, elements are just
|
|
328
|
+
displayed as an integer lift. For extensions rings and fields,
|
|
329
|
+
elements are displayed as a polynomial in the generator of the
|
|
330
|
+
extension.
|
|
331
|
+
|
|
332
|
+
- ``'digits'`` -- used only for small primes and totally ramified
|
|
333
|
+
extensions (or trivial extensions), elements are displayed as just
|
|
334
|
+
a string of `p`-adic digits, encoded using the 'alphabet' parameter
|
|
335
|
+
|
|
336
|
+
- ``'bars'`` -- like ``'digits'``, but uses a separator in order to
|
|
337
|
+
print a more canonical representation for each digit. This change
|
|
338
|
+
allows the use of this printing mode for unramified extensions and
|
|
339
|
+
extensions with larger primes.
|
|
340
|
+
|
|
341
|
+
- ``pos`` -- if ``True`` then integers in the range [0,... p-1] will be
|
|
342
|
+
used; if ``False`` integers in the range [(1-p)/2,..., p/2] will be used
|
|
343
|
+
|
|
344
|
+
- ``ram_name`` -- the string used to represent the uniformizer
|
|
345
|
+
|
|
346
|
+
- ``unram_name`` -- the string used to represent the trivial lift of a
|
|
347
|
+
generator of the residue field over the prime field
|
|
348
|
+
|
|
349
|
+
- ``var_name`` -- the string used to represent the user-specified
|
|
350
|
+
generator of this extension ring or field
|
|
351
|
+
|
|
352
|
+
- ``max_ram_terms`` -- controls the maximum number of terms shown when
|
|
353
|
+
printing in ``'series'``, ``'digits'`` or ``'bars'`` mode
|
|
354
|
+
|
|
355
|
+
- ``max_unram_terms`` -- for rings with non-prime residue fields,
|
|
356
|
+
controls how many terms appear in the coefficient of each pi^n when
|
|
357
|
+
printing in ``'series'`` or ``'bar'`` modes
|
|
358
|
+
|
|
359
|
+
- ``max_terse_terms`` -- controls the number of terms appearing when
|
|
360
|
+
printing polynomial representations in ``'terse'`` or ``'val-unit'``
|
|
361
|
+
modes
|
|
362
|
+
|
|
363
|
+
- ``sep`` -- controls the separator used in ``'bars'`` mode
|
|
364
|
+
|
|
365
|
+
- ``alphabet`` -- controls the alphabet used to translate `p`-adic digits
|
|
366
|
+
into strings (so that no separator need be used in ``'digits'`` mode)
|
|
367
|
+
|
|
368
|
+
- ``show_prec`` -- Specify how the precision is printed; it can be
|
|
369
|
+
``'none'``, ``'bigoh'`` or ``'dots'`` (the latter being not available
|
|
370
|
+
for all modes)
|
|
371
|
+
|
|
372
|
+
TESTS::
|
|
373
|
+
|
|
374
|
+
sage: R = Qp(7, print_mode='bars', print_sep='&') # indirect doctest
|
|
375
|
+
|
|
376
|
+
sage: R = Zp(5, print_mode='digits', print_max_terms=10)
|
|
377
|
+
Traceback (most recent call last):
|
|
378
|
+
...
|
|
379
|
+
ValueError: max_ram_terms must be unset when show_prec is 'dots'
|
|
380
|
+
"""
|
|
381
|
+
global _printer_defaults
|
|
382
|
+
self.ring = ring
|
|
383
|
+
self.prime_pow = ring.prime_pow
|
|
384
|
+
from sage.rings.padics.padic_base_generic import pAdicBaseGeneric
|
|
385
|
+
self.base = isinstance(ring, pAdicBaseGeneric)
|
|
386
|
+
if alphabet is None:
|
|
387
|
+
self.alphabet = _printer_defaults._alphabet
|
|
388
|
+
else:
|
|
389
|
+
self.alphabet = alphabet
|
|
390
|
+
# note that self.pos is reset to True if mode == 'digits'
|
|
391
|
+
if pos is None:
|
|
392
|
+
self.pos = _printer_defaults._pos
|
|
393
|
+
else:
|
|
394
|
+
self.pos = pos
|
|
395
|
+
if mode is None:
|
|
396
|
+
mode = _printer_defaults._mode
|
|
397
|
+
if mode == 'val-unit':
|
|
398
|
+
self.mode = val_unit
|
|
399
|
+
elif mode == 'series':
|
|
400
|
+
self.mode = series
|
|
401
|
+
elif mode == 'terse':
|
|
402
|
+
self.mode = terse
|
|
403
|
+
elif mode == 'digits':
|
|
404
|
+
if len(self.alphabet) < self.prime_pow.prime or (not self.base and ring.absolute_f() != 1):
|
|
405
|
+
raise ValueError("digits printing mode only usable for totally ramified extensions with p at most the length of the alphabet (default 62). Try using print_mode = 'bars' instead.")
|
|
406
|
+
else:
|
|
407
|
+
self.mode = digits
|
|
408
|
+
self.pos = True
|
|
409
|
+
elif mode == 'bars':
|
|
410
|
+
self.mode = bars
|
|
411
|
+
else:
|
|
412
|
+
raise ValueError("printing mode must be one of 'val-unit', 'series', 'terse', 'digits' or 'bars'")
|
|
413
|
+
if ram_name is None:
|
|
414
|
+
self.ram_name = ring._uniformizer_print()
|
|
415
|
+
else:
|
|
416
|
+
self.ram_name = ram_name
|
|
417
|
+
if self.ram_name is None:
|
|
418
|
+
self.latex_ram_name = None
|
|
419
|
+
else:
|
|
420
|
+
self.latex_ram_name = latex_variable_name(self.ram_name)
|
|
421
|
+
if unram_name is None:
|
|
422
|
+
self.unram_name = ring._unram_print()
|
|
423
|
+
else:
|
|
424
|
+
self.unram_name = unram_name
|
|
425
|
+
if self.unram_name is None:
|
|
426
|
+
self.latex_unram_name = None
|
|
427
|
+
else:
|
|
428
|
+
self.latex_unram_name = latex_variable_name(self.unram_name)
|
|
429
|
+
if var_name is None:
|
|
430
|
+
self.var_name = ring.variable_name()
|
|
431
|
+
else:
|
|
432
|
+
self.var_name = var_name
|
|
433
|
+
if self.var_name is None:
|
|
434
|
+
self.latex_var_name = None
|
|
435
|
+
else:
|
|
436
|
+
self.latex_var_name = latex_variable_name(self.var_name)
|
|
437
|
+
if sep is None:
|
|
438
|
+
self.sep = _printer_defaults._sep
|
|
439
|
+
else:
|
|
440
|
+
self.sep = sep
|
|
441
|
+
if max_ram_terms is not None:
|
|
442
|
+
self.max_ram_terms = max_ram_terms
|
|
443
|
+
if self.max_ram_terms < -1:
|
|
444
|
+
raise ValueError("max_ram_terms must be positive and fit in a long")
|
|
445
|
+
else:
|
|
446
|
+
self.max_ram_terms = _printer_defaults._max_ram_terms
|
|
447
|
+
if max_unram_terms is not None:
|
|
448
|
+
self.max_unram_terms = max_unram_terms
|
|
449
|
+
if self.max_unram_terms < -1:
|
|
450
|
+
raise ValueError("max_unram_terms must be positive and fit in a long")
|
|
451
|
+
else:
|
|
452
|
+
self.max_unram_terms = _printer_defaults._max_unram_terms
|
|
453
|
+
if max_terse_terms is not None:
|
|
454
|
+
self.max_terse_terms = max_terse_terms
|
|
455
|
+
if self.max_terse_terms < -1:
|
|
456
|
+
raise ValueError("max_terse_terms must be positive and fit in a long")
|
|
457
|
+
else:
|
|
458
|
+
self.max_terse_terms = _printer_defaults._max_terse_terms
|
|
459
|
+
from sage.rings.padics.factory import _canonicalize_show_prec
|
|
460
|
+
self.show_prec = _canonicalize_show_prec(self.ring._prec_type(), mode, show_prec)
|
|
461
|
+
|
|
462
|
+
# Incompatibilities
|
|
463
|
+
if self.show_prec == 'dots' and max_ram_terms >= 0:
|
|
464
|
+
raise ValueError("max_ram_terms must be unset when show_prec is 'dots'")
|
|
465
|
+
|
|
466
|
+
def __reduce__(self):
|
|
467
|
+
"""
|
|
468
|
+
Pickling.
|
|
469
|
+
|
|
470
|
+
TESTS::
|
|
471
|
+
|
|
472
|
+
sage: R = Zp(5, print_mode='bars', print_sep='&'); P = loads(dumps(R._printer))
|
|
473
|
+
sage: R._printer == P
|
|
474
|
+
True
|
|
475
|
+
sage: P._sep()
|
|
476
|
+
'&'
|
|
477
|
+
"""
|
|
478
|
+
return pAdicPrinter, (self.ring,
|
|
479
|
+
{'mode': self._print_mode(),
|
|
480
|
+
'pos': self.pos,
|
|
481
|
+
'ram_name': self.ram_name,
|
|
482
|
+
'unram_name': self.unram_name,
|
|
483
|
+
'var_name': self.var_name,
|
|
484
|
+
'max_ram_terms': self.max_ram_terms,
|
|
485
|
+
'max_unram_terms': self.max_unram_terms,
|
|
486
|
+
'max_terse_terms': self.max_terse_terms,
|
|
487
|
+
'sep':self.sep,
|
|
488
|
+
'alphabet': self.alphabet,
|
|
489
|
+
'show_prec': self.show_prec})
|
|
490
|
+
|
|
491
|
+
def __richcmp__(self, other, op):
|
|
492
|
+
"""
|
|
493
|
+
Comparison.
|
|
494
|
+
|
|
495
|
+
TESTS::
|
|
496
|
+
|
|
497
|
+
sage: R = Zp(5)
|
|
498
|
+
sage: S = Zp(5,print_mode='bars')
|
|
499
|
+
sage: R._printer == S._printer
|
|
500
|
+
False
|
|
501
|
+
"""
|
|
502
|
+
if not isinstance(other, pAdicPrinter_class):
|
|
503
|
+
return NotImplemented
|
|
504
|
+
return self.richcmp_modes(other, op)
|
|
505
|
+
|
|
506
|
+
def richcmp_modes(pAdicPrinter_class self,
|
|
507
|
+
pAdicPrinter_class other, int op):
|
|
508
|
+
"""
|
|
509
|
+
Return a comparison of the printing modes of ``self`` and ``other``.
|
|
510
|
+
|
|
511
|
+
Return 0 if and only if all relevant modes are equal
|
|
512
|
+
(``max_unram_terms`` is irrelevant if the ring is totally ramified
|
|
513
|
+
over the base, for example). This does not check if the rings are
|
|
514
|
+
equal (to prevent infinite recursion in the comparison
|
|
515
|
+
functions of `p`-adic rings), but it does check if the primes
|
|
516
|
+
are the same (since the prime affects whether ``pos`` is
|
|
517
|
+
relevant).
|
|
518
|
+
|
|
519
|
+
EXAMPLES::
|
|
520
|
+
|
|
521
|
+
sage: R = Qp(7, print_mode='digits', print_pos=True)
|
|
522
|
+
sage: S = Qp(7, print_mode='digits', print_pos=False)
|
|
523
|
+
sage: R._printer == S._printer
|
|
524
|
+
True
|
|
525
|
+
sage: R = Qp(7)
|
|
526
|
+
sage: S = Qp(7, print_mode='val-unit')
|
|
527
|
+
sage: R == S
|
|
528
|
+
False
|
|
529
|
+
sage: R._printer < S._printer
|
|
530
|
+
True
|
|
531
|
+
"""
|
|
532
|
+
lx = self.mode
|
|
533
|
+
rx = other.mode
|
|
534
|
+
if lx != rx:
|
|
535
|
+
return richcmp_not_equal(lx, rx, op)
|
|
536
|
+
|
|
537
|
+
p = self.ring.prime()
|
|
538
|
+
q = other.ring.prime()
|
|
539
|
+
if p != q:
|
|
540
|
+
return richcmp_not_equal(p, q, op)
|
|
541
|
+
|
|
542
|
+
if p != 2 and (self.mode == terse or self.mode == series or self.mode == val_unit or self.mode == bars):
|
|
543
|
+
lx = self.pos
|
|
544
|
+
rx = other.pos
|
|
545
|
+
if lx != rx:
|
|
546
|
+
return richcmp_not_equal(lx, rx, op)
|
|
547
|
+
|
|
548
|
+
if self.mode != digits:
|
|
549
|
+
lx = self.ram_name
|
|
550
|
+
rx = other.ram_name
|
|
551
|
+
if lx != rx:
|
|
552
|
+
return richcmp_not_equal(lx, rx, op)
|
|
553
|
+
|
|
554
|
+
if self.mode == bars:
|
|
555
|
+
lx = self.sep
|
|
556
|
+
rx = other.sep
|
|
557
|
+
if lx != rx:
|
|
558
|
+
return richcmp_not_equal(lx, rx, op)
|
|
559
|
+
|
|
560
|
+
if self.mode == digits:
|
|
561
|
+
lx = self.alphabet[:p]
|
|
562
|
+
rx = other.alphabet[:q]
|
|
563
|
+
if lx != rx:
|
|
564
|
+
return richcmp_not_equal(lx, rx, op)
|
|
565
|
+
|
|
566
|
+
if self.mode == series or self.mode == digits or self.mode == bars:
|
|
567
|
+
lx = self.max_ram_terms
|
|
568
|
+
rx = other.max_ram_terms
|
|
569
|
+
if lx != rx:
|
|
570
|
+
return richcmp_not_equal(lx, rx, op)
|
|
571
|
+
|
|
572
|
+
f = max(self.ring.absolute_f(), other.ring.absolute_f())
|
|
573
|
+
|
|
574
|
+
if f > 1 and (self.mode == series or self.mode == bars):
|
|
575
|
+
lx = self.unram_name
|
|
576
|
+
rx = other.unram_name
|
|
577
|
+
if lx != rx:
|
|
578
|
+
return richcmp_not_equal(lx, rx, op)
|
|
579
|
+
|
|
580
|
+
lx = self.max_unram_terms
|
|
581
|
+
rx = other.max_unram_terms
|
|
582
|
+
if lx != rx:
|
|
583
|
+
return richcmp_not_equal(lx, rx, op)
|
|
584
|
+
|
|
585
|
+
f = max(self.ring.relative_degree(), other.ring.relative_degree())
|
|
586
|
+
|
|
587
|
+
if f > 1 and self.mode == terse:
|
|
588
|
+
lx = self.var_name
|
|
589
|
+
rx = other.var_name
|
|
590
|
+
if lx != rx:
|
|
591
|
+
return richcmp_not_equal(lx, rx, op)
|
|
592
|
+
lx = self.max_terse_terms
|
|
593
|
+
rx = other.max_terse_terms
|
|
594
|
+
if lx != rx:
|
|
595
|
+
return richcmp_not_equal(lx, rx, op)
|
|
596
|
+
lx = self.show_prec
|
|
597
|
+
rx = other.show_prec
|
|
598
|
+
if lx != rx:
|
|
599
|
+
return richcmp_not_equal(lx, rx, op)
|
|
600
|
+
|
|
601
|
+
return rich_to_bool(op, 0)
|
|
602
|
+
|
|
603
|
+
def _repr_(self) -> str:
|
|
604
|
+
"""
|
|
605
|
+
Representation of this printer.
|
|
606
|
+
|
|
607
|
+
EXAMPLES::
|
|
608
|
+
|
|
609
|
+
sage: Zp(5)._printer # indirect doctest
|
|
610
|
+
series printer for 5-adic Ring with capped relative precision 20
|
|
611
|
+
"""
|
|
612
|
+
return "%s printer for %s" % (self._print_mode(), self.ring)
|
|
613
|
+
|
|
614
|
+
def __enter__(self):
|
|
615
|
+
"""
|
|
616
|
+
Used for context printing.
|
|
617
|
+
|
|
618
|
+
EXAMPLES::
|
|
619
|
+
|
|
620
|
+
sage: from sage.rings.padics.padic_printing import pAdicPrinter
|
|
621
|
+
sage: R = Zp(5,5); a = R(-1); a
|
|
622
|
+
4 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5)
|
|
623
|
+
sage: with pAdicPrinter(R, {'pos': False}): a
|
|
624
|
+
-1 + O(5^5)
|
|
625
|
+
"""
|
|
626
|
+
self.old = self.ring._printer
|
|
627
|
+
self.ring._printer = self
|
|
628
|
+
|
|
629
|
+
def dict(self):
|
|
630
|
+
"""
|
|
631
|
+
Return a dictionary storing all of ``self``'s printing options.
|
|
632
|
+
|
|
633
|
+
EXAMPLES::
|
|
634
|
+
|
|
635
|
+
sage: D = Zp(5)._printer.dict(); D['sep']
|
|
636
|
+
'|'
|
|
637
|
+
"""
|
|
638
|
+
return {'mode': self._print_mode(), 'pos': self.pos, 'ram_name': self.ram_name, 'unram_name': self.unram_name, 'var_name': self.var_name, 'max_ram_terms': self.max_ram_terms, 'max_unram_terms': self.max_unram_terms, 'max_terse_terms': self.max_terse_terms, 'sep': self.sep, 'alphabet': self.alphabet, 'show_prec': self.show_prec}
|
|
639
|
+
|
|
640
|
+
def __exit__(self, type, value, traceback):
|
|
641
|
+
"""
|
|
642
|
+
Used for context printing.
|
|
643
|
+
|
|
644
|
+
EXAMPLES::
|
|
645
|
+
|
|
646
|
+
sage: from sage.rings.padics.padic_printing import pAdicPrinter
|
|
647
|
+
sage: R = Zp(5,5); a = R(-1); a
|
|
648
|
+
4 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5)
|
|
649
|
+
sage: with pAdicPrinter(R, {'pos': False}): a
|
|
650
|
+
-1 + O(5^5)
|
|
651
|
+
sage: a
|
|
652
|
+
4 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5)
|
|
653
|
+
"""
|
|
654
|
+
self.ring._printer = self.old
|
|
655
|
+
|
|
656
|
+
def _pos(self):
|
|
657
|
+
"""
|
|
658
|
+
Access ``self.pos``.
|
|
659
|
+
|
|
660
|
+
EXAMPLES::
|
|
661
|
+
|
|
662
|
+
sage: R = Zp(5); R._printer._pos()
|
|
663
|
+
True
|
|
664
|
+
"""
|
|
665
|
+
return self.pos
|
|
666
|
+
|
|
667
|
+
def _sep(self):
|
|
668
|
+
"""
|
|
669
|
+
Access ``self.sep``.
|
|
670
|
+
|
|
671
|
+
EXAMPLES::
|
|
672
|
+
|
|
673
|
+
sage: R = Zp(5); R._printer._sep()
|
|
674
|
+
'|'
|
|
675
|
+
"""
|
|
676
|
+
return self.sep
|
|
677
|
+
|
|
678
|
+
def _alphabet(self):
|
|
679
|
+
"""
|
|
680
|
+
Access ``self.pos``.
|
|
681
|
+
|
|
682
|
+
EXAMPLES::
|
|
683
|
+
|
|
684
|
+
sage: R = Zp(17, print_mode='digits'); R._printer._alphabet()
|
|
685
|
+
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G')
|
|
686
|
+
"""
|
|
687
|
+
return self.alphabet
|
|
688
|
+
|
|
689
|
+
def _max_ram_terms(self):
|
|
690
|
+
"""
|
|
691
|
+
Access ``self.max_ram_terms``.
|
|
692
|
+
|
|
693
|
+
EXAMPLES::
|
|
694
|
+
|
|
695
|
+
sage: R = Zp(5); R._printer._max_ram_terms()
|
|
696
|
+
-1
|
|
697
|
+
"""
|
|
698
|
+
return self.max_ram_terms
|
|
699
|
+
|
|
700
|
+
def _max_unram_terms(self):
|
|
701
|
+
"""
|
|
702
|
+
Access ``self.max_unram_terms``.
|
|
703
|
+
|
|
704
|
+
EXAMPLES::
|
|
705
|
+
|
|
706
|
+
sage: R = Zp(5); R._printer._max_unram_terms()
|
|
707
|
+
-1
|
|
708
|
+
"""
|
|
709
|
+
return self.max_unram_terms
|
|
710
|
+
|
|
711
|
+
def _max_terse_terms(self):
|
|
712
|
+
"""
|
|
713
|
+
Access ``self.max_terse_terms``.
|
|
714
|
+
|
|
715
|
+
EXAMPLES::
|
|
716
|
+
|
|
717
|
+
sage: R = Zp(5); R._printer._max_terse_terms()
|
|
718
|
+
-1
|
|
719
|
+
"""
|
|
720
|
+
return self.max_terse_terms
|
|
721
|
+
|
|
722
|
+
def _show_prec(self):
|
|
723
|
+
"""
|
|
724
|
+
Access ``self.show_prec``.
|
|
725
|
+
|
|
726
|
+
EXAMPLES::
|
|
727
|
+
|
|
728
|
+
sage: R = ZpFP(5); R._printer._show_prec()
|
|
729
|
+
'none'
|
|
730
|
+
"""
|
|
731
|
+
return self.show_prec
|
|
732
|
+
|
|
733
|
+
def _ring(self):
|
|
734
|
+
"""
|
|
735
|
+
Access ``self.ring``.
|
|
736
|
+
|
|
737
|
+
EXAMPLES::
|
|
738
|
+
|
|
739
|
+
sage: R = Zp(5,5); R._printer._ring()
|
|
740
|
+
5-adic Ring with capped relative precision 5
|
|
741
|
+
"""
|
|
742
|
+
return self.ring
|
|
743
|
+
|
|
744
|
+
def _uniformizer_name(self):
|
|
745
|
+
"""
|
|
746
|
+
Access ``self.ram_name``.
|
|
747
|
+
|
|
748
|
+
EXAMPLES::
|
|
749
|
+
|
|
750
|
+
sage: R = Zp(5,5); R._printer._uniformizer_name()
|
|
751
|
+
'5'
|
|
752
|
+
"""
|
|
753
|
+
return self.ram_name
|
|
754
|
+
|
|
755
|
+
def _ram_name(self):
|
|
756
|
+
"""
|
|
757
|
+
Access ``self.ram_name``.
|
|
758
|
+
|
|
759
|
+
EXAMPLES::
|
|
760
|
+
|
|
761
|
+
sage: R = Zp(5,5); R._printer._ram_name()
|
|
762
|
+
'5'
|
|
763
|
+
"""
|
|
764
|
+
return self.ram_name
|
|
765
|
+
|
|
766
|
+
def _print_mode(self):
|
|
767
|
+
"""
|
|
768
|
+
Access ``self.mode``.
|
|
769
|
+
|
|
770
|
+
EXAMPLES::
|
|
771
|
+
|
|
772
|
+
sage: R = Zp(5); R._printer._print_mode()
|
|
773
|
+
'series'
|
|
774
|
+
"""
|
|
775
|
+
if self.mode == val_unit:
|
|
776
|
+
return 'val-unit'
|
|
777
|
+
elif self.mode == series:
|
|
778
|
+
return 'series'
|
|
779
|
+
elif self.mode == terse:
|
|
780
|
+
return 'terse'
|
|
781
|
+
elif self.mode == digits:
|
|
782
|
+
return 'digits'
|
|
783
|
+
elif self.mode == bars:
|
|
784
|
+
return 'bars'
|
|
785
|
+
|
|
786
|
+
def _base_p_list(self, value, pos):
|
|
787
|
+
"""
|
|
788
|
+
Return a list of integers forming the base p expansion of value.
|
|
789
|
+
|
|
790
|
+
If pos is True, these integers will be in the range
|
|
791
|
+
[0,..., p-1]; if pos is False, they will be in the range
|
|
792
|
+
[(1-p)/2,..., p/2].
|
|
793
|
+
|
|
794
|
+
The first entry will be the coefficient of p^0, etc.
|
|
795
|
+
|
|
796
|
+
EXAMPLES::
|
|
797
|
+
|
|
798
|
+
sage: P = Zp(17)._printer
|
|
799
|
+
sage: P._base_p_list(1298734,True)
|
|
800
|
+
[2, 15, 5, 9, 15]
|
|
801
|
+
sage: P._base_p_list(1298734,False)
|
|
802
|
+
[2, -2, 6, -8, -1, 1]
|
|
803
|
+
sage: P._base_p_list(Zp(17)(1298734),True)
|
|
804
|
+
[2, 15, 5, 9, 15]
|
|
805
|
+
sage: P._base_p_list(Zp(17)(1298734),False)
|
|
806
|
+
[2, -2, 6, -8, -1, 1]
|
|
807
|
+
"""
|
|
808
|
+
return self.base_p_list(value, pos)
|
|
809
|
+
|
|
810
|
+
cdef base_p_list(self, value, bint pos):
|
|
811
|
+
"""
|
|
812
|
+
Return a list of integers forming the base p expansion of value.
|
|
813
|
+
|
|
814
|
+
If pos is True, these integers will be in the range
|
|
815
|
+
[0,... p-1]; if po is False, they will be in the range
|
|
816
|
+
[(1-p)/2,..., p/2].
|
|
817
|
+
|
|
818
|
+
The first entry will be the coefficient of p^0, etc.
|
|
819
|
+
|
|
820
|
+
EXAMPLES::
|
|
821
|
+
|
|
822
|
+
sage: P = Zp(17)._printer
|
|
823
|
+
sage: P._base_p_list(1298734,True) # indirect doctest
|
|
824
|
+
[2, 15, 5, 9, 15]
|
|
825
|
+
sage: P._base_p_list(1298734,False)
|
|
826
|
+
[2, -2, 6, -8, -1, 1]
|
|
827
|
+
"""
|
|
828
|
+
if isinstance(value, Integer):
|
|
829
|
+
from sage.rings.padics.padic_capped_relative_element import base_p_list
|
|
830
|
+
return base_p_list(value, pos, self.prime_pow)
|
|
831
|
+
elif pos:
|
|
832
|
+
return trim_zeros(list(value.unit_part().expansion()))
|
|
833
|
+
else:
|
|
834
|
+
return trim_zeros(list(value.unit_part().expansion(lift_mode='smallest')))
|
|
835
|
+
|
|
836
|
+
def repr_gen(self, elt, do_latex, pos=None, mode=None, ram_name=None):
|
|
837
|
+
"""
|
|
838
|
+
The entry point for printing an element.
|
|
839
|
+
|
|
840
|
+
INPUT:
|
|
841
|
+
|
|
842
|
+
- ``elt`` -- a `p`-adic element of the appropriate ring to print
|
|
843
|
+
|
|
844
|
+
- ``do_latex`` -- whether to return a latex representation or
|
|
845
|
+
a normal one
|
|
846
|
+
|
|
847
|
+
EXAMPLES::
|
|
848
|
+
|
|
849
|
+
sage: R = Zp(5,5); P = R._printer; a = R(-5); a
|
|
850
|
+
4*5 + 4*5^2 + 4*5^3 + 4*5^4 + 4*5^5 + O(5^6)
|
|
851
|
+
sage: P.repr_gen(a, False, pos=False)
|
|
852
|
+
'-5 + O(5^6)'
|
|
853
|
+
sage: P.repr_gen(a, False, ram_name='p')
|
|
854
|
+
'4*p + 4*p^2 + 4*p^3 + 4*p^4 + 4*p^5 + O(p^6)'
|
|
855
|
+
"""
|
|
856
|
+
cdef int _mode
|
|
857
|
+
cdef bint _pos
|
|
858
|
+
if mode is None:
|
|
859
|
+
_mode = self.mode
|
|
860
|
+
elif mode == 'val-unit':
|
|
861
|
+
_mode = val_unit
|
|
862
|
+
elif mode == 'series':
|
|
863
|
+
_mode = series
|
|
864
|
+
elif mode == 'terse':
|
|
865
|
+
_mode = terse
|
|
866
|
+
elif mode == 'digits':
|
|
867
|
+
_mode = digits
|
|
868
|
+
elif mode == 'bars':
|
|
869
|
+
_mode = bars
|
|
870
|
+
else:
|
|
871
|
+
raise ValueError("printing mode must be one of 'val-unit', 'series', 'terse', 'bars', or 'digits'")
|
|
872
|
+
if pos is None:
|
|
873
|
+
_pos = self.pos
|
|
874
|
+
else:
|
|
875
|
+
_pos = pos
|
|
876
|
+
if ram_name is None:
|
|
877
|
+
if do_latex:
|
|
878
|
+
pprint = self.latex_ram_name
|
|
879
|
+
else:
|
|
880
|
+
pprint = self.ram_name
|
|
881
|
+
else:
|
|
882
|
+
pprint = str(ram_name)
|
|
883
|
+
if do_latex:
|
|
884
|
+
pprint = latex_variable_name(pprint)
|
|
885
|
+
return self._repr_gen(elt, do_latex, _pos, _mode, pprint)
|
|
886
|
+
|
|
887
|
+
cdef _repr_gen(self, pAdicGenericElement elt, bint do_latex, bint pos, int mode, ram_name):
|
|
888
|
+
r"""
|
|
889
|
+
Print a string representation of the element. See ``__init__`` for
|
|
890
|
+
more details on print modes.
|
|
891
|
+
|
|
892
|
+
EXAMPLES::
|
|
893
|
+
|
|
894
|
+
sage: R = Zp(7,4,'capped-rel','val-unit'); a = R(364); a # indirect doctest
|
|
895
|
+
7 * 52 + O(7^5)
|
|
896
|
+
sage: print(a.str('terse'))
|
|
897
|
+
364 + O(7^5)
|
|
898
|
+
sage: print(a.str('series'))
|
|
899
|
+
3*7 + 7^3 + O(7^5)
|
|
900
|
+
sage: K = Qp(7,4,'capped-rel','val-unit'); a = K(364); a
|
|
901
|
+
7 * 52 + O(7^5)
|
|
902
|
+
sage: print(a.str('series'))
|
|
903
|
+
3*7 + 7^3 + O(7^5)
|
|
904
|
+
sage: padic_printing.sep('')
|
|
905
|
+
sage: K = Qp(7, print_mode='digits')
|
|
906
|
+
sage: repr(K(1/2))
|
|
907
|
+
'...33333333333333333334'
|
|
908
|
+
sage: repr(K(1/42))
|
|
909
|
+
'...5555555555555555555.6'
|
|
910
|
+
sage: padic_printing.sep('|')
|
|
911
|
+
sage: repr(Qp(97, print_mode='bars')(1/13))
|
|
912
|
+
'...29|82|7|44|74|59|67|14|89|52|22|37|29|82|7|44|74|59|67|15'
|
|
913
|
+
|
|
914
|
+
TESTS:
|
|
915
|
+
|
|
916
|
+
Check that :issue:`24843` is resolved::
|
|
917
|
+
|
|
918
|
+
sage: R = Zp(2, print_mode='digits', show_prec=True)
|
|
919
|
+
sage: repr(R(0,10))
|
|
920
|
+
'...0000000000'
|
|
921
|
+
"""
|
|
922
|
+
s = ""
|
|
923
|
+
if self.show_prec == "dots":
|
|
924
|
+
unknown_digit = "?"
|
|
925
|
+
else:
|
|
926
|
+
unknown_digit = "0"
|
|
927
|
+
if elt._is_exact_zero():
|
|
928
|
+
return "0"
|
|
929
|
+
elif elt._is_inexact_zero():
|
|
930
|
+
prec = elt.precision_absolute()
|
|
931
|
+
if mode == digits and self.show_prec == "dots":
|
|
932
|
+
if prec > 0:
|
|
933
|
+
s = (self.alphabet[0] * prec)
|
|
934
|
+
else:
|
|
935
|
+
s = unknown_digit + "." + (unknown_digit * (-prec)) + self.alphabet[0]
|
|
936
|
+
elif mode == bars and self.show_prec == "dots":
|
|
937
|
+
if self.base or self._ring().absolute_f() == 1:
|
|
938
|
+
zero = '0'
|
|
939
|
+
else:
|
|
940
|
+
zero = '[]'
|
|
941
|
+
if prec > 0:
|
|
942
|
+
L = [zero] * prec
|
|
943
|
+
s = self.sep.join(L)
|
|
944
|
+
else:
|
|
945
|
+
L = ['.'] + ([unknown_digit] * (-prec)) + [zero]
|
|
946
|
+
s = self.sep + self.sep.join(L)
|
|
947
|
+
elif mode == val_unit:
|
|
948
|
+
if do_latex:
|
|
949
|
+
if elt.valuation() == 0:
|
|
950
|
+
s = self._repr_spec(elt, do_latex, pos, terse, 0, ram_name)
|
|
951
|
+
elif elt.valuation() == 1:
|
|
952
|
+
s = "%s \\cdot %s" % (ram_name, self._repr_spec(elt.unit_part(), do_latex, pos, terse, 1, ram_name))
|
|
953
|
+
else:
|
|
954
|
+
s = "%s^{%s} \\cdot %s" % (ram_name, elt.valuation(), self._repr_spec(elt.unit_part(), do_latex, pos, terse, 1, ram_name))
|
|
955
|
+
else:
|
|
956
|
+
if elt.valuation() == 0:
|
|
957
|
+
s = self._repr_spec(elt, do_latex, pos, terse, 0, ram_name)
|
|
958
|
+
elif elt.valuation() == 1:
|
|
959
|
+
s = "%s * %s" % (ram_name, self._repr_spec(elt.unit_part(), do_latex, pos, terse, 1, ram_name))
|
|
960
|
+
else:
|
|
961
|
+
s = "%s^%s * %s" % (ram_name, elt.valuation(), self._repr_spec(elt.unit_part(), do_latex, pos, terse, 1, ram_name))
|
|
962
|
+
elif mode == digits:
|
|
963
|
+
n = elt.valuation()
|
|
964
|
+
if self.base:
|
|
965
|
+
L = self.base_p_list(elt, True)
|
|
966
|
+
else:
|
|
967
|
+
L = elt._ext_p_list(True)
|
|
968
|
+
if self.max_ram_terms == -1:
|
|
969
|
+
lenL = elt.precision_relative()
|
|
970
|
+
else:
|
|
971
|
+
lenL = min(elt.precision_relative(), max(self.max_ram_terms, -n))
|
|
972
|
+
if self.show_prec == "dots":
|
|
973
|
+
if len(L) < lenL:
|
|
974
|
+
L += [0] * (lenL - len(L))
|
|
975
|
+
if len(L) > lenL:
|
|
976
|
+
L = L[:lenL]
|
|
977
|
+
L.reverse()
|
|
978
|
+
# The following step should work since mode is only allowed to be digits in the case of totally ramified extensions
|
|
979
|
+
# with primes smaller than the length of the alphabet
|
|
980
|
+
L = [self.alphabet[a] for a in L]
|
|
981
|
+
if n > 0:
|
|
982
|
+
L += [self.alphabet[0]]*n
|
|
983
|
+
elif n < 0:
|
|
984
|
+
L = [unknown_digit]*(1 - n - lenL) + L
|
|
985
|
+
L = L[:n] + ['.'] + L[n:]
|
|
986
|
+
s = "".join(L)
|
|
987
|
+
elif mode == bars:
|
|
988
|
+
n = elt.valuation()
|
|
989
|
+
if self.base:
|
|
990
|
+
L = self.base_p_list(elt, self.pos)
|
|
991
|
+
else:
|
|
992
|
+
L = elt._ext_p_list(self.pos)
|
|
993
|
+
if self.max_ram_terms == -1:
|
|
994
|
+
lenL = elt.precision_relative()
|
|
995
|
+
else:
|
|
996
|
+
lenL = min(elt.precision_relative(), max(self.max_ram_terms, -n))
|
|
997
|
+
if self.show_prec == "dots":
|
|
998
|
+
if len(L) < lenL:
|
|
999
|
+
if self.base or self._ring().absolute_f() == 1:
|
|
1000
|
+
L += [0]*(lenL - len(L))
|
|
1001
|
+
else:
|
|
1002
|
+
L += [[]]*(lenL - len(L))
|
|
1003
|
+
if len(L) > lenL:
|
|
1004
|
+
L = L[:lenL]
|
|
1005
|
+
L.reverse()
|
|
1006
|
+
if self.base or self._ring().absolute_f() == 1 or self.max_unram_terms == -1:
|
|
1007
|
+
L = [str(a) for a in L]
|
|
1008
|
+
else:
|
|
1009
|
+
if self.max_unram_terms == 0:
|
|
1010
|
+
L = ['[...]' if len(a) > 0 else '[]' for a in L]
|
|
1011
|
+
elif self.max_unram_terms == 1:
|
|
1012
|
+
L = ["[..., %s]" % (a[-1]) if len(a) > 1 else str(a) for a in L]
|
|
1013
|
+
else:
|
|
1014
|
+
L = ["[%s,..., " % (a[0]) + ", ".join(str(b) for b in a[1-self.max_unram_terms:]) + "]" if len(a) > 2 else str(a) for a in L]
|
|
1015
|
+
if n > 0:
|
|
1016
|
+
if self.base or self._ring().absolute_f() == 1:
|
|
1017
|
+
L += ['0']*n
|
|
1018
|
+
else:
|
|
1019
|
+
L += ['[]']*n
|
|
1020
|
+
elif n < 0:
|
|
1021
|
+
L = ['0']*(min(-n, elt.precision_relative()) - len(L)) + L
|
|
1022
|
+
L = [unknown_digit]*(-n - len(L)) + L
|
|
1023
|
+
L = L[:n] + ['.'] + L[n:]
|
|
1024
|
+
if L[0] == '.':
|
|
1025
|
+
s = self.sep + self.sep.join(L)
|
|
1026
|
+
else:
|
|
1027
|
+
s = self.sep.join(L)
|
|
1028
|
+
else: # mode == terse or series
|
|
1029
|
+
s = self._repr_spec(elt, do_latex, pos, mode, 0, ram_name)
|
|
1030
|
+
|
|
1031
|
+
if self.show_prec == "dots":
|
|
1032
|
+
s = "..." + s
|
|
1033
|
+
if self.show_prec == "bigoh":
|
|
1034
|
+
if s == "":
|
|
1035
|
+
s = "O(%s" % ram_name
|
|
1036
|
+
else:
|
|
1037
|
+
s += " + O(%s" % ram_name
|
|
1038
|
+
if elt.precision_absolute() == 1:
|
|
1039
|
+
s += ")"
|
|
1040
|
+
else:
|
|
1041
|
+
if do_latex:
|
|
1042
|
+
s += "^{%s})" % (elt.precision_absolute())
|
|
1043
|
+
else:
|
|
1044
|
+
s += "^%s)" % (elt.precision_absolute())
|
|
1045
|
+
if s == "": s = "0"
|
|
1046
|
+
return s
|
|
1047
|
+
|
|
1048
|
+
cdef _repr_spec(self, pAdicGenericElement elt, bint do_latex, bint pos, int mode, bint paren, ram_name):
|
|
1049
|
+
"""
|
|
1050
|
+
A function used by repr_gen for terse and series printing.
|
|
1051
|
+
|
|
1052
|
+
Should not be called if elt is an exact or inexact zero.
|
|
1053
|
+
"""
|
|
1054
|
+
cdef Integer lift_z, pprec
|
|
1055
|
+
cdef int ZZ_pEX
|
|
1056
|
+
cdef Py_ssize_t i
|
|
1057
|
+
cdef long val
|
|
1058
|
+
cdef bint integral
|
|
1059
|
+
var_name = self.latex_var_name if do_latex else self.var_name
|
|
1060
|
+
if self.base:
|
|
1061
|
+
if mode == terse:
|
|
1062
|
+
v = elt.valuation()
|
|
1063
|
+
if v >= 0:
|
|
1064
|
+
lift_z = <Integer> elt.lift()
|
|
1065
|
+
pprec = self.prime_pow.pow_Integer(mpz_get_ui((<Integer>elt.precision_absolute()).value))
|
|
1066
|
+
else:
|
|
1067
|
+
lift_z = <Integer> elt.unit_part().lift()
|
|
1068
|
+
pprec = self.prime_pow.pow_Integer(mpz_get_ui((<Integer>elt.precision_relative()).value))
|
|
1069
|
+
mpz_mod(lift_z.value, lift_z.value, pprec.value)
|
|
1070
|
+
if not pos:
|
|
1071
|
+
if lift_z > pprec / 2:
|
|
1072
|
+
mpz_sub(lift_z.value, lift_z.value, pprec.value)
|
|
1073
|
+
else:
|
|
1074
|
+
paren = 0
|
|
1075
|
+
else:
|
|
1076
|
+
paren = 0
|
|
1077
|
+
# if v>=0, _terse_frac only uses the first input.
|
|
1078
|
+
# if v<0, _terse_frac doesn't use the first input at all, and expects the unit part in the third input.
|
|
1079
|
+
s = self._terse_frac(lift_z, v, lift_z, ram_name, do_latex)
|
|
1080
|
+
if paren and not do_latex:
|
|
1081
|
+
return "(%s)" % (s)
|
|
1082
|
+
else:
|
|
1083
|
+
return s
|
|
1084
|
+
else: # mode == series
|
|
1085
|
+
slist = self.base_p_list(elt, pos)
|
|
1086
|
+
slist, ellipsis = self._truncate_list(slist, self.max_ram_terms, 0)
|
|
1087
|
+
s = ""
|
|
1088
|
+
exp = elt.valuation()
|
|
1089
|
+
for a in slist:
|
|
1090
|
+
if a != 0:
|
|
1091
|
+
if a < 0:
|
|
1092
|
+
if len(s) == 0:
|
|
1093
|
+
s = "-"
|
|
1094
|
+
else:
|
|
1095
|
+
s += " - "
|
|
1096
|
+
a = -a
|
|
1097
|
+
elif len(s) != 0:
|
|
1098
|
+
s += " + "
|
|
1099
|
+
s += self._co_dot_var(a, ram_name, exp, do_latex)
|
|
1100
|
+
exp += 1
|
|
1101
|
+
if ellipsis:
|
|
1102
|
+
s += self._plus_ellipsis(do_latex)
|
|
1103
|
+
else: # not self.base
|
|
1104
|
+
if mode == terse:
|
|
1105
|
+
if elt.parent()._implementation == 'FLINT':
|
|
1106
|
+
poly, k = elt._flint_rep_abs()
|
|
1107
|
+
L = [repr(a) for a in poly.coefficients(sparse=False)]
|
|
1108
|
+
ZZ_pEX = 1
|
|
1109
|
+
elif elt.parent()._implementation == 'Polynomial':
|
|
1110
|
+
poly = elt._poly_rep()
|
|
1111
|
+
if do_latex:
|
|
1112
|
+
L = [a._latex_() for a in poly.coefficients(sparse=False)]
|
|
1113
|
+
else:
|
|
1114
|
+
L = [repr(a) for a in poly.coefficients(sparse=False)]
|
|
1115
|
+
L, ellipsis = self._truncate_list(L, self.max_terse_terms, '0')
|
|
1116
|
+
s = ''
|
|
1117
|
+
for i, a in enumerate(L):
|
|
1118
|
+
if a == '0':
|
|
1119
|
+
continue
|
|
1120
|
+
if (i > 0) and ('+' in a or '-' in a[1:]):
|
|
1121
|
+
a = '(' + a + ')'
|
|
1122
|
+
if a[0] == '-':
|
|
1123
|
+
if s:
|
|
1124
|
+
s += ' - '
|
|
1125
|
+
else:
|
|
1126
|
+
s = '-'
|
|
1127
|
+
if a[1:] == '1':
|
|
1128
|
+
s += self._var(var_name, i, do_latex)
|
|
1129
|
+
else:
|
|
1130
|
+
s += a[1:] + self._dot_var(var_name, i, do_latex)
|
|
1131
|
+
else:
|
|
1132
|
+
if s:
|
|
1133
|
+
s += ' + '
|
|
1134
|
+
if a == '1':
|
|
1135
|
+
s += self._var(var_name, i, do_latex)
|
|
1136
|
+
else:
|
|
1137
|
+
s += a + self._dot_var(var_name, i, do_latex)
|
|
1138
|
+
if ellipsis:
|
|
1139
|
+
s += self._plus_ellipsis(do_latex)
|
|
1140
|
+
if paren and ' ' in s:
|
|
1141
|
+
s = '(' + s + ')'
|
|
1142
|
+
return s
|
|
1143
|
+
else:
|
|
1144
|
+
if elt.parent().is_capped_relative():
|
|
1145
|
+
poly, k = elt._ntl_rep_abs()
|
|
1146
|
+
s = repr(poly)
|
|
1147
|
+
else:
|
|
1148
|
+
s = repr(elt._ntl_rep())
|
|
1149
|
+
k = 0
|
|
1150
|
+
L = s.split("] [") # this splits a ZZ_pEX into the ZZ_pX components
|
|
1151
|
+
ZZ_pEX = L[0].count("[") # will equal 2 if elt was a ZZ_pEX element, 1 if it was a ZZ_pX element
|
|
1152
|
+
L[0] = L[0].replace("[","")
|
|
1153
|
+
L[-1] = L[-1].replace("]","")
|
|
1154
|
+
L = L[0].split()
|
|
1155
|
+
if ZZ_pEX == 2:
|
|
1156
|
+
L = [a.split() for a in L]
|
|
1157
|
+
L = [[("" if b == "0" else b) for b in a] for a in L]
|
|
1158
|
+
L, ellipsis = self._truncate_list(L, self.max_ram_terms, "")
|
|
1159
|
+
raise NotImplementedError
|
|
1160
|
+
else:
|
|
1161
|
+
L = [("" if b == "0" else b) for b in L]
|
|
1162
|
+
L, ellipsis = self._truncate_list(L, self.max_terse_terms, "")
|
|
1163
|
+
s = ""
|
|
1164
|
+
pn = self.prime_pow.pow_Integer(mpz_get_ui((<Integer>(elt.precision_absolute()-k)).value))
|
|
1165
|
+
if elt.parent().is_capped_relative():
|
|
1166
|
+
pk = self.prime_pow.pow_Integer(mpz_get_ui((<Integer>-k).value))
|
|
1167
|
+
if k >= 0:
|
|
1168
|
+
integral = True
|
|
1169
|
+
else:
|
|
1170
|
+
integral = False
|
|
1171
|
+
else:
|
|
1172
|
+
pk = Integer(1)
|
|
1173
|
+
integral = True
|
|
1174
|
+
for i from 0 <= i < len(L):
|
|
1175
|
+
if L[i] != "":
|
|
1176
|
+
a = Integer(L[i])
|
|
1177
|
+
if not pos and 2*a > pn:
|
|
1178
|
+
if integral:
|
|
1179
|
+
arep = pn - a
|
|
1180
|
+
else:
|
|
1181
|
+
a = (pn - a) / pk
|
|
1182
|
+
v, u = a.val_unit(self.prime_pow.prime)
|
|
1183
|
+
arep = self._terse_frac(a, v, u, ram_name, do_latex)
|
|
1184
|
+
if s == "":
|
|
1185
|
+
s = "-%s" % (arep)
|
|
1186
|
+
s += self._dot_var(var_name, i, do_latex)
|
|
1187
|
+
elif a == 1:
|
|
1188
|
+
s += " - "
|
|
1189
|
+
s += self._var(var_name, i, do_latex)
|
|
1190
|
+
else:
|
|
1191
|
+
s += " - %s" % (arep)
|
|
1192
|
+
s += self._dot_var(var_name, i, do_latex)
|
|
1193
|
+
elif a == pk:
|
|
1194
|
+
if s:
|
|
1195
|
+
s += " + "
|
|
1196
|
+
s += self._var(var_name, i, do_latex)
|
|
1197
|
+
else:
|
|
1198
|
+
a = a / pk
|
|
1199
|
+
v, u = a.val_unit(self.prime_pow.prime)
|
|
1200
|
+
arep = self._terse_frac(a, v, u, ram_name, do_latex)
|
|
1201
|
+
if s == "":
|
|
1202
|
+
s = "%s" % arep
|
|
1203
|
+
else:
|
|
1204
|
+
s += " + %s" % arep
|
|
1205
|
+
s += self._dot_var(var_name, i, do_latex)
|
|
1206
|
+
if ellipsis:
|
|
1207
|
+
s += self._plus_ellipsis(do_latex)
|
|
1208
|
+
else: # series
|
|
1209
|
+
s = ""
|
|
1210
|
+
L = elt._ext_p_list(pos)
|
|
1211
|
+
val = elt.valuation_c()
|
|
1212
|
+
# since elt was not supposed to be zero, this should give a non-empty list.
|
|
1213
|
+
if len(L) == 0:
|
|
1214
|
+
raise RuntimeError("repr_spec called on zero")
|
|
1215
|
+
R = elt.parent()
|
|
1216
|
+
f = R.absolute_f()
|
|
1217
|
+
if f > 1: # unramified part to the extension
|
|
1218
|
+
if self.unram_name is None:
|
|
1219
|
+
raise RuntimeError("need to have specified a name for the unramified variable")
|
|
1220
|
+
L, ellipsis = self._truncate_list(L, self.max_ram_terms, [])
|
|
1221
|
+
for i from 0 <= i < len(L):
|
|
1222
|
+
unram_name = self.latex_unram_name if do_latex else self.unram_name
|
|
1223
|
+
term = self._print_unram_term(L[i], do_latex, unram_name, self.max_unram_terms, 0, 0)
|
|
1224
|
+
if len(term) > 0:
|
|
1225
|
+
exp = i + val
|
|
1226
|
+
if (not do_latex and term.find(" ") != -1) or (do_latex and (term.find(" + ") != -1 or term.find(" - ") != -1)):
|
|
1227
|
+
if len(s) > 0:
|
|
1228
|
+
s += " + (" + term + ")"
|
|
1229
|
+
else:
|
|
1230
|
+
s = "(" + term + ")"
|
|
1231
|
+
s += self._dot_var(ram_name, exp, do_latex)
|
|
1232
|
+
else: # since len(term) > 0, len(L[i]) == 1.
|
|
1233
|
+
if term == "1":
|
|
1234
|
+
if len(s) > 0:
|
|
1235
|
+
s += " + "
|
|
1236
|
+
s += self._var(ram_name, exp, do_latex)
|
|
1237
|
+
continue
|
|
1238
|
+
elif term == "-1":
|
|
1239
|
+
if len(s) > 0:
|
|
1240
|
+
s += " - "
|
|
1241
|
+
else:
|
|
1242
|
+
s = "-"
|
|
1243
|
+
s += self._var(ram_name, exp, do_latex)
|
|
1244
|
+
continue
|
|
1245
|
+
elif len(s) > 0:
|
|
1246
|
+
if term[0] == "-":
|
|
1247
|
+
s += " - " + term[1:]
|
|
1248
|
+
else:
|
|
1249
|
+
s += " + " + term
|
|
1250
|
+
s += self._dot_var(ram_name, exp, do_latex)
|
|
1251
|
+
else:
|
|
1252
|
+
s = term
|
|
1253
|
+
s += self._dot_var(ram_name, exp, do_latex)
|
|
1254
|
+
if ellipsis:
|
|
1255
|
+
s += self._plus_ellipsis(do_latex)
|
|
1256
|
+
else: # f = 1, so no unramified printing required
|
|
1257
|
+
L, ellipsis = self._truncate_list(L, self.max_ram_terms, 0)
|
|
1258
|
+
s = self._print_list_as_poly(L, do_latex, ram_name, val, 1)
|
|
1259
|
+
if ellipsis:
|
|
1260
|
+
s += self._plus_ellipsis(do_latex)
|
|
1261
|
+
if paren and s.find(" ") != -1:
|
|
1262
|
+
s = "(" + s + ")"
|
|
1263
|
+
return s
|
|
1264
|
+
|
|
1265
|
+
cdef _var(self, x, exp, do_latex):
|
|
1266
|
+
"""
|
|
1267
|
+
Return a representation of 'x^exp', latexed if necessary.
|
|
1268
|
+
"""
|
|
1269
|
+
if exp == 0:
|
|
1270
|
+
return "1"
|
|
1271
|
+
if exp == 1:
|
|
1272
|
+
return str(x)
|
|
1273
|
+
if do_latex:
|
|
1274
|
+
return "%s^{%s}" % (x, exp)
|
|
1275
|
+
else:
|
|
1276
|
+
return "%s^%s" % (x, exp)
|
|
1277
|
+
|
|
1278
|
+
cdef _dot_var(self, x, exp, do_latex):
|
|
1279
|
+
"""
|
|
1280
|
+
Return a representation of '*x^exp', latexed if necessary.
|
|
1281
|
+
"""
|
|
1282
|
+
if exp == 0:
|
|
1283
|
+
return ""
|
|
1284
|
+
if exp == 1:
|
|
1285
|
+
if do_latex:
|
|
1286
|
+
return " \\cdot %s" % (x)
|
|
1287
|
+
else:
|
|
1288
|
+
return "*%s" % (x)
|
|
1289
|
+
if do_latex:
|
|
1290
|
+
return " \\cdot %s^{%s}" % (x, exp)
|
|
1291
|
+
else:
|
|
1292
|
+
return "*%s^%s" % (x, exp)
|
|
1293
|
+
|
|
1294
|
+
cdef _co_dot_var(self, co, x, exp, do_latex):
|
|
1295
|
+
"""
|
|
1296
|
+
Return a representation of 'co*x^exp', latexed if necessary.
|
|
1297
|
+
|
|
1298
|
+
co should be greater than 0
|
|
1299
|
+
"""
|
|
1300
|
+
if exp == 0:
|
|
1301
|
+
return "%s" % co
|
|
1302
|
+
if exp == 1:
|
|
1303
|
+
if co == 1:
|
|
1304
|
+
return "%s" % x
|
|
1305
|
+
if do_latex:
|
|
1306
|
+
return "%s \\cdot %s" % (co, x)
|
|
1307
|
+
else:
|
|
1308
|
+
return "%s*%s" % (co, x)
|
|
1309
|
+
if co == 1:
|
|
1310
|
+
if do_latex:
|
|
1311
|
+
return "%s^{%s}" % (x, exp)
|
|
1312
|
+
else:
|
|
1313
|
+
return "%s^%s" % (x, exp)
|
|
1314
|
+
if do_latex:
|
|
1315
|
+
return "%s \\cdot %s^{%s}" % (co, x, exp)
|
|
1316
|
+
else:
|
|
1317
|
+
return "%s*%s^%s" % (co, x, exp)
|
|
1318
|
+
|
|
1319
|
+
cdef _plus_ellipsis(self, bint do_latex):
|
|
1320
|
+
"""
|
|
1321
|
+
Return a representation of '+ ...', latexed if necessary.
|
|
1322
|
+
"""
|
|
1323
|
+
if do_latex:
|
|
1324
|
+
return " + \\cdots"
|
|
1325
|
+
else:
|
|
1326
|
+
return " + ..."
|
|
1327
|
+
|
|
1328
|
+
cdef _ellipsis(self, bint do_latex):
|
|
1329
|
+
"""
|
|
1330
|
+
Return a representation of '...', latexed if necessary.
|
|
1331
|
+
"""
|
|
1332
|
+
if do_latex:
|
|
1333
|
+
return "\\cdots"
|
|
1334
|
+
else:
|
|
1335
|
+
return "..."
|
|
1336
|
+
|
|
1337
|
+
cdef _truncate_list(self, L, max_terms, zero):
|
|
1338
|
+
"""
|
|
1339
|
+
Take a list L of coefficients and returns a list with at most max_terms nonzero terms.
|
|
1340
|
+
|
|
1341
|
+
INPUT:
|
|
1342
|
+
|
|
1343
|
+
- ``L`` -- list
|
|
1344
|
+
|
|
1345
|
+
- ``max_terms`` -- nonnegative integer (or -1, in which case
|
|
1346
|
+
no truncation occurs)
|
|
1347
|
+
|
|
1348
|
+
- ``zero`` -- what should be considered zero, usually 0 or []
|
|
1349
|
+
|
|
1350
|
+
OUTPUT:
|
|
1351
|
+
|
|
1352
|
+
- truncated list; later terms are removed
|
|
1353
|
+
- boolean; whether any truncation occurred
|
|
1354
|
+
"""
|
|
1355
|
+
if max_terms == -1 or len(L) == 0:
|
|
1356
|
+
return list(L), False
|
|
1357
|
+
cdef Py_ssize_t i, nonzero_index
|
|
1358
|
+
cdef Py_ssize_t count = 0
|
|
1359
|
+
ans = []
|
|
1360
|
+
for i, c in enumerate(L):
|
|
1361
|
+
if c != zero:
|
|
1362
|
+
count += 1
|
|
1363
|
+
if count > max_terms:
|
|
1364
|
+
return ans[:nonzero_index+1], True
|
|
1365
|
+
nonzero_index = i
|
|
1366
|
+
ans.append(c)
|
|
1367
|
+
return ans, False
|
|
1368
|
+
|
|
1369
|
+
cdef _print_unram_term(self, L, bint do_latex, polyname, long max_unram_terms, long expshift, bint increasing):
|
|
1370
|
+
"""
|
|
1371
|
+
Return a string representation of L when considered as a polynomial,
|
|
1372
|
+
truncating to at most ``max_unram_terms`` nonzero terms.
|
|
1373
|
+
|
|
1374
|
+
INPUT:
|
|
1375
|
+
|
|
1376
|
+
- ``L`` -- a list of coefficients
|
|
1377
|
+
|
|
1378
|
+
- ``do_latex`` -- whether to print latex-style
|
|
1379
|
+
|
|
1380
|
+
- ``polyname`` -- the name for the variable
|
|
1381
|
+
|
|
1382
|
+
- ``max_unram_terms`` -- a maximum number of terms before
|
|
1383
|
+
truncation occurs and an ellipsis is added. -1
|
|
1384
|
+
indicates no truncation should happen.
|
|
1385
|
+
|
|
1386
|
+
- ``expshift`` -- a shift for all the exponents of the variable
|
|
1387
|
+
|
|
1388
|
+
- ``increasing`` -- whether to order the exponents in increasing fashion
|
|
1389
|
+
"""
|
|
1390
|
+
s = ""
|
|
1391
|
+
cdef Py_ssize_t j, newj
|
|
1392
|
+
cdef long exp, count = 0
|
|
1393
|
+
if increasing:
|
|
1394
|
+
for j from 0 <= j < len(L):
|
|
1395
|
+
exp = j + expshift
|
|
1396
|
+
if L[j] != 0:
|
|
1397
|
+
if max_unram_terms == 0:
|
|
1398
|
+
return "(" + self._ellipsis(do_latex) + ")"
|
|
1399
|
+
elif max_unram_terms == 1:
|
|
1400
|
+
s = self._co_dot_var(L[j], polyname, exp, do_latex)
|
|
1401
|
+
s += self._plus_ellipsis(do_latex)
|
|
1402
|
+
return s
|
|
1403
|
+
else:
|
|
1404
|
+
count += 1
|
|
1405
|
+
if count == max_unram_terms: # this will never trigger if max_unram_terms == -1
|
|
1406
|
+
newj = len(L) - 1
|
|
1407
|
+
while L[newj] == 0:
|
|
1408
|
+
newj -= 1
|
|
1409
|
+
if newj != j:
|
|
1410
|
+
exp = newj + expshift
|
|
1411
|
+
s += self._plus_ellipsis(do_latex)
|
|
1412
|
+
s = self._print_term_of_poly(s, L[newj], do_latex, polyname, exp)
|
|
1413
|
+
return s
|
|
1414
|
+
else:
|
|
1415
|
+
s = self._print_term_of_poly(s, L[j], do_latex, polyname, exp)
|
|
1416
|
+
else:
|
|
1417
|
+
for j from len(L) - 1 >= j >= 0:
|
|
1418
|
+
exp = j + expshift
|
|
1419
|
+
if L[j] != 0:
|
|
1420
|
+
if max_unram_terms == 0:
|
|
1421
|
+
return "(" + self._ellipsis(do_latex) + ")"
|
|
1422
|
+
elif max_unram_terms == 1:
|
|
1423
|
+
s = self._co_dot_var(L[j], polyname, exp, do_latex)
|
|
1424
|
+
s += self._plus_ellipsis(do_latex)
|
|
1425
|
+
return s
|
|
1426
|
+
else:
|
|
1427
|
+
count += 1
|
|
1428
|
+
if count == max_unram_terms: # this will never trigger if max_unram_terms == -1
|
|
1429
|
+
newj = 0
|
|
1430
|
+
while L[newj] == 0:
|
|
1431
|
+
newj += 1
|
|
1432
|
+
if newj != j:
|
|
1433
|
+
exp = newj + expshift
|
|
1434
|
+
s += self._plus_ellipsis(do_latex)
|
|
1435
|
+
s = self._print_term_of_poly(s, L[newj], do_latex, polyname, exp)
|
|
1436
|
+
return s
|
|
1437
|
+
else:
|
|
1438
|
+
s = self._print_term_of_poly(s, L[j], do_latex, polyname, exp)
|
|
1439
|
+
return s
|
|
1440
|
+
|
|
1441
|
+
cdef _terse_frac(self, a, v, u, ram_name, bint do_latex):
|
|
1442
|
+
"""
|
|
1443
|
+
Return a representation of 'a=u/ram_name^v', latexed if necessary.
|
|
1444
|
+
"""
|
|
1445
|
+
if do_latex:
|
|
1446
|
+
if v >= 0:
|
|
1447
|
+
arep = a._latex_()
|
|
1448
|
+
elif v == -1:
|
|
1449
|
+
arep = "\\frac{%s}{%s}" % (u, ram_name)
|
|
1450
|
+
else:
|
|
1451
|
+
arep = "\\frac{%s}{%s^{%s}}" % (u, ram_name, -v)
|
|
1452
|
+
else:
|
|
1453
|
+
if v >= 0:
|
|
1454
|
+
arep = str(a)
|
|
1455
|
+
elif v == -1:
|
|
1456
|
+
arep = "%s/%s" % (u, ram_name)
|
|
1457
|
+
else:
|
|
1458
|
+
arep = "%s/%s^%s" % (u, ram_name, -v)
|
|
1459
|
+
return arep
|
|
1460
|
+
|
|
1461
|
+
cdef _print_list_as_poly(self, L, bint do_latex, polyname, long expshift, bint increasing):
|
|
1462
|
+
"""
|
|
1463
|
+
Print a list ``L`` as a polynomial.
|
|
1464
|
+
|
|
1465
|
+
INPUT:
|
|
1466
|
+
|
|
1467
|
+
- ``L`` -- a list of coefficients
|
|
1468
|
+
|
|
1469
|
+
- ``do_latex`` -- whether to print latex-style
|
|
1470
|
+
|
|
1471
|
+
- ``polyname`` -- the name for the variable
|
|
1472
|
+
|
|
1473
|
+
- ``expshift`` -- a shift for all the exponents of the variable
|
|
1474
|
+
|
|
1475
|
+
- ``increasing`` -- whether to order the exponents in increasing fashion
|
|
1476
|
+
"""
|
|
1477
|
+
s = ""
|
|
1478
|
+
cdef Py_ssize_t j
|
|
1479
|
+
cdef long exp
|
|
1480
|
+
if increasing:
|
|
1481
|
+
for j from 0 <= j < len(L):
|
|
1482
|
+
exp = j + expshift
|
|
1483
|
+
s = self._print_term_of_poly(s, L[j], do_latex, polyname, exp)
|
|
1484
|
+
else:
|
|
1485
|
+
for j from len(L) - 1 >= j >= 0:
|
|
1486
|
+
exp = j + expshift
|
|
1487
|
+
s = self._print_term_of_poly(s, L[j], do_latex, polyname, exp)
|
|
1488
|
+
return s
|
|
1489
|
+
|
|
1490
|
+
cdef _print_term_of_poly(self, s, coeff, bint do_latex, polyname, long exp):
|
|
1491
|
+
"""
|
|
1492
|
+
Appends +coeff*polyname^exp to s, latexed if necessary.
|
|
1493
|
+
"""
|
|
1494
|
+
if coeff < 0:
|
|
1495
|
+
if len(s) > 0:
|
|
1496
|
+
s += " - "
|
|
1497
|
+
else:
|
|
1498
|
+
s = "-"
|
|
1499
|
+
coeff = -coeff
|
|
1500
|
+
s += self._co_dot_var(coeff, polyname, exp, do_latex)
|
|
1501
|
+
elif coeff > 0:
|
|
1502
|
+
if len(s) > 0:
|
|
1503
|
+
s += " + "
|
|
1504
|
+
s += self._co_dot_var(coeff, polyname, exp, do_latex)
|
|
1505
|
+
return s
|