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,10 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
from sage.misc.lazy_import import lazy_import
|
|
3
|
+
|
|
4
|
+
lazy_import('sage.rings.padics.padic_valuation', 'pAdicValuation')
|
|
5
|
+
lazy_import('sage.rings.function_field.valuation', 'FunctionFieldValuation')
|
|
6
|
+
lazy_import('sage.rings.valuation.gauss_valuation', 'GaussValuation')
|
|
7
|
+
lazy_import('sage.rings.valuation.trivial_valuation', ['TrivialDiscretePseudoValuation', 'TrivialPseudoValuation', 'TrivialValuation'])
|
|
8
|
+
lazy_import('sage.rings.valuation.limit_valuation', 'LimitValuation')
|
|
9
|
+
|
|
10
|
+
del lazy_import
|
|
@@ -0,0 +1,697 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|
|
2
|
+
r"""
|
|
3
|
+
Value groups of discrete valuations
|
|
4
|
+
|
|
5
|
+
This file defines additive sub(semi-)groups of `\QQ` and related structures.
|
|
6
|
+
|
|
7
|
+
AUTHORS:
|
|
8
|
+
|
|
9
|
+
- Julian Rüth (2013-09-06): initial version
|
|
10
|
+
|
|
11
|
+
EXAMPLES::
|
|
12
|
+
|
|
13
|
+
sage: v = ZZ.valuation(2)
|
|
14
|
+
sage: v.value_group()
|
|
15
|
+
Additive Abelian Group generated by 1
|
|
16
|
+
sage: v.value_semigroup()
|
|
17
|
+
Additive Abelian Semigroup generated by 1
|
|
18
|
+
"""
|
|
19
|
+
# ****************************************************************************
|
|
20
|
+
# Copyright (C) 2013-2018 Julian Rüth <julian.rueth@fsfe.org>
|
|
21
|
+
#
|
|
22
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
23
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
24
|
+
# the License, or (at your option) any later version.
|
|
25
|
+
# https://www.gnu.org/licenses/
|
|
26
|
+
# ****************************************************************************
|
|
27
|
+
|
|
28
|
+
from sage.structure.parent import Parent
|
|
29
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
30
|
+
from sage.rings.integer_ring import ZZ
|
|
31
|
+
from sage.rings.rational_field import QQ
|
|
32
|
+
from sage.rings.infinity import infinity
|
|
33
|
+
from sage.misc.cachefunc import cached_method
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DiscreteValuationCodomain(UniqueRepresentation, Parent):
|
|
37
|
+
r"""
|
|
38
|
+
The codomain of discrete valuations, the rational numbers extended by
|
|
39
|
+
`\pm\infty`.
|
|
40
|
+
|
|
41
|
+
EXAMPLES::
|
|
42
|
+
|
|
43
|
+
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain
|
|
44
|
+
sage: C = DiscreteValuationCodomain(); C
|
|
45
|
+
Codomain of Discrete Valuations
|
|
46
|
+
|
|
47
|
+
TESTS::
|
|
48
|
+
|
|
49
|
+
sage: TestSuite(C).run() # long time
|
|
50
|
+
"""
|
|
51
|
+
def __init__(self):
|
|
52
|
+
r"""
|
|
53
|
+
TESTS::
|
|
54
|
+
|
|
55
|
+
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain
|
|
56
|
+
sage: isinstance(QQ.valuation(2).codomain(), DiscreteValuationCodomain)
|
|
57
|
+
True
|
|
58
|
+
"""
|
|
59
|
+
from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
|
|
60
|
+
from sage.categories.additive_monoids import AdditiveMonoids
|
|
61
|
+
UniqueRepresentation.__init__(self)
|
|
62
|
+
Parent.__init__(self, facade=(QQ, FiniteEnumeratedSet([infinity, -infinity])), category=AdditiveMonoids())
|
|
63
|
+
|
|
64
|
+
def _element_constructor_(self, x):
|
|
65
|
+
r"""
|
|
66
|
+
Create an element from ``x``.
|
|
67
|
+
|
|
68
|
+
INPUT:
|
|
69
|
+
|
|
70
|
+
- ``x`` -- a rational number or `\infty`
|
|
71
|
+
|
|
72
|
+
TESTS::
|
|
73
|
+
|
|
74
|
+
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain
|
|
75
|
+
sage: DiscreteValuationCodomain()(0)
|
|
76
|
+
0
|
|
77
|
+
sage: DiscreteValuationCodomain()(infinity)
|
|
78
|
+
+Infinity
|
|
79
|
+
sage: DiscreteValuationCodomain()(-infinity)
|
|
80
|
+
-Infinity
|
|
81
|
+
"""
|
|
82
|
+
if x is infinity:
|
|
83
|
+
return x
|
|
84
|
+
if x is -infinity:
|
|
85
|
+
return x
|
|
86
|
+
if x not in QQ:
|
|
87
|
+
raise ValueError("must be a rational number or infinity")
|
|
88
|
+
return QQ.coerce(x)
|
|
89
|
+
|
|
90
|
+
def _repr_(self):
|
|
91
|
+
r"""
|
|
92
|
+
Return a printable representation.
|
|
93
|
+
|
|
94
|
+
EXAMPLES::
|
|
95
|
+
|
|
96
|
+
sage: from sage.rings.valuation.value_group import DiscreteValuationCodomain
|
|
97
|
+
sage: DiscreteValuationCodomain() # indirect doctest
|
|
98
|
+
Codomain of Discrete Valuations
|
|
99
|
+
"""
|
|
100
|
+
return "Codomain of Discrete Valuations"
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class DiscreteValueGroup(UniqueRepresentation, Parent):
|
|
104
|
+
r"""
|
|
105
|
+
The value group of a discrete valuation, an additive subgroup of `\QQ`
|
|
106
|
+
generated by ``generator``.
|
|
107
|
+
|
|
108
|
+
INPUT:
|
|
109
|
+
|
|
110
|
+
- ``generator`` -- a rational number
|
|
111
|
+
|
|
112
|
+
.. NOTE::
|
|
113
|
+
|
|
114
|
+
We do not rely on the functionality provided by additive abelian groups
|
|
115
|
+
in Sage since these require the underlying set to be the integers.
|
|
116
|
+
Therefore, we roll our own \Z-module here.
|
|
117
|
+
We could have used :class:`AdditiveAbelianGroupWrapper` here, but it
|
|
118
|
+
seems to be somewhat outdated. In particular, generic group
|
|
119
|
+
functionality should now come from the category and not from the
|
|
120
|
+
super-class. A facade of \Q appeared to be the better approach.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
125
|
+
sage: D1 = DiscreteValueGroup(0); D1
|
|
126
|
+
Trivial Additive Abelian Group
|
|
127
|
+
sage: D2 = DiscreteValueGroup(4/3); D2
|
|
128
|
+
Additive Abelian Group generated by 4/3
|
|
129
|
+
sage: D3 = DiscreteValueGroup(-1/3); D3
|
|
130
|
+
Additive Abelian Group generated by 1/3
|
|
131
|
+
|
|
132
|
+
TESTS::
|
|
133
|
+
|
|
134
|
+
sage: TestSuite(D1).run() # long time
|
|
135
|
+
sage: TestSuite(D2).run() # long time
|
|
136
|
+
sage: TestSuite(D3).run() # long time
|
|
137
|
+
"""
|
|
138
|
+
@staticmethod
|
|
139
|
+
def __classcall__(cls, generator):
|
|
140
|
+
r"""
|
|
141
|
+
Normalize ``generator`` to a positive rational so that this is a
|
|
142
|
+
unique parent.
|
|
143
|
+
|
|
144
|
+
TESTS::
|
|
145
|
+
|
|
146
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
147
|
+
sage: DiscreteValueGroup(1) is DiscreteValueGroup(-1)
|
|
148
|
+
True
|
|
149
|
+
"""
|
|
150
|
+
generator = QQ.coerce(generator).abs()
|
|
151
|
+
return super().__classcall__(cls, generator)
|
|
152
|
+
|
|
153
|
+
def __init__(self, generator):
|
|
154
|
+
r"""
|
|
155
|
+
TESTS::
|
|
156
|
+
|
|
157
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
158
|
+
sage: isinstance(DiscreteValueGroup(0), DiscreteValueGroup)
|
|
159
|
+
True
|
|
160
|
+
"""
|
|
161
|
+
from sage.categories.modules import Modules
|
|
162
|
+
self._generator = generator
|
|
163
|
+
|
|
164
|
+
# We can not set the facade to DiscreteValuationCodomain since there
|
|
165
|
+
# are some issues with iterated facades currently
|
|
166
|
+
UniqueRepresentation.__init__(self)
|
|
167
|
+
Parent.__init__(self, facade=QQ, category=Modules(ZZ))
|
|
168
|
+
|
|
169
|
+
def _element_constructor_(self, x):
|
|
170
|
+
r"""
|
|
171
|
+
Create an element in this group from ``x``.
|
|
172
|
+
|
|
173
|
+
INPUT:
|
|
174
|
+
|
|
175
|
+
- ``x`` -- a rational number
|
|
176
|
+
|
|
177
|
+
TESTS::
|
|
178
|
+
|
|
179
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
180
|
+
sage: DiscreteValueGroup(0)(0)
|
|
181
|
+
0
|
|
182
|
+
sage: DiscreteValueGroup(0)(1)
|
|
183
|
+
Traceback (most recent call last):
|
|
184
|
+
...
|
|
185
|
+
ValueError: `1` is not in Trivial Additive Abelian Group.
|
|
186
|
+
sage: DiscreteValueGroup(1)(1)
|
|
187
|
+
1
|
|
188
|
+
sage: DiscreteValueGroup(1)(1/2)
|
|
189
|
+
Traceback (most recent call last):
|
|
190
|
+
...
|
|
191
|
+
ValueError: `1/2` is not in Additive Abelian Group generated by 1.
|
|
192
|
+
"""
|
|
193
|
+
x = QQ.coerce(x)
|
|
194
|
+
if x == 0 or (self._generator != 0 and x / self._generator in ZZ):
|
|
195
|
+
return x
|
|
196
|
+
|
|
197
|
+
raise ValueError("`{0}` is not in {1}.".format(x, self))
|
|
198
|
+
|
|
199
|
+
def _repr_(self):
|
|
200
|
+
r"""
|
|
201
|
+
Return a printable representation for this group.
|
|
202
|
+
|
|
203
|
+
EXAMPLES::
|
|
204
|
+
|
|
205
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
206
|
+
sage: DiscreteValueGroup(0) # indirect doctest
|
|
207
|
+
Trivial Additive Abelian Group
|
|
208
|
+
"""
|
|
209
|
+
if self.is_trivial():
|
|
210
|
+
return "Trivial Additive Abelian Group"
|
|
211
|
+
return "Additive Abelian Group generated by %r" % (self._generator,)
|
|
212
|
+
|
|
213
|
+
def __add__(self, other):
|
|
214
|
+
r"""
|
|
215
|
+
Return the subgroup of `\QQ` generated by this group and ``other``.
|
|
216
|
+
|
|
217
|
+
INPUT:
|
|
218
|
+
|
|
219
|
+
- ``other`` -- a discrete value group or a rational number
|
|
220
|
+
|
|
221
|
+
EXAMPLES::
|
|
222
|
+
|
|
223
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
224
|
+
sage: D = DiscreteValueGroup(1/2)
|
|
225
|
+
sage: D + 1/3
|
|
226
|
+
Additive Abelian Group generated by 1/6
|
|
227
|
+
sage: D + D
|
|
228
|
+
Additive Abelian Group generated by 1/2
|
|
229
|
+
sage: D + 1
|
|
230
|
+
Additive Abelian Group generated by 1/2
|
|
231
|
+
sage: DiscreteValueGroup(2/7) + DiscreteValueGroup(4/9)
|
|
232
|
+
Additive Abelian Group generated by 2/63
|
|
233
|
+
"""
|
|
234
|
+
if isinstance(other, DiscreteValueGroup):
|
|
235
|
+
return DiscreteValueGroup(self._generator.gcd(other._generator))
|
|
236
|
+
if isinstance(other, DiscreteValueSemigroup):
|
|
237
|
+
return other + self
|
|
238
|
+
from sage.structure.element import Element
|
|
239
|
+
if isinstance(other, Element) and QQ.has_coerce_map_from(other.parent()):
|
|
240
|
+
return self + DiscreteValueGroup(other)
|
|
241
|
+
raise ValueError("`other` must be a DiscreteValueGroup or a rational number")
|
|
242
|
+
|
|
243
|
+
def _mul_(self, other, switch_sides=False):
|
|
244
|
+
r"""
|
|
245
|
+
Return the group generated by ``other`` times the generator of this
|
|
246
|
+
group.
|
|
247
|
+
|
|
248
|
+
INPUT:
|
|
249
|
+
|
|
250
|
+
- ``other`` -- a rational number
|
|
251
|
+
|
|
252
|
+
EXAMPLES::
|
|
253
|
+
|
|
254
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
255
|
+
sage: D = DiscreteValueGroup(1/2)
|
|
256
|
+
sage: 1/2 * D
|
|
257
|
+
Additive Abelian Group generated by 1/4
|
|
258
|
+
sage: D * (1/2)
|
|
259
|
+
Additive Abelian Group generated by 1/4
|
|
260
|
+
sage: D * 0
|
|
261
|
+
Trivial Additive Abelian Group
|
|
262
|
+
"""
|
|
263
|
+
other = QQ.coerce(other)
|
|
264
|
+
return DiscreteValueGroup(self._generator * other)
|
|
265
|
+
|
|
266
|
+
def index(self, other):
|
|
267
|
+
r"""
|
|
268
|
+
Return the index of ``other`` in this group.
|
|
269
|
+
|
|
270
|
+
INPUT:
|
|
271
|
+
|
|
272
|
+
- ``other`` -- a subgroup of this group
|
|
273
|
+
|
|
274
|
+
EXAMPLES::
|
|
275
|
+
|
|
276
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
277
|
+
sage: DiscreteValueGroup(3/8).index(DiscreteValueGroup(3))
|
|
278
|
+
8
|
|
279
|
+
sage: DiscreteValueGroup(3).index(DiscreteValueGroup(3/8))
|
|
280
|
+
Traceback (most recent call last):
|
|
281
|
+
...
|
|
282
|
+
ValueError: other must be a subgroup of this group
|
|
283
|
+
sage: DiscreteValueGroup(3).index(DiscreteValueGroup(0))
|
|
284
|
+
Traceback (most recent call last):
|
|
285
|
+
...
|
|
286
|
+
ValueError: other must have finite index in this group
|
|
287
|
+
sage: DiscreteValueGroup(0).index(DiscreteValueGroup(0))
|
|
288
|
+
1
|
|
289
|
+
sage: DiscreteValueGroup(0).index(DiscreteValueGroup(3))
|
|
290
|
+
Traceback (most recent call last):
|
|
291
|
+
...
|
|
292
|
+
ValueError: other must be a subgroup of this group
|
|
293
|
+
"""
|
|
294
|
+
if not isinstance(other, DiscreteValueGroup):
|
|
295
|
+
raise ValueError("other must be a DiscreteValueGroup")
|
|
296
|
+
if other._generator not in self:
|
|
297
|
+
raise ValueError("other must be a subgroup of this group")
|
|
298
|
+
if other._generator == 0:
|
|
299
|
+
if self._generator == 0:
|
|
300
|
+
return ZZ(1)
|
|
301
|
+
else:
|
|
302
|
+
raise ValueError("other must have finite index in this group")
|
|
303
|
+
return ZZ(other._generator / self._generator)
|
|
304
|
+
|
|
305
|
+
def numerator(self):
|
|
306
|
+
r"""
|
|
307
|
+
Return the numerator of a generator of this group.
|
|
308
|
+
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
312
|
+
sage: DiscreteValueGroup(3/8).numerator()
|
|
313
|
+
3
|
|
314
|
+
"""
|
|
315
|
+
return self._generator.numerator()
|
|
316
|
+
|
|
317
|
+
def denominator(self):
|
|
318
|
+
r"""
|
|
319
|
+
Return the denominator of a generator of this group.
|
|
320
|
+
|
|
321
|
+
EXAMPLES::
|
|
322
|
+
|
|
323
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
324
|
+
sage: DiscreteValueGroup(3/8).denominator()
|
|
325
|
+
8
|
|
326
|
+
"""
|
|
327
|
+
return self._generator.denominator()
|
|
328
|
+
|
|
329
|
+
def gen(self):
|
|
330
|
+
r"""
|
|
331
|
+
Return a generator of this group.
|
|
332
|
+
|
|
333
|
+
EXAMPLES::
|
|
334
|
+
|
|
335
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
336
|
+
sage: DiscreteValueGroup(-3/8).gen()
|
|
337
|
+
3/8
|
|
338
|
+
"""
|
|
339
|
+
return self._generator
|
|
340
|
+
|
|
341
|
+
def some_elements(self):
|
|
342
|
+
r"""
|
|
343
|
+
Return some typical elements in this group.
|
|
344
|
+
|
|
345
|
+
EXAMPLES::
|
|
346
|
+
|
|
347
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
348
|
+
sage: DiscreteValueGroup(-3/8).some_elements()
|
|
349
|
+
[3/8, -3/8, 0, 42, 3/2, -3/2, 9/8, -9/8]
|
|
350
|
+
"""
|
|
351
|
+
return [self._generator, -self._generator] + [x for x in QQ.some_elements() if x in self]
|
|
352
|
+
|
|
353
|
+
def is_trivial(self):
|
|
354
|
+
r"""
|
|
355
|
+
Return whether this is the trivial additive abelian group.
|
|
356
|
+
|
|
357
|
+
EXAMPLES::
|
|
358
|
+
|
|
359
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
360
|
+
sage: DiscreteValueGroup(-3/8).is_trivial()
|
|
361
|
+
False
|
|
362
|
+
sage: DiscreteValueGroup(0).is_trivial()
|
|
363
|
+
True
|
|
364
|
+
"""
|
|
365
|
+
return self._generator.is_zero()
|
|
366
|
+
|
|
367
|
+
def _element_with_valuation(self, subgroup, s):
|
|
368
|
+
r"""
|
|
369
|
+
Return exponents such that `\pi^a+\psi^b` has valuation `s` where `\pi`
|
|
370
|
+
is a unformizer corresponding to this value group and `\psi` a
|
|
371
|
+
unformizer corresponding to its ``subgroup``.
|
|
372
|
+
|
|
373
|
+
The returned values are such that ``a`` is minimal.
|
|
374
|
+
|
|
375
|
+
EXAMPLES::
|
|
376
|
+
|
|
377
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueGroup
|
|
378
|
+
sage: DiscreteValueGroup(3/8)._element_with_valuation(DiscreteValueGroup(3), 15/8)
|
|
379
|
+
(-3, 1)
|
|
380
|
+
sage: DiscreteValueGroup(3/8)._element_with_valuation(DiscreteValueGroup(3), 33/8)
|
|
381
|
+
(3, 1)
|
|
382
|
+
"""
|
|
383
|
+
if s not in self:
|
|
384
|
+
raise ValueError("s must be in the value group but %r is not in %r." % (s, self))
|
|
385
|
+
|
|
386
|
+
i = self.index(subgroup)
|
|
387
|
+
x = s/self.gen()
|
|
388
|
+
a = x % i
|
|
389
|
+
if abs(a-i) < a:
|
|
390
|
+
a -= i
|
|
391
|
+
b = (x-a)/i
|
|
392
|
+
return a, b
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class DiscreteValueSemigroup(UniqueRepresentation, Parent):
|
|
396
|
+
r"""
|
|
397
|
+
The value semigroup of a discrete valuation, an additive subsemigroup of
|
|
398
|
+
`\QQ` generated by ``generators``.
|
|
399
|
+
|
|
400
|
+
INPUT:
|
|
401
|
+
|
|
402
|
+
- ``generators`` -- rational numbers
|
|
403
|
+
|
|
404
|
+
EXAMPLES::
|
|
405
|
+
|
|
406
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
407
|
+
sage: D1 = DiscreteValueSemigroup(0); D1
|
|
408
|
+
Trivial Additive Abelian Semigroup
|
|
409
|
+
sage: D2 = DiscreteValueSemigroup(4/3); D2
|
|
410
|
+
Additive Abelian Semigroup generated by 4/3
|
|
411
|
+
sage: D3 = DiscreteValueSemigroup([-1/3, 1/2]); D3
|
|
412
|
+
Additive Abelian Semigroup generated by -1/3, 1/2
|
|
413
|
+
|
|
414
|
+
TESTS::
|
|
415
|
+
|
|
416
|
+
sage: TestSuite(D1).run() # long time
|
|
417
|
+
sage: TestSuite(D2).run() # long time # needs sage.geometry.polyhedron
|
|
418
|
+
sage: TestSuite(D3).run() # long time # needs sage.numerical.mip
|
|
419
|
+
"""
|
|
420
|
+
@staticmethod
|
|
421
|
+
def __classcall__(cls, generators):
|
|
422
|
+
r"""
|
|
423
|
+
Normalize ``generators``.
|
|
424
|
+
|
|
425
|
+
TESTS:
|
|
426
|
+
|
|
427
|
+
We do not find minimal generators or something like that but just sort the
|
|
428
|
+
generators and drop generators that are trivially contained in the
|
|
429
|
+
semigroup generated by the remaining generators::
|
|
430
|
+
|
|
431
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
432
|
+
sage: DiscreteValueSemigroup([1,2]) is DiscreteValueSemigroup([1])
|
|
433
|
+
True
|
|
434
|
+
|
|
435
|
+
In this case, the normalization is not sufficient to determine that
|
|
436
|
+
these are the same semigroup::
|
|
437
|
+
|
|
438
|
+
sage: DiscreteValueSemigroup([1,-1,1/3]) is DiscreteValueSemigroup([1/3,-1/3])
|
|
439
|
+
False
|
|
440
|
+
"""
|
|
441
|
+
if generators in QQ:
|
|
442
|
+
generators = [generators]
|
|
443
|
+
generators = list({QQ.coerce(g) for g in generators if g != 0})
|
|
444
|
+
generators.sort()
|
|
445
|
+
simplified_generators = generators
|
|
446
|
+
|
|
447
|
+
# this is not very efficient but there should never be more than a
|
|
448
|
+
# couple of generators
|
|
449
|
+
for g in generators:
|
|
450
|
+
for h in generators:
|
|
451
|
+
if g == h:
|
|
452
|
+
continue
|
|
453
|
+
from sage.rings.semirings.non_negative_integer_semiring import NN
|
|
454
|
+
if h / g in NN:
|
|
455
|
+
simplified_generators.remove(h)
|
|
456
|
+
break
|
|
457
|
+
|
|
458
|
+
return super().__classcall__(cls, tuple(simplified_generators))
|
|
459
|
+
|
|
460
|
+
def __init__(self, generators):
|
|
461
|
+
r"""
|
|
462
|
+
TESTS::
|
|
463
|
+
|
|
464
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
465
|
+
sage: isinstance(DiscreteValueSemigroup([0]), DiscreteValueSemigroup)
|
|
466
|
+
True
|
|
467
|
+
"""
|
|
468
|
+
from sage.categories.additive_magmas import AdditiveMagmas
|
|
469
|
+
self._generators = generators
|
|
470
|
+
|
|
471
|
+
category = AdditiveMagmas().AdditiveAssociative().AdditiveUnital()
|
|
472
|
+
if all(-g in generators for g in generators):
|
|
473
|
+
# check whether this is trivially a group
|
|
474
|
+
# is_group() performs a complete check that is very costly and
|
|
475
|
+
# refines the category
|
|
476
|
+
category = category.AdditiveInverse()
|
|
477
|
+
|
|
478
|
+
# We can not set the facade to DiscreteValuationCodomain since there
|
|
479
|
+
# are some issues with iterated facades currently
|
|
480
|
+
Parent.__init__(self, facade=QQ, category=category)
|
|
481
|
+
|
|
482
|
+
def _solve_linear_program(self, target):
|
|
483
|
+
r"""
|
|
484
|
+
Return the coefficients of a linear combination to write ``target`` in
|
|
485
|
+
terms of the generators of this semigroup.
|
|
486
|
+
|
|
487
|
+
Return ``None`` if no such combination exists.
|
|
488
|
+
|
|
489
|
+
EXAMPLES::
|
|
490
|
+
|
|
491
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
492
|
+
sage: D = DiscreteValueSemigroup([2,3,5])
|
|
493
|
+
sage: D._solve_linear_program(12) # needs sage.numerical.mip
|
|
494
|
+
{0: 1, 1: 0, 2: 2}
|
|
495
|
+
sage: 1*2 + 0*3 + 2*5
|
|
496
|
+
12
|
|
497
|
+
"""
|
|
498
|
+
if len(self._generators) == 0:
|
|
499
|
+
if target == 0:
|
|
500
|
+
return {}
|
|
501
|
+
else:
|
|
502
|
+
return None
|
|
503
|
+
|
|
504
|
+
if len(self._generators) == 1:
|
|
505
|
+
from sage.rings.semirings.non_negative_integer_semiring import NN
|
|
506
|
+
exp = target / self._generators[0]
|
|
507
|
+
if exp not in NN:
|
|
508
|
+
return None
|
|
509
|
+
return {0: exp}
|
|
510
|
+
|
|
511
|
+
if len(self._generators) == 2 and self._generators[0] == - self._generators[1]:
|
|
512
|
+
from sage.rings.integer_ring import ZZ
|
|
513
|
+
exp = target / self._generators[0]
|
|
514
|
+
if exp not in ZZ:
|
|
515
|
+
return None
|
|
516
|
+
return {0: exp, 1: 0}
|
|
517
|
+
|
|
518
|
+
from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException
|
|
519
|
+
P = MixedIntegerLinearProgram(maximization=False, solver='ppl')
|
|
520
|
+
x = P.new_variable(integer=True, nonnegative=True)
|
|
521
|
+
constraint = sum([g * x[i]
|
|
522
|
+
for i, g in enumerate(self._generators)]) == target
|
|
523
|
+
P.add_constraint(constraint)
|
|
524
|
+
P.set_objective(None)
|
|
525
|
+
try:
|
|
526
|
+
P.solve()
|
|
527
|
+
except MIPSolverException:
|
|
528
|
+
return None
|
|
529
|
+
return P.get_values(x)
|
|
530
|
+
|
|
531
|
+
def _element_constructor_(self, x):
|
|
532
|
+
r"""
|
|
533
|
+
Create an element in this group from ``x``.
|
|
534
|
+
|
|
535
|
+
INPUT:
|
|
536
|
+
|
|
537
|
+
- ``x`` -- a rational number
|
|
538
|
+
|
|
539
|
+
TESTS::
|
|
540
|
+
|
|
541
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
542
|
+
sage: DiscreteValueSemigroup([])(0)
|
|
543
|
+
0
|
|
544
|
+
sage: DiscreteValueSemigroup([])(1)
|
|
545
|
+
Traceback (most recent call last):
|
|
546
|
+
...
|
|
547
|
+
ValueError: `1` is not in Trivial Additive Abelian Semigroup.
|
|
548
|
+
sage: DiscreteValueSemigroup([1])(1)
|
|
549
|
+
1
|
|
550
|
+
sage: DiscreteValueSemigroup([1])(-1)
|
|
551
|
+
Traceback (most recent call last):
|
|
552
|
+
...
|
|
553
|
+
ValueError: `-1` is not in Additive Abelian Semigroup generated by 1.
|
|
554
|
+
"""
|
|
555
|
+
x = QQ.coerce(x)
|
|
556
|
+
if x in self._generators or self._solve_linear_program(x) is not None:
|
|
557
|
+
return x
|
|
558
|
+
|
|
559
|
+
raise ValueError("`{0}` is not in {1}.".format(x, self))
|
|
560
|
+
|
|
561
|
+
def _repr_(self):
|
|
562
|
+
r"""
|
|
563
|
+
Return a printable representation for this semigroup.
|
|
564
|
+
|
|
565
|
+
EXAMPLES::
|
|
566
|
+
|
|
567
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
568
|
+
sage: DiscreteValueSemigroup(0) # indirect doctest
|
|
569
|
+
Trivial Additive Abelian Semigroup
|
|
570
|
+
"""
|
|
571
|
+
if self.is_trivial():
|
|
572
|
+
return "Trivial Additive Abelian Semigroup"
|
|
573
|
+
return "Additive Abelian Semigroup generated by %s" % (', '.join(repr(g) for g in self._generators),)
|
|
574
|
+
|
|
575
|
+
def __add__(self, other):
|
|
576
|
+
r"""
|
|
577
|
+
Return the subsemigroup of `\QQ` generated by this semigroup and ``other``.
|
|
578
|
+
|
|
579
|
+
INPUT:
|
|
580
|
+
|
|
581
|
+
- ``other`` -- a discrete value (semi-)group or a rational number
|
|
582
|
+
|
|
583
|
+
EXAMPLES::
|
|
584
|
+
|
|
585
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup, DiscreteValueGroup
|
|
586
|
+
sage: D = DiscreteValueSemigroup(1/2)
|
|
587
|
+
sage: D + 1/3
|
|
588
|
+
Additive Abelian Semigroup generated by 1/3, 1/2
|
|
589
|
+
sage: D + D
|
|
590
|
+
Additive Abelian Semigroup generated by 1/2
|
|
591
|
+
sage: D + 1
|
|
592
|
+
Additive Abelian Semigroup generated by 1/2
|
|
593
|
+
sage: DiscreteValueGroup(2/7) + DiscreteValueSemigroup(4/9)
|
|
594
|
+
Additive Abelian Semigroup generated by -2/7, 2/7, 4/9
|
|
595
|
+
"""
|
|
596
|
+
if isinstance(other, DiscreteValueSemigroup):
|
|
597
|
+
return DiscreteValueSemigroup(self._generators + other._generators)
|
|
598
|
+
if isinstance(other, DiscreteValueGroup):
|
|
599
|
+
return DiscreteValueSemigroup(self._generators + (other._generator, -other._generator))
|
|
600
|
+
from sage.structure.element import Element
|
|
601
|
+
if isinstance(other, Element) and QQ.has_coerce_map_from(other.parent()):
|
|
602
|
+
return self + DiscreteValueSemigroup(other)
|
|
603
|
+
raise ValueError("`other` must be a DiscreteValueGroup, a DiscreteValueSemigroup or a rational number")
|
|
604
|
+
|
|
605
|
+
def _mul_(self, other, switch_sides=False):
|
|
606
|
+
r"""
|
|
607
|
+
Return the semigroup generated by ``other`` times the generators of this
|
|
608
|
+
semigroup.
|
|
609
|
+
|
|
610
|
+
INPUT:
|
|
611
|
+
|
|
612
|
+
- ``other`` -- a rational number
|
|
613
|
+
|
|
614
|
+
EXAMPLES::
|
|
615
|
+
|
|
616
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
617
|
+
sage: D = DiscreteValueSemigroup(1/2)
|
|
618
|
+
sage: 1/2 * D
|
|
619
|
+
Additive Abelian Semigroup generated by 1/4
|
|
620
|
+
sage: D * (1/2)
|
|
621
|
+
Additive Abelian Semigroup generated by 1/4
|
|
622
|
+
sage: D * 0
|
|
623
|
+
Trivial Additive Abelian Semigroup
|
|
624
|
+
"""
|
|
625
|
+
other = QQ.coerce(other)
|
|
626
|
+
return DiscreteValueSemigroup([g*other for g in self._generators])
|
|
627
|
+
|
|
628
|
+
def gens(self) -> tuple:
|
|
629
|
+
r"""
|
|
630
|
+
Return the generators of this semigroup.
|
|
631
|
+
|
|
632
|
+
EXAMPLES::
|
|
633
|
+
|
|
634
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
635
|
+
sage: DiscreteValueSemigroup(-3/8).gens()
|
|
636
|
+
(-3/8,)
|
|
637
|
+
"""
|
|
638
|
+
return tuple(self._generators)
|
|
639
|
+
|
|
640
|
+
def some_elements(self):
|
|
641
|
+
r"""
|
|
642
|
+
Return some typical elements in this semigroup.
|
|
643
|
+
|
|
644
|
+
EXAMPLES::
|
|
645
|
+
|
|
646
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
647
|
+
sage: list(DiscreteValueSemigroup([-3/8,1/2]).some_elements()) # needs sage.numerical.mip
|
|
648
|
+
[0, -3/8, 1/2, ...]
|
|
649
|
+
"""
|
|
650
|
+
yield self(0)
|
|
651
|
+
if self.is_trivial():
|
|
652
|
+
return
|
|
653
|
+
yield from self._generators
|
|
654
|
+
from sage.rings.integer_ring import ZZ
|
|
655
|
+
for x in (ZZ**len(self._generators)).some_elements():
|
|
656
|
+
yield QQ.coerce(sum([abs(c) * g
|
|
657
|
+
for c, g in zip(x, self._generators)]))
|
|
658
|
+
|
|
659
|
+
def is_trivial(self):
|
|
660
|
+
r"""
|
|
661
|
+
Return whether this is the trivial additive abelian semigroup.
|
|
662
|
+
|
|
663
|
+
EXAMPLES::
|
|
664
|
+
|
|
665
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
666
|
+
sage: DiscreteValueSemigroup(-3/8).is_trivial()
|
|
667
|
+
False
|
|
668
|
+
sage: DiscreteValueSemigroup([]).is_trivial()
|
|
669
|
+
True
|
|
670
|
+
"""
|
|
671
|
+
return len(self._generators) == 0
|
|
672
|
+
|
|
673
|
+
@cached_method
|
|
674
|
+
def is_group(self):
|
|
675
|
+
r"""
|
|
676
|
+
Return whether this semigroup is a group.
|
|
677
|
+
|
|
678
|
+
EXAMPLES::
|
|
679
|
+
|
|
680
|
+
sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup
|
|
681
|
+
sage: DiscreteValueSemigroup(1).is_group()
|
|
682
|
+
False
|
|
683
|
+
sage: D = DiscreteValueSemigroup([-1, 1])
|
|
684
|
+
sage: D.is_group()
|
|
685
|
+
True
|
|
686
|
+
|
|
687
|
+
Invoking this method also changes the category of this semigroup if it
|
|
688
|
+
is a group::
|
|
689
|
+
|
|
690
|
+
sage: D in AdditiveMagmas().AdditiveAssociative().AdditiveUnital().AdditiveInverse()
|
|
691
|
+
True
|
|
692
|
+
"""
|
|
693
|
+
for x in self._generators:
|
|
694
|
+
if -x not in self:
|
|
695
|
+
return False
|
|
696
|
+
self._refine_category_(self.category().AdditiveInverse())
|
|
697
|
+
return True
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-pari
|