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,2129 @@
|
|
|
1
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
2
|
+
\\ Copyright (C) 2011 Denis Simon
|
|
3
|
+
\\
|
|
4
|
+
\\ Distributed under the terms of the GNU General Public License (GPL)
|
|
5
|
+
\\
|
|
6
|
+
\\ This code is distributed in the hope that it will be useful,
|
|
7
|
+
\\ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
\\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
9
|
+
\\ General Public License for more details.
|
|
10
|
+
\\
|
|
11
|
+
\\ The full text of the GPL is available at:
|
|
12
|
+
\\
|
|
13
|
+
\\ http://www.gnu.org/licenses/
|
|
14
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
Auteur :
|
|
18
|
+
Denis SIMON -> simon@math.unicaen.fr
|
|
19
|
+
adresse du fichier :
|
|
20
|
+
www.math.unicaen.fr/~simon/ell.gp
|
|
21
|
+
|
|
22
|
+
*********************************************
|
|
23
|
+
* VERSION 06/04/2011 *
|
|
24
|
+
*********************************************
|
|
25
|
+
|
|
26
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
27
|
+
\\ Comment utiliser ce programme ? \\
|
|
28
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
29
|
+
|
|
30
|
+
Programme de calcul du rang des courbes elliptiques
|
|
31
|
+
dans les corps de nombres.
|
|
32
|
+
langage: GP
|
|
33
|
+
pour l'utiliser, lancer gp, puis taper
|
|
34
|
+
\r ell.gp
|
|
35
|
+
|
|
36
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
37
|
+
\\ Description des principales fonctions \\
|
|
38
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
39
|
+
|
|
40
|
+
Explications succintes :
|
|
41
|
+
definition du corps :
|
|
42
|
+
bnf=bnfinit(y^2+1);
|
|
43
|
+
(il est indispensable que la variable soit y).
|
|
44
|
+
on peut ensuite poser :
|
|
45
|
+
X = Mod(y,bnf.pol);
|
|
46
|
+
|
|
47
|
+
La fonction bnfellrank() accepte toutes les courbes sous la forme
|
|
48
|
+
[a1,a2,a3,a4,a6]
|
|
49
|
+
Les coefficients peuvent etre entiers ou non.
|
|
50
|
+
L'algorithme utilise est celui de la 2-descente.
|
|
51
|
+
La 2-torsion peut etre quelconque.
|
|
52
|
+
Il suffit de taper :
|
|
53
|
+
|
|
54
|
+
gp > ell = [a1,a2,a3,a4,a6];
|
|
55
|
+
gp > bnfellrank(bnf,ell)
|
|
56
|
+
|
|
57
|
+
Retourne un vecteur [r,s,vec]
|
|
58
|
+
ou r est le rang probable (c'est toujours une minoration du rang),
|
|
59
|
+
s est le 2-rang du groupe de Selmer,
|
|
60
|
+
vec est une liste de points dans E(K)/2E(K).
|
|
61
|
+
|
|
62
|
+
Courbes avec #E[2](K) >= 2:
|
|
63
|
+
ell doit etre sous la forme
|
|
64
|
+
y^2 = x^3 + A*^2 + B*x
|
|
65
|
+
avec A et B entiers algebriques
|
|
66
|
+
gp > ell = [0,A,0,B,0]
|
|
67
|
+
gp > bnfell2descent_viaisog(ell)
|
|
68
|
+
= algorithme de la 2-descente par isogenies
|
|
69
|
+
Attention A et B doivent etre entiers
|
|
70
|
+
|
|
71
|
+
Courbes avec #E[2](K) = 4: y^2 = (x-e1)*(x-e2)*(x-e3)
|
|
72
|
+
-> bnfell2descent_complete(bnf,e1,e2,e3);
|
|
73
|
+
= algorithme de la 2-descente complete
|
|
74
|
+
Attention: les ei doivent etre entiers algebriques.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
78
|
+
\\ Affichage des calculs \\
|
|
79
|
+
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
80
|
+
|
|
81
|
+
On peut avoir plus ou moins de details de calculs avec
|
|
82
|
+
DEBUGLEVEL_ell = 0;
|
|
83
|
+
DEBUGLEVEL_ell = 1; 2; 3;...
|
|
84
|
+
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
nf_scalar_or_multable_to_alg(nf, z) = {
|
|
89
|
+
if (type(z) == "t_MAT", nfbasistoalg(nf, z[,1]), z);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
93
|
+
\\ SCRIPT \\
|
|
94
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
95
|
+
|
|
96
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
97
|
+
\\ MANIPULATION OF GLOBAL VARIABLES \\
|
|
98
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
99
|
+
|
|
100
|
+
{default_ell(
|
|
101
|
+
DEBUGLEVEL_ell_val:small = 0,
|
|
102
|
+
LIM1_val:small = 2,
|
|
103
|
+
LIM3_val:small = 4,
|
|
104
|
+
LIMTRIV_val:small = 2,
|
|
105
|
+
MAXPROB_val:small = 20,
|
|
106
|
+
LIMBIGPRIME_val:small = 30
|
|
107
|
+
) =
|
|
108
|
+
|
|
109
|
+
DEBUGLEVEL_ell = DEBUGLEVEL_ell_val;
|
|
110
|
+
print(" DEBUGLEVEL_ell = ",DEBUGLEVEL_ell);
|
|
111
|
+
|
|
112
|
+
LIM1 = LIM1_val;
|
|
113
|
+
print(" LIM1 = ",LIM1);
|
|
114
|
+
|
|
115
|
+
LIM3 = LIM3_val;
|
|
116
|
+
print(" LIM3 = ",LIM3);
|
|
117
|
+
|
|
118
|
+
LIMTRIV = LIMTRIV_val;
|
|
119
|
+
print(" LIMTRIV = ",LIMTRIV);
|
|
120
|
+
|
|
121
|
+
MAXPROB = MAXPROB_val;
|
|
122
|
+
print(" MAXPROB = ",MAXPROB);
|
|
123
|
+
|
|
124
|
+
LIMBIGPRIME = LIMBIGPRIME_val;
|
|
125
|
+
print(" LIMBIGPRIME = ",LIMBIGPRIME);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
129
|
+
\\ COMMON FUNCTIONS TO ell.gp AND ellQ.gp \\
|
|
130
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
131
|
+
|
|
132
|
+
{ellcomposeurst(urst1,urst2) =
|
|
133
|
+
local(u1 = urst1[1], r1 = urst1[2], s1 = urst1[3], t1 = urst1[4],
|
|
134
|
+
u2 = urst2[1], r2 = urst2[2], s2 = urst2[3], t2 = urst2[4]);
|
|
135
|
+
[u1*u2,u1^2*r2+r1,u1*s2+s1,u1^3*t2+s1*u1^2*r2+t1];
|
|
136
|
+
}
|
|
137
|
+
{ellinverturst(urst) =
|
|
138
|
+
local(u = urst[1], r = urst[2], s = urst[3], t = urst[4]);
|
|
139
|
+
[1/u,-r/u^2,-s/u,(r*s-t)/u^3];
|
|
140
|
+
}
|
|
141
|
+
{mysubst(polsu,subsx) =
|
|
142
|
+
if( type(lift(polsu)) == "t_POL",
|
|
143
|
+
return(simplify(subst(lift(polsu),variable(lift(polsu)),subsx)))
|
|
144
|
+
, return(simplify(lift(polsu))));
|
|
145
|
+
}
|
|
146
|
+
{degre(idegre) =
|
|
147
|
+
local(ideg = idegre, jdeg = 0);
|
|
148
|
+
|
|
149
|
+
while( ideg >>= 1, jdeg++);
|
|
150
|
+
return(jdeg);
|
|
151
|
+
}
|
|
152
|
+
{nfissquare(nf, a) = #nfsqrt(nf,a) > 0;
|
|
153
|
+
}
|
|
154
|
+
{nfsqrt( nf, a) =
|
|
155
|
+
\\ if a is a square in the number field nf returns [sqrt(a)], otherwise [].
|
|
156
|
+
local(alift,ta,py,pfact);
|
|
157
|
+
|
|
158
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nfsqrt ",a));
|
|
159
|
+
if( a==0 || a==1,
|
|
160
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",a));
|
|
161
|
+
return([a]));
|
|
162
|
+
|
|
163
|
+
alift = lift(a);
|
|
164
|
+
ta = type(a);
|
|
165
|
+
if( !poldegree(alift), alift = polcoeff(alift,0));
|
|
166
|
+
|
|
167
|
+
if( type(alift) != "t_POL",
|
|
168
|
+
if( issquare(alift),
|
|
169
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",sqrtrat(alift)));
|
|
170
|
+
return([sqrtrat(alift)])));
|
|
171
|
+
|
|
172
|
+
if( poldegree(nf.pol) <= 1,
|
|
173
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[]));
|
|
174
|
+
return([]));
|
|
175
|
+
if( ta == "t_POL", a = Mod(a,nf.pol));
|
|
176
|
+
|
|
177
|
+
\\ the norm should be a square
|
|
178
|
+
|
|
179
|
+
if( !issquare(norm(a)),
|
|
180
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[]));
|
|
181
|
+
return([]));
|
|
182
|
+
|
|
183
|
+
\\ the real embeddings must all be >0
|
|
184
|
+
|
|
185
|
+
for( i = 1, nf.r1,
|
|
186
|
+
if( nfrealsign(nf,a,i) < 0,
|
|
187
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[]));
|
|
188
|
+
return([])));
|
|
189
|
+
|
|
190
|
+
\\ factorization over nf of the polynomial X^2-a
|
|
191
|
+
|
|
192
|
+
if( variable(nf.pol) == 'x,
|
|
193
|
+
py = subst(nf.pol,'x,'y);
|
|
194
|
+
pfact = lift(factornf('x^2-mysubst(alift,Mod('y,py)),py)[1,1])
|
|
195
|
+
,
|
|
196
|
+
pfact = lift(factornf('x^2-a,nf.pol)[1,1]));
|
|
197
|
+
if( poldegree(pfact) == 2,
|
|
198
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",[]));
|
|
199
|
+
return([]));
|
|
200
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrt ",pfact));
|
|
201
|
+
return([subst(polcoeff(pfact,0),'y,Mod(variable(nf.pol),nf.pol))]);
|
|
202
|
+
}
|
|
203
|
+
{nfrealsign(nf,a,i) =
|
|
204
|
+
\\ return the sign of the algebraic number a in the i-th real embedding.
|
|
205
|
+
local(nf_roots,ay,prec0);
|
|
206
|
+
|
|
207
|
+
if( a == 0, return(0));
|
|
208
|
+
|
|
209
|
+
a = lift(a);
|
|
210
|
+
if( type(a) != "t_POL",
|
|
211
|
+
return(sign(a)));
|
|
212
|
+
|
|
213
|
+
nf_roots = nf.roots;
|
|
214
|
+
prec0 = default(realprecision);
|
|
215
|
+
|
|
216
|
+
ay = 0;
|
|
217
|
+
while( ay == 0 || precision(ay) < 38,
|
|
218
|
+
|
|
219
|
+
ay = subst(a,variable(a),nf_roots[i]);
|
|
220
|
+
|
|
221
|
+
if( ay == 0 || precision(ay) < 38,
|
|
222
|
+
if( DEBUGLEVEL_ell >= 3,
|
|
223
|
+
print(" **** Warning: doubling the real precision in nfrealsign **** ",
|
|
224
|
+
2*default(realprecision)));
|
|
225
|
+
default(realprecision,2*default(realprecision));
|
|
226
|
+
nf_roots = real(polroots(nf.pol))
|
|
227
|
+
)
|
|
228
|
+
);
|
|
229
|
+
default(realprecision,prec0);
|
|
230
|
+
|
|
231
|
+
return(sign(ay));
|
|
232
|
+
}
|
|
233
|
+
{sqrtrat(a) =
|
|
234
|
+
sqrtint(numerator(a))/sqrtint(denominator(a));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
238
|
+
\\ FUNCTIONS SPECIFIC TO ell.gp \\
|
|
239
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
240
|
+
|
|
241
|
+
{nfpolratroots(nf,pol) =
|
|
242
|
+
local(f,ans);
|
|
243
|
+
f = nffactor(nf,lift(pol))[,1];
|
|
244
|
+
ans = [];
|
|
245
|
+
for( j = 1, #f,
|
|
246
|
+
if( poldegree(f[j]) == 1,
|
|
247
|
+
ans = concat(ans,[-polcoeff(f[j],0)/polcoeff(f[j],1)])));
|
|
248
|
+
return(ans);
|
|
249
|
+
}
|
|
250
|
+
{mynfhilbert2(nf,a,b,p) =
|
|
251
|
+
\\ p is a prime output by idealprimedec() above 2
|
|
252
|
+
local(v,res);
|
|
253
|
+
|
|
254
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting mynfhilbert2"));
|
|
255
|
+
v = idealval(nf,a,p)\2;
|
|
256
|
+
if( v, a *= nfbasistoalg(nf,p[2])^(-2*v));
|
|
257
|
+
|
|
258
|
+
v = idealval(nf,b,p)\2;
|
|
259
|
+
if( v, b *= nfbasistoalg(nf,p[2])^(-2*v));
|
|
260
|
+
|
|
261
|
+
if( nfqp_soluble(nf,a*'x^2+b,initp(nf,p)), res = 1, res = -1);
|
|
262
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of mynfhilbert2",res));
|
|
263
|
+
return(res);
|
|
264
|
+
}
|
|
265
|
+
{mynfhilbertp(nf,a,b,p) =
|
|
266
|
+
\\ calcule le symbole de Hilbert quadratique local (a,b)_p
|
|
267
|
+
\\ * en l'ideal premier p du corps nf,
|
|
268
|
+
\\ * a et b sont des elements non nuls de nf, sous la forme
|
|
269
|
+
\\ * de polmods ou de polynomes, et p renvoye par idealprimedec().
|
|
270
|
+
|
|
271
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting mynfhilbertp at ",p));
|
|
272
|
+
if( a == 0 || b == 0, error("mynfhilbertp: argument = 0"));
|
|
273
|
+
if( p.p == 2,
|
|
274
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of mynfhilbertp"));
|
|
275
|
+
return(mynfhilbert2(nf,a,b,p)));
|
|
276
|
+
if( type(a) != "t_POLMOD", a = Mod(a,nf.pol));
|
|
277
|
+
if( type(b) != "t_POLMOD", b = Mod(b,nf.pol));
|
|
278
|
+
return(nfhilbert(nf,a,b,p));
|
|
279
|
+
}
|
|
280
|
+
{ideallistfactor(nf,listfact) =
|
|
281
|
+
local(Slist,S1,test,k);
|
|
282
|
+
|
|
283
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting ideallistfactor"));
|
|
284
|
+
Slist = []; test = 1;
|
|
285
|
+
for( i = 1, #listfact,
|
|
286
|
+
if( listfact[i] == 0, next);
|
|
287
|
+
S1 = idealfactor(nf,listfact[i])[,1];
|
|
288
|
+
for( j = 1, #S1, k = #Slist;
|
|
289
|
+
for( k = 1, #Slist,
|
|
290
|
+
if( Slist[k] == S1[j], test = 0; break));
|
|
291
|
+
if( test, Slist = concat(Slist,[S1[j]]), test = 1);
|
|
292
|
+
));
|
|
293
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of ideallistfactor"));
|
|
294
|
+
return(Slist);
|
|
295
|
+
}
|
|
296
|
+
{mynfhilbert(nf,a,b) =
|
|
297
|
+
\\ calcule le symbole de Hilbert quadratique global (a,b):
|
|
298
|
+
\\ =1 si l'equation X^2-aY^2-bZ^2=0 a une solution non triviale,
|
|
299
|
+
\\ =-1 sinon,
|
|
300
|
+
\\ a et b doivent etre non nuls.
|
|
301
|
+
local(al,bl,S);
|
|
302
|
+
|
|
303
|
+
if( DEBUGLEVEL_ell >= 4, print(" starting mynfhilbert ",[a,b]));
|
|
304
|
+
if( a == 0 || b == 0, error("mynfhilbert : argument = 0"));
|
|
305
|
+
al = lift(a); bl = lift(b);
|
|
306
|
+
|
|
307
|
+
\\ solutions locales aux places reelles
|
|
308
|
+
|
|
309
|
+
for( i = 1, nf.r1,
|
|
310
|
+
if( nfrealsign(nf,al,i) < 0 && nfrealsign(nf,bl,i) < 0,
|
|
311
|
+
if( DEBUGLEVEL_ell >= 3, print(" mynfhilbert: no solution at infinity"));
|
|
312
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of mynfhilbert"));
|
|
313
|
+
return(-1))
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
if( type(a) != "t_POLMOD", a = Mod(a,nf.pol));
|
|
317
|
+
if( type(b) != "t_POLMOD", b = Mod(b,nf.pol));
|
|
318
|
+
|
|
319
|
+
\\ solutions locales aux places finies (celles qui divisent 2ab)
|
|
320
|
+
|
|
321
|
+
S = ideallistfactor(nf,[2,a,b]);
|
|
322
|
+
forstep ( i = #S, 2, -1,
|
|
323
|
+
\\ d'apres la formule du produit on peut eviter un premier
|
|
324
|
+
if( mynfhilbertp(nf,a,b, S[i]) == -1,
|
|
325
|
+
if( DEBUGLEVEL_ell >= 3, print(" mynfhilbert: no solution at: ",S[i]));
|
|
326
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of mynfhilbert"));
|
|
327
|
+
return(-1)));
|
|
328
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of mynfhilbert"));
|
|
329
|
+
return(1);
|
|
330
|
+
}
|
|
331
|
+
{initp( nf, p) =
|
|
332
|
+
\\ pp[1] est l'ideal sous forme reduite
|
|
333
|
+
\\ pp[2] est un entier de Zk avec une valuation 1 en p
|
|
334
|
+
\\ pp[3] est la valuation de 2 en p
|
|
335
|
+
\\ pp[4] sert a detecter les carres dans Qp
|
|
336
|
+
\\ si p|2 il faut la structure de Zk/p^(1+2v) d'apres Hensel
|
|
337
|
+
\\ sinon il suffit de calculer x^(N(p)-1)/2
|
|
338
|
+
\\ pp[5] est un systeme de representants de Zk/p
|
|
339
|
+
\\ c'est donc un ensemble de cardinal p^f .
|
|
340
|
+
local(idval,pp);
|
|
341
|
+
|
|
342
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting initp for p = ",p));
|
|
343
|
+
idval = idealval(nf,2,p);
|
|
344
|
+
pp=[ p, nfbasistoalg(nf,p[2]), idval, 0, repres(nf,p) ];
|
|
345
|
+
if( idval,
|
|
346
|
+
pp[4] = idealstar(nf,idealpow(nf,p,1+2*idval)),
|
|
347
|
+
pp[4] = p.p^p.f\2 );
|
|
348
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of initp"));
|
|
349
|
+
return(pp);
|
|
350
|
+
}
|
|
351
|
+
{deno(num) =
|
|
352
|
+
\\ calcule un denominateur du polynome num
|
|
353
|
+
|
|
354
|
+
if( num == 0, return(1));
|
|
355
|
+
if( type(num) == "t_POL",
|
|
356
|
+
return(denominator(content(num))));
|
|
357
|
+
return(denominator(num));
|
|
358
|
+
}
|
|
359
|
+
{nfratpoint(nf,pol,lim,singlepoint=1) =
|
|
360
|
+
\\ Si singlepoint == 1, cherche un seul point, sinon plusieurs.
|
|
361
|
+
local(compt1,compt2,deg,n,AA,point,listpoints,vectx,evpol,sq,xpol);
|
|
362
|
+
|
|
363
|
+
if( DEBUGLEVEL_ell >= 4,
|
|
364
|
+
print(" starting nfratpoint with pol = ",pol);
|
|
365
|
+
print(" lim = ",lim));
|
|
366
|
+
|
|
367
|
+
compt1 = 0; compt2 = 0;
|
|
368
|
+
deg = poldegree(pol); n = poldegree(nf.pol);
|
|
369
|
+
AA = lim<<1;
|
|
370
|
+
if( !singlepoint, listpoints = []);
|
|
371
|
+
|
|
372
|
+
\\ cas triviaux
|
|
373
|
+
sq = nfsqrt(nf,polcoeff(pol,0));
|
|
374
|
+
if( sq!= [],
|
|
375
|
+
point = [ 0, sq[1], 1];
|
|
376
|
+
if( singlepoint,
|
|
377
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfratpoint"));
|
|
378
|
+
return(point));
|
|
379
|
+
listpoints = concat(listpoints,[point])
|
|
380
|
+
);
|
|
381
|
+
sq = nfsqrt(nf,pollead(pol));
|
|
382
|
+
if( sq != [],
|
|
383
|
+
point = [ 1, sq[1], 0];
|
|
384
|
+
if( singlepoint,
|
|
385
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfratpoint"));
|
|
386
|
+
return(point));
|
|
387
|
+
listpoints = concat(listpoints,[point])
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
\\ boucle generale
|
|
391
|
+
point = [];
|
|
392
|
+
vectx = vector(n,i,[-lim,lim]);
|
|
393
|
+
for( denoz = 1, lim,
|
|
394
|
+
if( poldegree(pol)%2 == 0 &&
|
|
395
|
+
!issquare(Mod(norm(pollead(pol)),denoz)), next);
|
|
396
|
+
forvec( xx = vectx,
|
|
397
|
+
if( denoz == 1 || gcd(content(xx),denoz) == 1,
|
|
398
|
+
xpol = nfbasistoalg(nf,xx~);
|
|
399
|
+
evpol = subst(pol,'x,xpol/denoz);
|
|
400
|
+
sq = nfsqrt(nf,evpol);
|
|
401
|
+
if( sq != [],
|
|
402
|
+
point = [xpol/denoz, sq[1], 1];
|
|
403
|
+
if( singlepoint, break(2));
|
|
404
|
+
listpoints = concat(listpoints,[point])));
|
|
405
|
+
));
|
|
406
|
+
|
|
407
|
+
if( singlepoint, listpoints = point);
|
|
408
|
+
if( DEBUGLEVEL_ell >= 3, print(" points found by nfratpoint = ",listpoints));
|
|
409
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfratpoint"));
|
|
410
|
+
return(Vec(listpoints));
|
|
411
|
+
}
|
|
412
|
+
{repres(nf,p) =
|
|
413
|
+
\\ calcule un systeme de representants Zk/p
|
|
414
|
+
local(fond,mat,f,rep,pp,ppi,pp2,jppi,gjf);
|
|
415
|
+
|
|
416
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting repres"));
|
|
417
|
+
fond = [];
|
|
418
|
+
mat = idealhnf(nf,p);
|
|
419
|
+
for( i = 1, #mat,
|
|
420
|
+
if( mat[i,i] != 1, fond = concat(fond, nf.zk[i])));
|
|
421
|
+
f = #fond;
|
|
422
|
+
pp = p.p;
|
|
423
|
+
rep = vector(pp^f,i,0);
|
|
424
|
+
rep[1] = 0;
|
|
425
|
+
ppi = 1;
|
|
426
|
+
pp2 = pp\2;
|
|
427
|
+
for( i = 1, f,
|
|
428
|
+
for( j = 1, pp-1,
|
|
429
|
+
if( j <= pp2, gjf = j*fond[i], gjf = (j-pp)*fond[i]);
|
|
430
|
+
jppi = j*ppi;
|
|
431
|
+
for( k = 0, ppi-1, rep[jppi+k+1] = rep[k+1]+gjf ));
|
|
432
|
+
ppi *= pp);
|
|
433
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of repres"));
|
|
434
|
+
return(Mod(rep,nf.pol));
|
|
435
|
+
}
|
|
436
|
+
{val(nf,num,p) =
|
|
437
|
+
if( num == 0, 32000, idealval(nf,lift(num),p));
|
|
438
|
+
}
|
|
439
|
+
{nfissquaremodpodd( nf, a, p) =
|
|
440
|
+
\\ Return 1 if a is a p-adic square, 0 otherwise.
|
|
441
|
+
\\ Only for a prime ideal p coprime to 2.
|
|
442
|
+
\\ a = t_POLMOD
|
|
443
|
+
local(v,ap,norme,den);
|
|
444
|
+
|
|
445
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nfissquaremodpodd"));
|
|
446
|
+
if( a == 0,
|
|
447
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd"));
|
|
448
|
+
return(1));
|
|
449
|
+
v = idealval(nf,lift(a),p);
|
|
450
|
+
if( v%2,
|
|
451
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd"));
|
|
452
|
+
return(0));
|
|
453
|
+
ap = a/nfbasistoalg(nf,p[2])^v;
|
|
454
|
+
|
|
455
|
+
norme = (p.p^p.f-1)/2;
|
|
456
|
+
den = denominator(content(lift(ap)))%p.p;
|
|
457
|
+
if( sign(den), ap *= Mod(1,p.p));
|
|
458
|
+
ap = ap^norme-1;
|
|
459
|
+
if( ap == 0,
|
|
460
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd"));
|
|
461
|
+
return(1));
|
|
462
|
+
ap = lift(lift(ap));
|
|
463
|
+
if( idealval(nf,ap,p) > 0,
|
|
464
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd"));
|
|
465
|
+
return(1));
|
|
466
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpodd"));
|
|
467
|
+
return(0);
|
|
468
|
+
}
|
|
469
|
+
{nfissquaremodp( nf, a, p, zinit) =
|
|
470
|
+
\\ a is an algebraic integer of nf
|
|
471
|
+
\\ returns 1 if a is a square modulo the prime ideal p, 0 otherwise
|
|
472
|
+
\\ a = t_POLMOD
|
|
473
|
+
local(valap,zlog);
|
|
474
|
+
|
|
475
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nfissquaremodp ",[a,p,zinit]));
|
|
476
|
+
if( a == 0,
|
|
477
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp"));
|
|
478
|
+
return(1));
|
|
479
|
+
|
|
480
|
+
if( p.p != 2,
|
|
481
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp"));
|
|
482
|
+
return(nfissquaremodpodd(nf,a,p)));
|
|
483
|
+
|
|
484
|
+
valap = idealval(nf,a,p);
|
|
485
|
+
if( valap%2,
|
|
486
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp"));
|
|
487
|
+
return(0));
|
|
488
|
+
if( valap,
|
|
489
|
+
zlog = ideallog(nf,a*(nf_scalar_or_multable_to_alg(nf,p[5])/p.p)^valap,zinit)
|
|
490
|
+
,
|
|
491
|
+
zlog = ideallog(nf,a,zinit));
|
|
492
|
+
for( i = 1, #zinit[2][2],
|
|
493
|
+
if( !(zinit[2][2][i]%2) && (zlog[i]%2),
|
|
494
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp"));
|
|
495
|
+
return(0)));
|
|
496
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodp"));
|
|
497
|
+
return(1);
|
|
498
|
+
}
|
|
499
|
+
{nfissquaremodpq( nf, a, p, q) =
|
|
500
|
+
\\ cette fonction renvoie 1 si a est un carre
|
|
501
|
+
\\ ?inversible? modulo P^q et 0 sinon.
|
|
502
|
+
\\ P divise 2, et ?(a,p)=1?.
|
|
503
|
+
local(vala,zinit,zlog);
|
|
504
|
+
|
|
505
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nfissquaremodpq ",[a,p,q]));
|
|
506
|
+
if( a == 0,
|
|
507
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq"));
|
|
508
|
+
return(1));
|
|
509
|
+
vala = idealval(nf,a,p);
|
|
510
|
+
if( vala >= q,
|
|
511
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq"));
|
|
512
|
+
return(1));
|
|
513
|
+
if( vala%2,
|
|
514
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq"));
|
|
515
|
+
return(0));
|
|
516
|
+
zinit = idealstar(nf,idealpow(nf,p,q-vala),2);
|
|
517
|
+
zlog = ideallog(nf,a*nf_scalar_or_multable_to_alg(nf,p[5]/2)^vala,zinit);
|
|
518
|
+
for( i = 1, #zinit[2][2],
|
|
519
|
+
if( !(zinit[2][2][i]%2) && (zlog[i]%2),
|
|
520
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq"));
|
|
521
|
+
return(0)));
|
|
522
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfissquaremodpq"));
|
|
523
|
+
return(1);
|
|
524
|
+
}
|
|
525
|
+
{nfsqrtmodpq(nf,a,p,q) =
|
|
526
|
+
\\ suppose que a est un carre modulo p^q
|
|
527
|
+
\\ et renvoie x tel que x^2 = a mod p^q.
|
|
528
|
+
local(p_hnf,f,aaa,qq,e,xx,yy,r,aux,b,m,vp,inv2x,zinit,zlog,expo,p_ini,non_sq,id);
|
|
529
|
+
|
|
530
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nfsqrtmodpq ",a,p,q));
|
|
531
|
+
if( a == 0 || a == 1,
|
|
532
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrtmodpq"));
|
|
533
|
+
return(a));
|
|
534
|
+
f = idealval(nf,a,p);
|
|
535
|
+
if( f >= q,
|
|
536
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrtmodpq"));
|
|
537
|
+
return(0));
|
|
538
|
+
if( f%2, error("nfsqrtmodpq: a is not a square, odd valuation"));
|
|
539
|
+
a = nfalgtobasis(nf,a);
|
|
540
|
+
if( f, aaa = nfeltpow(nf,nfeltdiv(nf,a,nf_scalar_or_multable_to_alg(nf,p[5]/p.p)),f), aaa = a);
|
|
541
|
+
p_hnf = idealhnf(nf,p);
|
|
542
|
+
p_ini = nfmodprinit(nf,p);
|
|
543
|
+
if( DEBUGLEVEL_ell >= 5, print(" p_hnf = ",p_hnf));
|
|
544
|
+
if( DEBUGLEVEL_ell >= 5, print(" p_ini = ",p_ini));
|
|
545
|
+
|
|
546
|
+
if( p.p != 2,
|
|
547
|
+
\\ first case : p is odd
|
|
548
|
+
|
|
549
|
+
\\ Shanks sqrt algorithm
|
|
550
|
+
if( DEBUGLEVEL_ell >= 5, print(" Shanks sqrt algorithm"));
|
|
551
|
+
non_sq = nfrandintmodid(nf,p_hnf);
|
|
552
|
+
while( nfissquaremodpodd(nf,non_sq,p), non_sq = nfrandintmodid(nf,p_hnf));
|
|
553
|
+
non_sq = nfalgtobasis(nf,non_sq);
|
|
554
|
+
qq = ( p.p^p.f -1) \ 2;
|
|
555
|
+
e = 1; while( !(qq%2), e++; qq \= 2);
|
|
556
|
+
non_sq = nfeltpowmodpr(nf,non_sq,qq,p_ini);
|
|
557
|
+
yy = non_sq; r = e;
|
|
558
|
+
xx = nfeltpowmodpr(nf,aaa,qq\2,p_ini);
|
|
559
|
+
aux = nfeltmulmodpr(nf,aaa,xx,p_ini);
|
|
560
|
+
b = nfeltmulmodpr(nf,aux,xx,p_ini);
|
|
561
|
+
xx = aux;
|
|
562
|
+
aux = b; m = 0;
|
|
563
|
+
while( !val(nf,nfbasistoalg(nf,aux)-1,p),
|
|
564
|
+
m++;
|
|
565
|
+
aux = nfeltpowmodpr(nf,aux,2,p_ini)
|
|
566
|
+
);
|
|
567
|
+
while( m,
|
|
568
|
+
if( m == r, error("nfsqrtmodpq: m = r"));
|
|
569
|
+
aux = nfeltpowmodpr(nf,yy,1<<(r-m-1),p_ini);
|
|
570
|
+
yy = nfeltpowmodpr(nf,aux,2,p_ini);
|
|
571
|
+
r = m;
|
|
572
|
+
xx = nfeltmulmodpr(nf,xx,aux,p_ini);
|
|
573
|
+
b = nfeltmulmodpr(nf,b,yy,p_ini);
|
|
574
|
+
aux = b;m = 0;
|
|
575
|
+
while( !val(nf,nfbasistoalg(nf,aux)-1,p),
|
|
576
|
+
m++;
|
|
577
|
+
aux = nfeltpowmodpr(nf,aux,2,p_ini)
|
|
578
|
+
)
|
|
579
|
+
);
|
|
580
|
+
|
|
581
|
+
\\ lift de Hensel
|
|
582
|
+
\\
|
|
583
|
+
|
|
584
|
+
xx = nfbasistoalg(nf,xx);
|
|
585
|
+
aaa= nfbasistoalg(nf,aaa);
|
|
586
|
+
if( q > 1,
|
|
587
|
+
if( DEBUGLEVEL_ell >= 5, print(" Hensel lifting"));
|
|
588
|
+
vp = idealval(nf,xx^2-aaa,p);
|
|
589
|
+
if( vp < q-f,
|
|
590
|
+
yy = 2*xx;
|
|
591
|
+
inv2x = nfbasistoalg(nf,idealaddtoone(nf,yy,p)[1])/yy;
|
|
592
|
+
while( vp < q, vp++; xx -= (xx^2-aaa)*inv2x);
|
|
593
|
+
);
|
|
594
|
+
if( f, xx *= nfbasistoalg(nf,p[2])^(f\2));
|
|
595
|
+
);
|
|
596
|
+
xx = mynfeltreduce(nf,xx,idealpow(nf,p,q))
|
|
597
|
+
,
|
|
598
|
+
\\ cas ou p divise 2 */
|
|
599
|
+
if( q-f > 1, id = idealpow(nf,p,q-f), id = p_hnf);
|
|
600
|
+
zinit = idealstar(nf,id,2);
|
|
601
|
+
zlog = ideallog(nf,aaa,zinit);
|
|
602
|
+
xx = 1;
|
|
603
|
+
for( i = 1, #zlog,
|
|
604
|
+
expo = zlog[i];
|
|
605
|
+
if( expo,
|
|
606
|
+
if( !expo%2,
|
|
607
|
+
expo = expo>>1
|
|
608
|
+
, aux = zinit[2][i];
|
|
609
|
+
expo = expo*((aux+1)>>1)%aux
|
|
610
|
+
);
|
|
611
|
+
xx *= nfbasistoalg(nf,zinit[2][3][i])^expo
|
|
612
|
+
)
|
|
613
|
+
);
|
|
614
|
+
if( f,
|
|
615
|
+
xx *= nfbasistoalg(nf,p[2])^(f>>1);
|
|
616
|
+
id = idealpow(nf,p,q));
|
|
617
|
+
xx = mynfeltreduce(nf,xx,id);
|
|
618
|
+
);
|
|
619
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfsqrtmodpq ",xx));
|
|
620
|
+
return(xx);
|
|
621
|
+
}
|
|
622
|
+
{nflemma6( nf, pol, p, nu, xx) =
|
|
623
|
+
local(gx,gpx,lambda,mu);
|
|
624
|
+
|
|
625
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nflemma6"));
|
|
626
|
+
gx = subst( pol, 'x, xx);
|
|
627
|
+
if( nfissquaremodpodd(nf,gx,p),
|
|
628
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6"));
|
|
629
|
+
return(1));
|
|
630
|
+
gpx = subst( pol', 'x, xx);
|
|
631
|
+
lambda = val(nf,gx,p);mu = val(nf,gpx,p);
|
|
632
|
+
|
|
633
|
+
if( lambda>2*mu,
|
|
634
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6"));
|
|
635
|
+
return(1));
|
|
636
|
+
if( (lambda >= 2*nu) && (mu >= nu),
|
|
637
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6"));
|
|
638
|
+
return(0));
|
|
639
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nflemma6"));
|
|
640
|
+
return(-1);
|
|
641
|
+
}
|
|
642
|
+
{nflemma7( nf, pol, p, nu, xx, zinit) =
|
|
643
|
+
local(gx,gpx,v,lambda,mu,q);
|
|
644
|
+
|
|
645
|
+
if( DEBUGLEVEL_ell >= 5, print("entree dans nflemma7 ",[xx,nu]));
|
|
646
|
+
gx = subst( pol, 'x, xx);
|
|
647
|
+
if( nfissquaremodp(nf,gx,p,zinit),
|
|
648
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
649
|
+
return(1));
|
|
650
|
+
gpx = subst( pol', 'x, xx);
|
|
651
|
+
v = p[3];
|
|
652
|
+
lambda = val(nf,gx,p);mu = val(nf,gpx,p);
|
|
653
|
+
if( lambda>2*mu,
|
|
654
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
655
|
+
return(1));
|
|
656
|
+
if( nu > mu,
|
|
657
|
+
if( lambda%2,
|
|
658
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
659
|
+
return(-1));
|
|
660
|
+
q = mu+nu-lambda;
|
|
661
|
+
if( q > 2*v,
|
|
662
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
663
|
+
return(-1));
|
|
664
|
+
if( nfissquaremodpq(nf,gx*nf_scalar_or_multable_to_alg(nf,p[5]/2)^lambda,p,q),
|
|
665
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
666
|
+
return(1))
|
|
667
|
+
,
|
|
668
|
+
if( lambda >= 2*nu,
|
|
669
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
670
|
+
return(0));
|
|
671
|
+
if( lambda%2,
|
|
672
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
673
|
+
return(-1));
|
|
674
|
+
q = 2*nu-lambda;
|
|
675
|
+
if( q > 2*v,
|
|
676
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
677
|
+
return(-1));
|
|
678
|
+
if( nfissquaremodpq(nf,gx*nf_scalar_or_multable_to_alg(nf,p[5]/2)^lambda,p,q),
|
|
679
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
680
|
+
return(0))
|
|
681
|
+
);
|
|
682
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nflemma7"));
|
|
683
|
+
return(-1);
|
|
684
|
+
}
|
|
685
|
+
{nfzp_soluble( nf, pol, p, nu, pnu, x0) =
|
|
686
|
+
local(result,pnup,lrep);
|
|
687
|
+
|
|
688
|
+
if( DEBUGLEVEL_ell >= 5, print("entree dans nfzp_soluble ",[lift(x0),nu]));
|
|
689
|
+
if( p[3] == 0,
|
|
690
|
+
result = nflemma6(nf,pol,p[1],nu,x0),
|
|
691
|
+
result = nflemma7(nf,pol,p[1],nu,x0,p[4]));
|
|
692
|
+
if( result == +1,
|
|
693
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble"));
|
|
694
|
+
return(1));
|
|
695
|
+
if( result == -1,
|
|
696
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble"));
|
|
697
|
+
return(0));
|
|
698
|
+
pnup = pnu*p[2];
|
|
699
|
+
lrep = #p[5];
|
|
700
|
+
nu++;
|
|
701
|
+
for( i = 1, lrep,
|
|
702
|
+
if( nfzp_soluble(nf,pol,p,nu,pnup,x0+pnu*p[5][i]),
|
|
703
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble"));
|
|
704
|
+
return(1)));
|
|
705
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nfzp_soluble"));
|
|
706
|
+
return(0);
|
|
707
|
+
}
|
|
708
|
+
{mynfeltmod(nf,a,b) =
|
|
709
|
+
local(qred);
|
|
710
|
+
|
|
711
|
+
qred = round(nfalgtobasis(nf,a/b));
|
|
712
|
+
qred = a-b*nfbasistoalg(nf,qred);
|
|
713
|
+
return(qred);
|
|
714
|
+
}
|
|
715
|
+
{mynfeltreduce(nf,a,id) =
|
|
716
|
+
nfbasistoalg(nf,nfeltreduce(nf,nfalgtobasis(nf,a),id));
|
|
717
|
+
}
|
|
718
|
+
{nfrandintmodid( nf, id) =
|
|
719
|
+
local(res);
|
|
720
|
+
|
|
721
|
+
if( DEBUGLEVEL_ell >= 5, print("entree dans nfrandintmodid"));
|
|
722
|
+
res = 0;
|
|
723
|
+
while( !res,
|
|
724
|
+
res = nfrandint(nf,0);
|
|
725
|
+
res = mynfeltreduce(nf,res,id));
|
|
726
|
+
if( DEBUGLEVEL_ell >= 5, print("fin de nfrandintmodid"));
|
|
727
|
+
return(res);
|
|
728
|
+
}
|
|
729
|
+
{nfrandint( nf, borne) =
|
|
730
|
+
local(d,res);
|
|
731
|
+
|
|
732
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nfrandint"));
|
|
733
|
+
d = poldegree(nf.pol);
|
|
734
|
+
res = vectorv(d,i,if( borne, random(borne<<1)-borne, random()));
|
|
735
|
+
res = nfbasistoalg(nf,res);
|
|
736
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfrandint"));
|
|
737
|
+
return(res);
|
|
738
|
+
}
|
|
739
|
+
{nfqp_solublebig( nf, pol, p,ap=0,b=1) =
|
|
740
|
+
local(deg,xx,z,Px,cont,pi,pol2,Roots);
|
|
741
|
+
|
|
742
|
+
if( DEBUGLEVEL_ell >= 4, print(" starting nfqp_solublebig avec ",p.p));
|
|
743
|
+
deg = poldegree(pol);
|
|
744
|
+
|
|
745
|
+
if( nfissquaremodpodd(nf,polcoeff(pol,0),p),
|
|
746
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig"));
|
|
747
|
+
return(1));
|
|
748
|
+
if( nfissquaremodpodd(nf,pollead(pol),p),
|
|
749
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig"));
|
|
750
|
+
return(1));
|
|
751
|
+
|
|
752
|
+
\\ on tient compte du contenu de pol
|
|
753
|
+
cont = idealval(nf,polcoeff(pol,0),p);
|
|
754
|
+
for( i = 1, deg,
|
|
755
|
+
if( cont, cont = min(cont,idealval(nf,polcoeff(pol,i),p))));
|
|
756
|
+
if( cont, pi = nf_scalar_or_multable_to_alg(nf,p[5]/p.p));
|
|
757
|
+
if( cont > 1, pol *= pi^(2*(cont\2)));
|
|
758
|
+
|
|
759
|
+
\\ On essaye des valeurs de x au hasard
|
|
760
|
+
if( cont%2,
|
|
761
|
+
pol2 = pol*pi
|
|
762
|
+
, pol2 = pol;
|
|
763
|
+
for( i = 1, MAXPROB,
|
|
764
|
+
xx = nfrandint(nf,0);
|
|
765
|
+
z = 0; while( !z, z = random());
|
|
766
|
+
xx = -ap*z+b*xx;
|
|
767
|
+
Px=polcoeff(pol,deg);
|
|
768
|
+
forstep (j=deg-1,0,-1,Px=Px*xx+polcoeff(pol,j));
|
|
769
|
+
Px *= z^deg;
|
|
770
|
+
if( nfissquaremodpodd(nf,Px,p),
|
|
771
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig"));
|
|
772
|
+
return(1));
|
|
773
|
+
)
|
|
774
|
+
);
|
|
775
|
+
|
|
776
|
+
\\ On essaye les racines de pol
|
|
777
|
+
Roots = nfpolrootsmod(nf,pol2,p);
|
|
778
|
+
pi = nfbasistoalg(nf,p[2]);
|
|
779
|
+
for( i = 1, #Roots,
|
|
780
|
+
if( nfqp_solublebig(nf,subst(pol,'x,pi*'x+Roots[i]),p),
|
|
781
|
+
if( DEBUGLEVEL_ell >= 4, print("fin de nfqp_solublebig"));
|
|
782
|
+
return(1)));
|
|
783
|
+
|
|
784
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfqp_solublebig"));
|
|
785
|
+
return(0);
|
|
786
|
+
}
|
|
787
|
+
{nfpolrootsmod(nf,pol,p) =
|
|
788
|
+
\\ calcule les racines modulo l'ideal p du polynome pol.
|
|
789
|
+
\\ p est un ideal premier de nf, sous la forme idealprimedec
|
|
790
|
+
local(factlist,sol);
|
|
791
|
+
|
|
792
|
+
factlist = nffactormod(nf,pol,p)[,1];
|
|
793
|
+
sol = [];
|
|
794
|
+
for( i = 1, #factlist,
|
|
795
|
+
if( poldegree(factlist[i]) == 1,
|
|
796
|
+
sol = concat(sol, [-polcoeff(factlist[i],0)/polcoeff(factlist[i],1)])));
|
|
797
|
+
return(sol);
|
|
798
|
+
}
|
|
799
|
+
{nfqp_soluble( nf, pol, p) =
|
|
800
|
+
\\ p is a prime output by initp()
|
|
801
|
+
\\ return 1 if pol(x) = y^2 has a p-adic rational solution
|
|
802
|
+
\\ (possibly oo)
|
|
803
|
+
\\ coeff of nfqfsoluble must be integers.
|
|
804
|
+
|
|
805
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting nfqp_soluble ",p));
|
|
806
|
+
if( DEBUGLEVEL_ell >= 5, print(" pol = ",pol));
|
|
807
|
+
if( nfissquaremodp(nf,pollead(pol),p[1],p[4]),
|
|
808
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble"));
|
|
809
|
+
return(1));
|
|
810
|
+
if( nfissquaremodp(nf,polcoeff(pol,0),p[1],p[4]),
|
|
811
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble"));
|
|
812
|
+
return(1));
|
|
813
|
+
if( nfzp_soluble(nf,pol,p,0,1,0),
|
|
814
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble"));
|
|
815
|
+
return(1));
|
|
816
|
+
if( nfzp_soluble(nf,polrecip(pol),p,1, p[2],0),
|
|
817
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble"));
|
|
818
|
+
return(1));
|
|
819
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of nfqp_soluble"));
|
|
820
|
+
return(0);
|
|
821
|
+
}
|
|
822
|
+
{nflocallysoluble( nf, pol, r=0,a=1,b=1) =
|
|
823
|
+
\\ Test whether Y^2 = pol is Everywhere Locally Soluble
|
|
824
|
+
local(pol0,plist,add,ff,p,Delta,c,s,t);
|
|
825
|
+
|
|
826
|
+
if( DEBUGLEVEL_ell >= 4, print(" starting nflocallysoluble ",[pol,r,a,b]));
|
|
827
|
+
pol0 = pol;
|
|
828
|
+
|
|
829
|
+
\\ places finies
|
|
830
|
+
|
|
831
|
+
pol *= deno(content(lift(pol)))^2;
|
|
832
|
+
for( ii = 1, 3,
|
|
833
|
+
if( ii == 1, plist = idealprimedec(nf,2));
|
|
834
|
+
if( ii == 2 && r, plist = idealfactor(nf,poldisc(pol0/pollead(pol0))/pollead(pol0)^6/2^12)[,1]);
|
|
835
|
+
if( ii == 2 && !r, plist = idealfactor(nf,poldisc(pol0))[,1]);
|
|
836
|
+
if( ii == 3,
|
|
837
|
+
add = idealadd(nf,a,b);
|
|
838
|
+
ff = factor(idealnorm(nf,add))[,1];
|
|
839
|
+
addprimes(ff);
|
|
840
|
+
if( DEBUGLEVEL_ell >= 4, print(" list of primes = ",ff));
|
|
841
|
+
plist = idealfactor(nf,add)[,1]);
|
|
842
|
+
for( i = 1, #plist,
|
|
843
|
+
p = plist[i];
|
|
844
|
+
if( DEBUGLEVEL_ell >= 3, print(" p = ",p));
|
|
845
|
+
if( p.p < LIMBIGPRIME || !LIMBIGPRIME,
|
|
846
|
+
if( !nfqp_soluble(nf,pol,initp(nf,p)),
|
|
847
|
+
if( DEBUGLEVEL_ell >= 2, print(" not ELS at ",p));
|
|
848
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble"));
|
|
849
|
+
return(0)),
|
|
850
|
+
if( !nfqp_solublebig(nf,pol,p,r/a,b),
|
|
851
|
+
if( DEBUGLEVEL_ell >= 2, print(" not ELS at ",p.p," ( = big prime )"));
|
|
852
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble"));
|
|
853
|
+
return(0))));
|
|
854
|
+
);
|
|
855
|
+
|
|
856
|
+
\\ places reelles
|
|
857
|
+
|
|
858
|
+
/*
|
|
859
|
+
Peter Bruin, August 2014: code adapted to fix precision problems.
|
|
860
|
+
|
|
861
|
+
We want to count the number of real roots of a polynomial of the
|
|
862
|
+
form x^4 + s*x^2 + a*x + b. The action of complex conjugation on
|
|
863
|
+
the complex roots determines the sign of the discriminant Delta:
|
|
864
|
+
|
|
865
|
+
cycle type () or (1 2)(3 4), i.e. 4 or 0 real roots: Delta > 0
|
|
866
|
+
cycle type (1 2), i.e. exactly 2 real roots: Delta < 0
|
|
867
|
+
|
|
868
|
+
We may assume Delta > 0 and have to decide whether there are 0 or 4
|
|
869
|
+
real roots. We apply Sturm's theorem to the following sequence
|
|
870
|
+
(with t = 2*s^3 - 8*b*s + 9*a^2):
|
|
871
|
+
|
|
872
|
+
p0 = x^4 + s*x^2 + a*x + b
|
|
873
|
+
p1 = 4*x^3 + 2*s*x + a
|
|
874
|
+
p2 = x*p1 - 4*p0
|
|
875
|
+
= -2*s*x^2 - 3*a*x - 4*b
|
|
876
|
+
p3 = (3*a - 2*s*x)*p2 - s^2*p1
|
|
877
|
+
= -t*x - a*(s^2 + 12*b)
|
|
878
|
+
p4 = Delta
|
|
879
|
+
|
|
880
|
+
Note that the case of 4 real roots can only occur if both s and t
|
|
881
|
+
are nonzero, otherwise the Sturm sequence is shorter than this one.
|
|
882
|
+
By Sturm's theorem, the number of roots equals
|
|
883
|
+
|
|
884
|
+
(sign changes in [1, -4, -2*s, t, Delta]) -
|
|
885
|
+
(sign changes in [1, 4, -2*s, -t, Delta]).
|
|
886
|
+
|
|
887
|
+
Hence the only way to have 4 real roots is if s < 0 and t < 0.
|
|
888
|
+
*/
|
|
889
|
+
if( nf.r1,
|
|
890
|
+
c = pollead(pol);
|
|
891
|
+
pol /= c;
|
|
892
|
+
pol = subst(pol, 'x, 'x - polcoeff(pol, 3)/4);
|
|
893
|
+
s = polcoeff(pol, 2);
|
|
894
|
+
t = 2*s^3 - 8*s*polcoeff(pol, 0) + 9*polcoeff(pol, 1)^2;
|
|
895
|
+
Delta = poldisc(pol);
|
|
896
|
+
for( i = 1, nf.r1,
|
|
897
|
+
if( nfrealsign(nf,c,i) > 0, next);
|
|
898
|
+
if( nfrealsign(nf,Delta,i) < 0, next);
|
|
899
|
+
if( nfrealsign(nf,s,i) < 0 && nfrealsign(nf,t,i) < 0, next);
|
|
900
|
+
if( DEBUGLEVEL_ell >= 2, print(" not ELS at infinity"));
|
|
901
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble"));
|
|
902
|
+
return(0);
|
|
903
|
+
));
|
|
904
|
+
if( DEBUGLEVEL_ell >= 2, print(" quartic ELS "));
|
|
905
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nflocallysoluble"));
|
|
906
|
+
return(1);
|
|
907
|
+
}
|
|
908
|
+
{nfellcount( nf, c, d, KS2gen, pointstriv) =
|
|
909
|
+
local(found,listgen,listpointscount,m1,m2,lastloc,mask,i,d1,iaux,j,triv,pol,point,deuxpoints,aux,v);
|
|
910
|
+
|
|
911
|
+
if( DEBUGLEVEL_ell >= 4, print(" starting nfellcount ",[c,d]));
|
|
912
|
+
found = 0;
|
|
913
|
+
listgen = KS2gen;
|
|
914
|
+
listpointscount = [];
|
|
915
|
+
|
|
916
|
+
m1 = m2 = 0; lastloc = -1;
|
|
917
|
+
|
|
918
|
+
mask = 1 << #KS2gen;
|
|
919
|
+
i = 1;
|
|
920
|
+
while( i < mask,
|
|
921
|
+
d1 = 1; iaux = i; j = 1;
|
|
922
|
+
while( iaux,
|
|
923
|
+
if( iaux%2, d1 *= listgen[j]);
|
|
924
|
+
iaux >>= 1; j++);
|
|
925
|
+
if( DEBUGLEVEL_ell >= 2, print(" d1 = ",d1));
|
|
926
|
+
triv = 0;
|
|
927
|
+
for( j = 1, #pointstriv,
|
|
928
|
+
if( pointstriv[j][3]*pointstriv[j][1]
|
|
929
|
+
&& nfissquare(nf,d1*pointstriv[j][1]*pointstriv[j][3]),
|
|
930
|
+
listpointscount = concat(listpointscount,[pointstriv[j]]);
|
|
931
|
+
if( DEBUGLEVEL_ell >= 2, print(" comes from a trivial point"));
|
|
932
|
+
triv = 1; m1++;
|
|
933
|
+
if( degre(i) > lastloc, m2++);
|
|
934
|
+
found = 1; lastloc = -1; break
|
|
935
|
+
));
|
|
936
|
+
if( !triv,
|
|
937
|
+
pol = Pol([d1,0,c,0,d/d1]);
|
|
938
|
+
if( DEBUGLEVEL_ell >= 3, print(" quartic: y^2 = ",pol));
|
|
939
|
+
point = nfratpoint(nf,pol,LIM1,1);
|
|
940
|
+
if( point != [],
|
|
941
|
+
if( DEBUGLEVEL_ell >= 2, print(" point on the quartic"));
|
|
942
|
+
if( DEBUGLEVEL_ell >= 3, print(" ",point));
|
|
943
|
+
m1++;
|
|
944
|
+
if( point[3] != 0,
|
|
945
|
+
aux = d1*point[1]/point[3]^2;
|
|
946
|
+
deuxpoints = [ aux*point[1], aux*point[2]/point[3] ]
|
|
947
|
+
,
|
|
948
|
+
deuxpoints = [0]);
|
|
949
|
+
listpointscount = concat(listpointscount,[deuxpoints]);
|
|
950
|
+
if( degre(i) > lastloc, m2++);
|
|
951
|
+
found = 1; lastloc = -1
|
|
952
|
+
,
|
|
953
|
+
if( nflocallysoluble(nf,pol),
|
|
954
|
+
if( degre(i) > lastloc, m2++; lastloc = degre(i));
|
|
955
|
+
point = nfratpoint(nf,pol,LIM3,1);
|
|
956
|
+
if( point != [],
|
|
957
|
+
if( DEBUGLEVEL_ell >= 2, print(" point on the quartic"));
|
|
958
|
+
if( DEBUGLEVEL_ell >= 3, print(" ",point));
|
|
959
|
+
m1++;
|
|
960
|
+
aux = d1*point[1]/point[3]^2;
|
|
961
|
+
deuxpoints = [ aux*point[1], aux*point[2]/point[3] ];
|
|
962
|
+
listpointscount = concat(listpointscount,[deuxpoints]);
|
|
963
|
+
if( degre(i) > lastloc, m2++);
|
|
964
|
+
found = 1; lastloc = -1
|
|
965
|
+
,
|
|
966
|
+
if( DEBUGLEVEL_ell >= 2, print(" no point found on the quartic"));
|
|
967
|
+
))));
|
|
968
|
+
if( found,
|
|
969
|
+
found = 0;
|
|
970
|
+
v = 0; iaux = (i>>1);
|
|
971
|
+
while( iaux, iaux >>= 1; v++);
|
|
972
|
+
mask >>= 1;
|
|
973
|
+
listgen = vecextract(listgen,(1<<#listgen)-(1<<v)-1);
|
|
974
|
+
i = (1<<v)
|
|
975
|
+
, i++)
|
|
976
|
+
);
|
|
977
|
+
for( i = 1, #listpointscount,
|
|
978
|
+
if( #listpointscount[i] > 1,
|
|
979
|
+
if( subst('x^3+c*'x^2+d*'x,'x,listpointscount[i][1])-listpointscount[i][2]^2 != 0,
|
|
980
|
+
error("nfellcount: WRONG POINT = ",listpointscount[i]))));
|
|
981
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfellcount"));
|
|
982
|
+
return([listpointscount,[m1,m2]]);
|
|
983
|
+
}
|
|
984
|
+
{bnfell2descent_viaisog( bnf, ell) =
|
|
985
|
+
\\ Calcul du rang des courbes elliptiques avec 2-torsion
|
|
986
|
+
\\ dans le corps de nombres bnf
|
|
987
|
+
\\ par la methode des 2-isogenies.
|
|
988
|
+
\\
|
|
989
|
+
\\ ell = [a1,a2,a3,a4,a6]
|
|
990
|
+
\\ y^2+a1xy+a3y=x^3+a2x^2+a4x+a6
|
|
991
|
+
\\
|
|
992
|
+
\\ ell doit etre sous la forme
|
|
993
|
+
\\ y^2=x^3+ax^2+bx -> ell = [0,a,0,b,0]
|
|
994
|
+
\\ avec a et b entiers.
|
|
995
|
+
local(P,Pfact,tors,pointstriv,apinit,bpinit,plist,KS2prod,oddclass,KS2gen,listpoints,pointgen,n1,n2,certain,np1,np2,listpoints2,aux1,aux2,certainp,rang,strange);
|
|
996
|
+
|
|
997
|
+
if( DEBUGLEVEL_ell >= 2, print(" Algorithm of 2-descent via isogenies"));
|
|
998
|
+
if( DEBUGLEVEL_ell >= 3, print(" starting bnfell2descent_viaisog"));
|
|
999
|
+
if( variable(bnf.pol) != 'y,
|
|
1000
|
+
error("bnfell2descent_viaisog: the variable of the number field must be y"));
|
|
1001
|
+
ell = ellinit(Mod(lift(ell),bnf.pol));
|
|
1002
|
+
|
|
1003
|
+
if( ell.disc == 0,
|
|
1004
|
+
error("bnfell2descent_viaisog: singular curve !!"));
|
|
1005
|
+
if( ell.a1 != 0 || ell.a3 != 0 || ell.a6 != 0,
|
|
1006
|
+
error("bnfell2descent_viaisog: curve not of the form [0,a,0,b,0]"));
|
|
1007
|
+
if( denominator(nfalgtobasis(bnf,ell.a2)) > 1 || denominator(nfalgtobasis(bnf,ell.a4)) > 1,
|
|
1008
|
+
error("bnfell2descent_viaisog: non integral coefficients"));
|
|
1009
|
+
|
|
1010
|
+
P = Pol([1,ell.a2,ell.a4])*Mod(1,bnf.pol);
|
|
1011
|
+
Pfact = factornf(P,bnf.pol)[,1];
|
|
1012
|
+
tors = #Pfact;
|
|
1013
|
+
if( #Pfact > 1,
|
|
1014
|
+
pointstriv = [[0,0,1],[-polcoeff(Pfact[1],0),0,1],[-polcoeff(Pfact[2],0),0,1]]
|
|
1015
|
+
, pointstriv = [[0,0,1]]);
|
|
1016
|
+
|
|
1017
|
+
apinit = -2*ell.a2; bpinit = ell.a2^2-4*ell.a4;
|
|
1018
|
+
|
|
1019
|
+
\\ calcul des ideaux premiers de plist
|
|
1020
|
+
\\ et de quelques renseignements associes
|
|
1021
|
+
plist = idealfactor(bnf,6*ell.disc)[,1];
|
|
1022
|
+
|
|
1023
|
+
if( DEBUGLEVEL_ell >= 3, print(" Search for trivial points on the curve"));
|
|
1024
|
+
P *= 'x;
|
|
1025
|
+
if( DEBUGLEVEL_ell >= 3, print(" Y^2 = ",P));
|
|
1026
|
+
pointstriv = concat( pointstriv, nfratpoint(bnf.nf,P,LIMTRIV,0));
|
|
1027
|
+
if( DEBUGLEVEL_ell >= 1, print(" trivial points on E(K) = ");
|
|
1028
|
+
print(lift(pointstriv)); print());
|
|
1029
|
+
|
|
1030
|
+
KS2prod = ell.a4;
|
|
1031
|
+
oddclass = 0;
|
|
1032
|
+
while( !oddclass,
|
|
1033
|
+
KS2gen = bnfsunit(bnf,idealfactor(bnf,KS2prod)[,1]~);
|
|
1034
|
+
oddclass = KS2gen[5][1]%2;
|
|
1035
|
+
if( !oddclass,
|
|
1036
|
+
KS2prod = idealmul(bnf,KS2prod,(KS2gen[5][3][1])));
|
|
1037
|
+
);
|
|
1038
|
+
KS2gen = KS2gen[1];
|
|
1039
|
+
for( i = 1, #KS2gen,
|
|
1040
|
+
KS2gen[i] = nfbasistoalg(bnf, KS2gen[i]));
|
|
1041
|
+
KS2gen = concat(Mod(lift(concat(bnf.tu[2], bnf.fu)),bnf.pol),KS2gen);
|
|
1042
|
+
if( DEBUGLEVEL_ell >= 2,
|
|
1043
|
+
print(" #K(b,2)gen = ",#KS2gen);
|
|
1044
|
+
print(" K(b,2)gen = ",KS2gen));
|
|
1045
|
+
|
|
1046
|
+
listpoints = nfellcount(bnf.nf,ell.a2,ell.a4,KS2gen,pointstriv);
|
|
1047
|
+
pointgen = listpoints[1];
|
|
1048
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1049
|
+
print(" points on E(K) = ",lift(pointgen));
|
|
1050
|
+
print());
|
|
1051
|
+
n1 = listpoints[2][1]; n2 = listpoints[2][2];
|
|
1052
|
+
|
|
1053
|
+
certain = (n1 == n2);
|
|
1054
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1055
|
+
if( certain,
|
|
1056
|
+
print("[E(K):phi'(E'(K))] = ",1<<n1);
|
|
1057
|
+
print("#S^(phi')(E'/K) = ",1<<n2);
|
|
1058
|
+
print("#III(E'/K)[phi'] = 1"); print()
|
|
1059
|
+
,
|
|
1060
|
+
print("[E(K):phi'(E'(K))] >= ",1<<n1);
|
|
1061
|
+
print("#S^(phi')(E'/K) = ",1<<n2);
|
|
1062
|
+
print("#III(E'/K)[phi'] <= ",1<<(n2-n1)); print())
|
|
1063
|
+
);
|
|
1064
|
+
|
|
1065
|
+
KS2prod = bpinit;
|
|
1066
|
+
oddclass = 0;
|
|
1067
|
+
while( !oddclass,
|
|
1068
|
+
KS2gen = bnfsunit(bnf,idealfactor(bnf,KS2prod)[,1]~);
|
|
1069
|
+
oddclass = (KS2gen[5][1]%2);
|
|
1070
|
+
if( !oddclass,
|
|
1071
|
+
KS2prod = idealmul(bnf,KS2prod,(KS2gen[5][3][1]))));
|
|
1072
|
+
KS2gen = KS2gen[1];
|
|
1073
|
+
for( i = 1, #KS2gen,
|
|
1074
|
+
KS2gen[i] = nfbasistoalg(bnf, KS2gen[i]));
|
|
1075
|
+
KS2gen = concat(Mod(lift(concat(bnf.tu[2], bnf.fu)),bnf.pol),KS2gen);
|
|
1076
|
+
if( DEBUGLEVEL_ell >= 2,
|
|
1077
|
+
print(" #K(a^2-4b,2)gen = ",#KS2gen);
|
|
1078
|
+
print(" K(a^2-4b,2)gen = ",KS2gen));
|
|
1079
|
+
|
|
1080
|
+
P = Pol([1,apinit,bpinit])*Mod(1,bnf.pol);
|
|
1081
|
+
Pfact= factornf(P,bnf.pol)[,1];
|
|
1082
|
+
if( #Pfact > 1,
|
|
1083
|
+
pointstriv=[[0,0,1],[-polcoeff(Pfact[1],0),0,1],[-polcoeff(Pfact[2],0),0,1]]
|
|
1084
|
+
, pointstriv = [[0,0,1]]);
|
|
1085
|
+
|
|
1086
|
+
if( DEBUGLEVEL_ell >= 3, print(" Search for trivial points on the curve"));
|
|
1087
|
+
P *= 'x;
|
|
1088
|
+
if( DEBUGLEVEL_ell >= 3, print(" Y^2 = ",P));
|
|
1089
|
+
pointstriv = concat( pointstriv, nfratpoint(bnf.nf,P,LIMTRIV,0));
|
|
1090
|
+
if( DEBUGLEVEL_ell >= 1, print(" trivial points on E'(K) = ");
|
|
1091
|
+
print(lift(pointstriv)); print());
|
|
1092
|
+
|
|
1093
|
+
listpoints = nfellcount(bnf.nf,apinit,bpinit,KS2gen,pointstriv);
|
|
1094
|
+
if( DEBUGLEVEL_ell >= 1, print(" points on E'(K) = ",lift(listpoints[1])));
|
|
1095
|
+
np1 = listpoints[2][1]; np2 = listpoints[2][2];
|
|
1096
|
+
listpoints2 = vector(#listpoints[1],i,0);
|
|
1097
|
+
for( i = 1, #listpoints[1],
|
|
1098
|
+
listpoints2[i] = [0,0];
|
|
1099
|
+
aux1 = listpoints[1][i][1]^2;
|
|
1100
|
+
if( aux1 != 0,
|
|
1101
|
+
aux2 = listpoints[1][i][2];
|
|
1102
|
+
listpoints2[i][1] = aux2^2/aux1/4;
|
|
1103
|
+
listpoints2[i][2] = aux2*(bpinit-aux1)/aux1/8
|
|
1104
|
+
, listpoints2[i] = listpoints[1][i]));
|
|
1105
|
+
if( DEBUGLEVEL_ell >= 1, print(" points on E(K) = ",lift(listpoints2)); print());
|
|
1106
|
+
pointgen = concat(pointgen,listpoints2);
|
|
1107
|
+
|
|
1108
|
+
certainp = (np1 == np2);
|
|
1109
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1110
|
+
if( certainp,
|
|
1111
|
+
print("[E'(K):phi(E(K))] = ",1<<np1);
|
|
1112
|
+
print("#S^(phi)(E/K) = ",1<<np2);
|
|
1113
|
+
print("#III(E/K)[phi] = 1"); print()
|
|
1114
|
+
,
|
|
1115
|
+
print("[E'(K):phi(E(K))] >= ",1<<np1);
|
|
1116
|
+
print("#S^(phi)(E/K) = ",1<<np2);
|
|
1117
|
+
print("#III(E/K)[phi] <= ",1<<(np2-np1)); print());
|
|
1118
|
+
|
|
1119
|
+
if( !certain && (np2>np1), print1(1<<(np2-np1)," <= "));
|
|
1120
|
+
print1("#III(E/K)[2] ");
|
|
1121
|
+
if( certain && certainp, print1(" "), print1("<"));
|
|
1122
|
+
print("= ",1<<(n2+np2-n1-np1));
|
|
1123
|
+
|
|
1124
|
+
print("#E(K)[2] = ",1<<tors);
|
|
1125
|
+
);
|
|
1126
|
+
rang = n1+np1-2;
|
|
1127
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1128
|
+
if( certain && certainp,
|
|
1129
|
+
print("#E(K)/2E(K) = ",(1<<(rang+tors)));
|
|
1130
|
+
print("rank = ",rang); print()
|
|
1131
|
+
,
|
|
1132
|
+
print("#E(K)/2E(K) >= ",(1<<(rang+tors))); print();
|
|
1133
|
+
print(rang," <= rank <= ",n2+np2-2); print()
|
|
1134
|
+
));
|
|
1135
|
+
|
|
1136
|
+
strange = (n2+np2-n1-np1)%2;
|
|
1137
|
+
if( strange,
|
|
1138
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1139
|
+
print(" !!! III should be a square !!!"); print("hence"));
|
|
1140
|
+
if( certain,
|
|
1141
|
+
np1++;
|
|
1142
|
+
certainp = (np1 == np2);
|
|
1143
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1144
|
+
if( certainp,
|
|
1145
|
+
print("[E'(K):phi(E(K))] = ",1<<np1);
|
|
1146
|
+
print("#S^(phi)(E/K) = ",1<<np2);
|
|
1147
|
+
print("#III(E/K)[phi] = 1"); print()
|
|
1148
|
+
,
|
|
1149
|
+
print("[E'(K):phi(E(K))] >= ",1<<np1);
|
|
1150
|
+
print("#S^(phi)(E/K) = ",1<<np2);
|
|
1151
|
+
print("#III(E/K)[phi] <= ",1<<(np2-np1)); print())
|
|
1152
|
+
)
|
|
1153
|
+
,
|
|
1154
|
+
if( certainp,
|
|
1155
|
+
n1++;
|
|
1156
|
+
certain = ( n1 == n2);
|
|
1157
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1158
|
+
if( certain,
|
|
1159
|
+
print("[E(K):phi'(E'(K))] = ",1<<n1);
|
|
1160
|
+
print("#S^(phi')(E'/K) = ",1<<n2);
|
|
1161
|
+
print("#III(E'/K)[phi'] = 1"); print()
|
|
1162
|
+
,
|
|
1163
|
+
print("[E(K):phi'(E'(K))] >= ",1<<n1);
|
|
1164
|
+
print("#S^(phi')(E'/K) = ",1<<n2);
|
|
1165
|
+
print("#III(E'/K)[phi'] <= ",1<<(n2-n1)); print())
|
|
1166
|
+
)
|
|
1167
|
+
, n1++)
|
|
1168
|
+
);
|
|
1169
|
+
|
|
1170
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1171
|
+
if( !certain && (np2>np1), print1(1<<(np2-np1)," <= "));
|
|
1172
|
+
print1("#III(E/K)[2] ");
|
|
1173
|
+
if( certain && certainp, print1(" "), print1("<"));
|
|
1174
|
+
print("= ",1<<(n2+np2-n1-np1));
|
|
1175
|
+
print("#E(K)[2] = ",1<<tors);
|
|
1176
|
+
);
|
|
1177
|
+
rang = n1+np1-2;
|
|
1178
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1179
|
+
if( certain && certainp,
|
|
1180
|
+
print("#E(K)/2E(K) = ",(1<<(rang+tors))); print();
|
|
1181
|
+
print("rank = ",rang); print()
|
|
1182
|
+
,
|
|
1183
|
+
print("#E(K)/2E(K) >= ",(1<<(rang+tors))); print();
|
|
1184
|
+
print(rang," <= rank <= ",n2+np2-2); print())
|
|
1185
|
+
));
|
|
1186
|
+
|
|
1187
|
+
\\ end of strange
|
|
1188
|
+
|
|
1189
|
+
if( DEBUGLEVEL_ell >= 1, print(" points = ",pointgen));
|
|
1190
|
+
if( DEBUGLEVEL_ell >= 3, print(" end of bnfell2descent_viaisog"));
|
|
1191
|
+
return([rang,n2+np2-2+tors,pointgen]);
|
|
1192
|
+
}
|
|
1193
|
+
{nfchinese( nf, b, fact) =
|
|
1194
|
+
\\ Chinese Remainder Theorem
|
|
1195
|
+
local(l,fact2);
|
|
1196
|
+
|
|
1197
|
+
if( DEBUGLEVEL_ell >= 4, print(" starting nfchinese"));
|
|
1198
|
+
l = #fact[,1];
|
|
1199
|
+
fact2 = vector(l,i,idealdiv(nf,b,idealpow(nf,fact[i,1],fact[i,2])));
|
|
1200
|
+
fact2 = idealaddtoone(nf,fact2);
|
|
1201
|
+
for( i = 1, l,
|
|
1202
|
+
fact2[i] = nfbasistoalg(nf,fact2[i]));
|
|
1203
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of nfchinese"));
|
|
1204
|
+
return(fact2);
|
|
1205
|
+
}
|
|
1206
|
+
{bnfqfsolve2(bnf, aleg, bleg, aut=['y]) =
|
|
1207
|
+
\\ Solves Legendre Equation x^2-aleg*Y^2=bleg*Z^2
|
|
1208
|
+
\\ Using quadratic norm equations
|
|
1209
|
+
\\ aut contains the Galois automorphisms of bnf ( as polynomials in y)
|
|
1210
|
+
\\ with aut[1] = y.
|
|
1211
|
+
local(aux,solvepolrel,auxsolve,solvepolabs,exprxy,rrrnf,bbbnf,SL0,SL1,SL,sunL,fondsunL,normfondsunL,SK,sunK,fondsunK,vecbleg,matnorm,matnormmod,expsolution,solution,reste,carre,verif,x0,x1);
|
|
1212
|
+
|
|
1213
|
+
if( DEBUGLEVEL_ell >= 3, print(" starting bnfqfsolve2"));
|
|
1214
|
+
solvepolrel = 'x^2-aleg;
|
|
1215
|
+
if( DEBUGLEVEL_ell >= 4, print(" aleg = ",aleg));
|
|
1216
|
+
if( DEBUGLEVEL_ell >= 4, print(" bleg = ",bleg));
|
|
1217
|
+
|
|
1218
|
+
if( nfissquare(bnf,aleg),
|
|
1219
|
+
if( DEBUGLEVEL_ell >= 4, print(" aleg is a square !!"));
|
|
1220
|
+
aleg = nfsqrt(bnf,aleg)[1];
|
|
1221
|
+
return([aleg,1,0]~)
|
|
1222
|
+
);
|
|
1223
|
+
|
|
1224
|
+
if( #aut > 1,
|
|
1225
|
+
if( DEBUGLEVEL_ell >= 4, print(" factorization of the discriminant using the automorphisms of bnf"));
|
|
1226
|
+
for( i = 2, #aut,
|
|
1227
|
+
aux = abs(polresultant(lift(aleg)-subst(lift(aleg),'y,aut[i]),bnf.pol));
|
|
1228
|
+
if( aux, addprimes(factor(aux)[,1]))));
|
|
1229
|
+
|
|
1230
|
+
auxsolve = rnfequation(bnf,solvepolrel,1);
|
|
1231
|
+
solvepolabs = auxsolve[1];
|
|
1232
|
+
exprxy = auxsolve[2];
|
|
1233
|
+
if( auxsolve[3],
|
|
1234
|
+
if( DEBUGLEVEL_ell >= 5, print(" case with auxsolve[3] != 0")));
|
|
1235
|
+
if( DEBUGLEVEL_ell >= 4, print(" bbbnfinit ",solvepolabs));
|
|
1236
|
+
rrrnf = rnfinit(bnf,solvepolrel);
|
|
1237
|
+
bbbnf = bnfinit(solvepolabs,1);
|
|
1238
|
+
if( DEBUGLEVEL_ell >= 4, print(" done"));
|
|
1239
|
+
SL0 = 1;
|
|
1240
|
+
if( DEBUGLEVEL_ell >= 4, print(" bbbnf.clgp = ",bbbnf.clgp));
|
|
1241
|
+
for( i = 1, #bbbnf.clgp[2],
|
|
1242
|
+
if( bbbnf.clgp[2][i]%2 == 0,
|
|
1243
|
+
SL0 = idealmul(bbbnf,SL0,bbbnf.clgp[3][i][1,1])));
|
|
1244
|
+
SL1 = idealmul(bbbnf,SL0,rnfeltup(rrrnf,bleg));
|
|
1245
|
+
SL = idealfactor(bbbnf,SL1)[,1]~;
|
|
1246
|
+
sunL = bnfsunit(bbbnf,SL);
|
|
1247
|
+
fondsunL = concat(concat(bbbnf.fu, bbbnf.tu[2]),vector(#sunL[1],i,nfbasistoalg(bbbnf,sunL[1][i])));
|
|
1248
|
+
normfondsunL = vector(#fondsunL, i, norm(rnfeltabstorel(rrrnf,fondsunL[i])));
|
|
1249
|
+
SK = idealfactor(bnf,idealnorm(bbbnf,SL1))[,1]~;
|
|
1250
|
+
sunK = bnfsunit(bnf,SK);
|
|
1251
|
+
fondsunK = concat(concat(bnf.fu, bnf.tu[2]),vector(#sunK[1],i,nfbasistoalg(bnf,sunK[1][i])));
|
|
1252
|
+
vecbleg = bnfissunit(bnf,sunK,bleg);
|
|
1253
|
+
matnorm = matrix(#fondsunK,#normfondsunL,i,j,0);
|
|
1254
|
+
for( i = 1, #normfondsunL,
|
|
1255
|
+
matnorm[,i] = lift(bnfissunit( bnf,sunK,normfondsunL[i] )));
|
|
1256
|
+
matnormmod = matnorm*Mod(1,2);
|
|
1257
|
+
expsolution = lift(matinverseimage( matnormmod, vecbleg*Mod(1,2)));
|
|
1258
|
+
if( !length(expsolution), error("bnfqfsolve2 : NO SOLUTION !! "));
|
|
1259
|
+
solution = prod( i = 1, #expsolution, fondsunL[i]^expsolution[i]);
|
|
1260
|
+
solution = rnfeltabstorel(rrrnf,solution);
|
|
1261
|
+
reste = (lift(vecbleg) - matnorm*expsolution)/2;
|
|
1262
|
+
carre = prod( i = 1, #vecbleg, fondsunK[i]^reste[i]);
|
|
1263
|
+
solution *= carre;
|
|
1264
|
+
x1 = polcoeff(lift(solution),1,'x);
|
|
1265
|
+
x0 = polcoeff(lift(solution),0,'x);
|
|
1266
|
+
verif = x0^2 - aleg*x1^2-bleg;
|
|
1267
|
+
if( verif, error("bnfqfsolve2: WRONG POINT"));
|
|
1268
|
+
if( DEBUGLEVEL_ell >= 3, print(" end of bnfqfsolve2"));
|
|
1269
|
+
return([x0,x1,1]~);
|
|
1270
|
+
}
|
|
1271
|
+
{bnfqfsolve(bnf, aleg, bleg, flag3, aut=['y]) =
|
|
1272
|
+
\\ cette fonction resout l'equation X^2-aleg*Y^2=bleg*Z^2
|
|
1273
|
+
\\ dans le corps de nombres nf.
|
|
1274
|
+
\\ la solution est [X,Y,Z],
|
|
1275
|
+
\\ [0,0,0] sinon.
|
|
1276
|
+
local(nf,aa,bb,na,nb,maxnb,mat,resl,t,sq,pol,vecrat,alpha,xx,yy,borne,test,sun,fact,suni,f,l,aux,alpha2,maxnbiter,idbb,rem,nbiter,mask,oldnb,newnb,bor,testici,de,xxp,yyp,rap,verif);
|
|
1277
|
+
|
|
1278
|
+
if( DEBUGLEVEL_ell >= 5, print(" starting bnfqfsolve"));
|
|
1279
|
+
if( DEBUGLEVEL_ell >= 3, print(" (a,b) = (",aleg,",",bleg,")"));
|
|
1280
|
+
nf = bnf.nf;
|
|
1281
|
+
aleg = Mod(lift(aleg),nf.pol); aa = aleg;
|
|
1282
|
+
bleg = Mod(lift(bleg),nf.pol); bb = bleg;
|
|
1283
|
+
|
|
1284
|
+
if( aa == 0,
|
|
1285
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of bnfqfsolve"));
|
|
1286
|
+
return([0,1,0]~));
|
|
1287
|
+
if( bb == 0,
|
|
1288
|
+
if( DEBUGLEVEL_ell >= 5, print(" end of bnfqfsolve"));
|
|
1289
|
+
return([0,0,1]~));
|
|
1290
|
+
|
|
1291
|
+
na = abs(norm(aa)); nb = abs(norm(bb));
|
|
1292
|
+
if( na > nb, maxnb = na, maxnb = nb);
|
|
1293
|
+
maxnb <<= 20;
|
|
1294
|
+
mat = Mod(matid(3),nf.pol); borne = 1;
|
|
1295
|
+
test = 0; nbiter = 0;
|
|
1296
|
+
|
|
1297
|
+
while( 1,
|
|
1298
|
+
if( flag3 && bnf.clgp[1]>1, resl = bnfqfsolve2(bnf,aa,bb,aut); break);
|
|
1299
|
+
if( DEBUGLEVEL_ell >= 4, print(" (na,nb,a,b) = ",lift([na,nb,aa,bb,norm(aa),norm(bb)])));
|
|
1300
|
+
if( DEBUGLEVEL_ell >= 5, print(" ***",nb,"*** "));
|
|
1301
|
+
if( nb >= maxnb,
|
|
1302
|
+
mat = Mod(matid(3),nf.pol);
|
|
1303
|
+
aa = aleg; bb = bleg; na = abs(norm(aleg)); nb = abs(norm(bleg)));
|
|
1304
|
+
if( aa == 1, resl = [1,1,0]~; break);
|
|
1305
|
+
if( bb == 1, resl = [1,0,1]~; break);
|
|
1306
|
+
if( aa+bb == 1, resl = [1,1,1]~; break);
|
|
1307
|
+
if( aa+bb == 0, resl = [0,1,1]~; break);
|
|
1308
|
+
if( aa == bb && aa != 1,
|
|
1309
|
+
t = aa*mat[,1];
|
|
1310
|
+
mat[,1] = mat[,3]; mat[,3] = t;
|
|
1311
|
+
aa = -1; na = 1);
|
|
1312
|
+
if( issquare(na),
|
|
1313
|
+
sq = nfsqrt(nf,aa);
|
|
1314
|
+
if( sq != [], resl = [sq[1],1,0]~; break));
|
|
1315
|
+
if( issquare(nb),
|
|
1316
|
+
sq = nfsqrt(nf,bb);
|
|
1317
|
+
if( sq != [], resl = [sq[1],0,1]~; break));
|
|
1318
|
+
if( na > nb,
|
|
1319
|
+
t = aa; aa = bb; bb = t;
|
|
1320
|
+
t = na; na = nb; nb = t;
|
|
1321
|
+
t = mat[,3]; mat[,3] = mat[,2]; mat[,2] = t);
|
|
1322
|
+
if( nb == 1,
|
|
1323
|
+
if( DEBUGLEVEL_ell >= 4, print(" (a,b) = ",lift([aa,bb])));
|
|
1324
|
+
if( DEBUGLEVEL_ell >= 4, print(" (na,nb) = ",lift([na,nb])));
|
|
1325
|
+
if( aleg == aa && bleg == bb, mat = Mod(matid(3),nf.pol));
|
|
1326
|
+
if( flag3, resl = bnfqfsolve2(bnf,aa,bb,aut); break);
|
|
1327
|
+
pol = aa*'x^2+bb;
|
|
1328
|
+
vecrat = nfratpoint(nf,pol,borne++,1);
|
|
1329
|
+
if( vecrat != 0, resl=[vecrat[2],vecrat[1],vecrat[3]]~; break);
|
|
1330
|
+
|
|
1331
|
+
alpha = 0;
|
|
1332
|
+
if( DEBUGLEVEL_ell >= 4, print(" bound = ",borne));
|
|
1333
|
+
while( alpha==0,
|
|
1334
|
+
xx = nfrandint(nf,borne); yy = nfrandint(nf,borne);
|
|
1335
|
+
borne++;
|
|
1336
|
+
alpha = xx^2-aa*yy^2 );
|
|
1337
|
+
bb *= alpha; nb *= abs(norm(alpha));
|
|
1338
|
+
t = xx*mat[,1]+yy*mat[,2];
|
|
1339
|
+
mat[,2] = xx*mat[,2]+aa*yy*mat[,1];
|
|
1340
|
+
mat[,1] = t;
|
|
1341
|
+
mat[,3] *= alpha
|
|
1342
|
+
,
|
|
1343
|
+
test = 1;
|
|
1344
|
+
if( DEBUGLEVEL_ell >= 4, print("on factorise bb = ",bb));
|
|
1345
|
+
sun = bnfsunit(bnf,idealfactor(bnf,bb)[,1]~);
|
|
1346
|
+
fact = lift(bnfissunit(bnf,sun,bb));
|
|
1347
|
+
if( DEBUGLEVEL_ell >= 4, print("fact = ",fact));
|
|
1348
|
+
suni = concat(concat(bnf.fu, bnf.tu[2]),vector(#sun[1],i,nfbasistoalg(bnf,sun[1][i])));
|
|
1349
|
+
for( i = 1, #suni,
|
|
1350
|
+
if( (f = fact[i]>>1),
|
|
1351
|
+
test =0;
|
|
1352
|
+
for( k = 1, 3, mat[k,3] /= suni[i]^f);
|
|
1353
|
+
nb /= abs(norm(suni[i]))^(2*f);
|
|
1354
|
+
bb /= suni[i]^(2*f)));
|
|
1355
|
+
if( DEBUGLEVEL_ell >= 4, print(" factorization of bb = ",bb));
|
|
1356
|
+
fact = idealfactor(nf,bb);
|
|
1357
|
+
if( DEBUGLEVEL_ell >= 4, print(" fact = ",fact));
|
|
1358
|
+
l = #fact[,1];
|
|
1359
|
+
|
|
1360
|
+
if( test,
|
|
1361
|
+
aux = 1;
|
|
1362
|
+
for( i = 1, l,
|
|
1363
|
+
if( (f = fact[i,2]>>1) &&
|
|
1364
|
+
!(fact[i,1][1]%2) && !nfissquaremodpodd(nf,aa,fact[i,1]),
|
|
1365
|
+
aux=idealmul(nf,aux,idealpow(nf,fact[i,1],f))));
|
|
1366
|
+
if( aux != 1,
|
|
1367
|
+
test = 0;
|
|
1368
|
+
alpha = nfbasistoalg(nf,idealappr(nf,idealinv(nf,aux)));
|
|
1369
|
+
alpha2 = alpha^2;
|
|
1370
|
+
bb *= alpha2; nb *= abs(norm(alpha2));
|
|
1371
|
+
mat[,3] *= alpha));
|
|
1372
|
+
if( test,
|
|
1373
|
+
maxnbiter = 1<<l;
|
|
1374
|
+
sq = vector(l,i,nfsqrtmodpq(nf,aa,fact[i,1],fact[i,2]));
|
|
1375
|
+
l = #sq;
|
|
1376
|
+
if( DEBUGLEVEL_ell >= 4,
|
|
1377
|
+
print(" sq = ",sq);
|
|
1378
|
+
print(" fact = ",fact);
|
|
1379
|
+
print(" l = ",l));
|
|
1380
|
+
if( l > 1,
|
|
1381
|
+
idbb = idealhnf(nf,bb);
|
|
1382
|
+
rem = nfchinese(nf,idbb,fact));
|
|
1383
|
+
test = 1; nbiter = 1;
|
|
1384
|
+
while( test && nbiter <= maxnbiter,
|
|
1385
|
+
if( l > 1,
|
|
1386
|
+
mask = nbiter; xx = 0;
|
|
1387
|
+
for( i = 1, l,
|
|
1388
|
+
if( mask%2, xx += rem[i]*sq[i], xx -= rem[i]*sq[i] ); mask >>= 1)
|
|
1389
|
+
,
|
|
1390
|
+
test = 0; xx = sq[1]);
|
|
1391
|
+
xx = mynfeltmod(nf,xx,bb);
|
|
1392
|
+
alpha = xx^2-aa;
|
|
1393
|
+
if( alpha == 0, resl=[xx,1,0]~; break(2));
|
|
1394
|
+
t = alpha/bb;
|
|
1395
|
+
if( DEBUGLEVEL_ell >= 4, print(" [alpha,bb] = ",[alpha,bb]));
|
|
1396
|
+
oldnb = nb;
|
|
1397
|
+
newnb = abs(norm(t));
|
|
1398
|
+
if( DEBUGLEVEL_ell >= 4, print(" [oldnb,newnb,oldnb/newnb] = ",[oldnb,newnb,oldnb/newnb+0.]));
|
|
1399
|
+
while( nb > newnb,
|
|
1400
|
+
mat[,3] *= t;
|
|
1401
|
+
bb = t; nb = newnb;
|
|
1402
|
+
t = xx*mat[,1]+mat[,2];
|
|
1403
|
+
mat[,2] = aa*mat[,1] + xx*mat[,2];
|
|
1404
|
+
mat[,1] = t;
|
|
1405
|
+
xx = mynfeltmod(nf,-xx,bb);
|
|
1406
|
+
alpha = xx^2-aa;
|
|
1407
|
+
t = alpha/bb;
|
|
1408
|
+
newnb = abs(norm(t));
|
|
1409
|
+
);
|
|
1410
|
+
if( nb == oldnb, nbiter++, test = 0);
|
|
1411
|
+
);
|
|
1412
|
+
if( nb == oldnb,
|
|
1413
|
+
if( flag3, resl = bnfqfsolve2(bnf,aa,bb,aut); break);
|
|
1414
|
+
pol = aa*'x^2+bb;
|
|
1415
|
+
vecrat =nfratpoint(nf,pol,borne++<<1,1);
|
|
1416
|
+
if( vecrat != 0, resl = [vecrat[2],vecrat[1],vecrat[3]]~; break);
|
|
1417
|
+
|
|
1418
|
+
bor = 1000; yy = 1; testici = 1;
|
|
1419
|
+
for( i = 1, 10000, de = nfbasistoalg(nf,vectorv(poldegree(nf.pol),j,random(bor)));
|
|
1420
|
+
if( idealadd(bnf,de,bb) != matid(poldegree(bnf.pol)),next);
|
|
1421
|
+
xxp = mynfeltmod(bnf,de*xx,bb); yyp = mynfeltmod(bnf,de*yy,bb);
|
|
1422
|
+
rap = (norm(xxp^2-aa*yyp^2)/nb^2+0.);
|
|
1423
|
+
if( abs(rap) < 1,
|
|
1424
|
+
if( DEBUGLEVEL_ell >= 4, print(" ********** \n \n MIRACLE ",rap," \n \n ***"));
|
|
1425
|
+
t = (xxp^2-aa*yyp^2)/bb;
|
|
1426
|
+
mat[,3] *= t;
|
|
1427
|
+
bb = t; nb = abs(norm(bb));
|
|
1428
|
+
if( DEBUGLEVEL_ell >= 4, print(" newnb = ",nb));
|
|
1429
|
+
t = xxp*mat[,1]+yyp*mat[,2];
|
|
1430
|
+
mat[,2] = aa*yyp*mat[,1] + xxp*mat[,2];
|
|
1431
|
+
mat[,1] = t;
|
|
1432
|
+
xx = xxp; yy = -yyp; testici = 0;
|
|
1433
|
+
));
|
|
1434
|
+
|
|
1435
|
+
if( testici,
|
|
1436
|
+
alpha = 0;
|
|
1437
|
+
while( alpha == 0,
|
|
1438
|
+
xx = nfrandint(nf,4*borne); yy = nfrandint(nf,4*borne);
|
|
1439
|
+
borne++;
|
|
1440
|
+
alpha = xx^2-aa*yy^2);
|
|
1441
|
+
bb *= alpha; nb *= abs(norm(alpha));
|
|
1442
|
+
t = xx*mat[,1] + yy*mat[,2];
|
|
1443
|
+
mat[,2] = xx*mat[,2]+aa*yy*mat[,1];
|
|
1444
|
+
mat[,1] = t;
|
|
1445
|
+
mat[,3] *= alpha;)))));
|
|
1446
|
+
resl = lift(mat*resl);
|
|
1447
|
+
if( DEBUGLEVEL_ell >= 5, print(" resl1 = ",resl));
|
|
1448
|
+
if( DEBUGLEVEL_ell >= 5, print(" content = ",content(resl)));
|
|
1449
|
+
resl /= content(resl);
|
|
1450
|
+
resl = Mod(lift(resl),nf.pol);
|
|
1451
|
+
if( DEBUGLEVEL_ell >=5, print(" resl3 = ",resl));
|
|
1452
|
+
fact = idealadd(nf,idealadd(nf,resl[1],resl[2]),resl[3]);
|
|
1453
|
+
fact = bnfisprincipal(bnf,fact,3);
|
|
1454
|
+
resl *=1/nfbasistoalg(nf,fact[2]);
|
|
1455
|
+
if( DEBUGLEVEL_ell >= 5, print(" resl4 = ",resl));
|
|
1456
|
+
if( DEBUGLEVEL_ell >= 3, print(" resl = ",resl));
|
|
1457
|
+
verif = (resl[1]^2-aleg*resl[2]^2-bleg*resl[3]^2 == 0);
|
|
1458
|
+
if( !verif, error("bnfqfsolve: WRONG POINT"));
|
|
1459
|
+
if( DEBUGLEVEL_ell >= 3, print(" end of bnfqfsolve"));
|
|
1460
|
+
return(resl);
|
|
1461
|
+
}
|
|
1462
|
+
{bnfredquartique( bnf, pol, r,a,b) =
|
|
1463
|
+
\\ reduction d'une quartique issue de la 2-descente
|
|
1464
|
+
\\ en connaissant les valeurs de r, a et b.
|
|
1465
|
+
local(gcc,princ,rp,pol2);
|
|
1466
|
+
|
|
1467
|
+
if( DEBUGLEVEL_ell >= 4, print(" starting bnfredquartique"));
|
|
1468
|
+
if( DEBUGLEVEL_ell >= 4, print(" ",[r,a,b]));
|
|
1469
|
+
if( DEBUGLEVEL_ell >= 3, print(" reduction of the quartic ",pol));
|
|
1470
|
+
|
|
1471
|
+
if( a == 0,
|
|
1472
|
+
rp = 0
|
|
1473
|
+
,
|
|
1474
|
+
gcc = idealadd(bnf,b,a);
|
|
1475
|
+
if( gcc == 1,
|
|
1476
|
+
rp = nfbasistoalg(bnf,idealaddtoone(bnf.nf,a,b)[1])/a;
|
|
1477
|
+
rp = mynfeltmod(bnf,r*rp,b)
|
|
1478
|
+
,
|
|
1479
|
+
princ = bnfisprincipal(bnf,gcc,3);
|
|
1480
|
+
if( princ[1] == 0, gcc = nfbasistoalg(bnf,princ[2])
|
|
1481
|
+
,
|
|
1482
|
+
if( DEBUGLEVEL_ell >= 3, print(" quartic not reduced"));
|
|
1483
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of bnfredquartique"));
|
|
1484
|
+
return([pol,0,1]));
|
|
1485
|
+
rp = nfbasistoalg(bnf,idealaddtoone(bnf.nf,a/gcc,b/gcc)[1])/(a/gcc);
|
|
1486
|
+
rp = mynfeltmod(bnf,r*rp,b)/gcc;
|
|
1487
|
+
b /= gcc;
|
|
1488
|
+
)
|
|
1489
|
+
);
|
|
1490
|
+
pol2 = subst(pol/b,'x,rp+b*'x)/b^3;
|
|
1491
|
+
if( DEBUGLEVEL_ell >= 3, print(" quartic reduced: ",pol2));
|
|
1492
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of bnfredquartique"));
|
|
1493
|
+
return([pol2,rp,b]);
|
|
1494
|
+
}
|
|
1495
|
+
{bnfell2descent_gen( bnf, ell, ext, help=[], bigflag=1, flag3=1, aut=['y]) =
|
|
1496
|
+
\\ bnf a un polynome en y.
|
|
1497
|
+
\\ si ell= y^2=P(x), alors ext est
|
|
1498
|
+
\\ ext[1] est une equation relative du corps (=P(x)),
|
|
1499
|
+
\\ ext[2] est le resultat rnfequation(bnf,P,1);
|
|
1500
|
+
\\ ext[3] est le bnfinit (sur Q) de l'extension.
|
|
1501
|
+
\\ dans la suite ext est note L = K(theta).
|
|
1502
|
+
\\ help est une liste de points deja connus sur ell.
|
|
1503
|
+
\\ si bigflag !=0 alors on applique bnfredquartique.
|
|
1504
|
+
\\ si flag3 ==1 alors on utilise bnfqfsolve2 (equation aux normes) pour resoudre Legendre
|
|
1505
|
+
\\ aut est une liste d'automorphismes connus de bnf
|
|
1506
|
+
\\ (ca peut aider a factoriser certains discriminants).
|
|
1507
|
+
\\ ell est de la forme y^2=x^3+A*x^2+B*x+C
|
|
1508
|
+
\\ ie ell=[0,A,0,B,C], avec A,B et C entiers.
|
|
1509
|
+
\\
|
|
1510
|
+
local(nf,unnf,ellnf,A,B,C,S,plist,Lrnf,SLprod,LS2,LS2gen,polrel,alpha,ttheta,KS2gen,normLS2,normcoord,LS2coordtilda,LS2tilda,aux,listgen,listpointstriv,listpoints,m1,m2,loc,lastloc,maskwhile,iwhile,zc,iaux,liftzc,ispointtriv,point,c,b,a,found,alphac,r,denc,dena,cp,alphacp,beta,mattr,vec,z1,cont,d,e,polorig,pol,redq,transl,multip,UVW,pointxx,point2,rang,listELS,listnotELS);
|
|
1511
|
+
|
|
1512
|
+
if( DEBUGLEVEL_ell >= 4, print(" starting bnfell2descent_gen"));
|
|
1513
|
+
|
|
1514
|
+
nf = bnf.nf;
|
|
1515
|
+
unnf = Mod(1,nf.pol);
|
|
1516
|
+
ellnf = ell*unnf;
|
|
1517
|
+
if( #ellnf <= 5, ellnf = ellinit(ellnf));
|
|
1518
|
+
|
|
1519
|
+
A = ellnf.a2; if( DEBUGLEVEL_ell >= 2, print(" A = ",A));
|
|
1520
|
+
B = ellnf.a4; if( DEBUGLEVEL_ell >= 2, print(" B = ",B));
|
|
1521
|
+
C = ellnf.a6; if( DEBUGLEVEL_ell >= 2, print(" C = ",C));
|
|
1522
|
+
|
|
1523
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1524
|
+
\\ Construction of L(S,2) \\
|
|
1525
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1526
|
+
|
|
1527
|
+
if( DEBUGLEVEL_ell >= 2, print(); print(" Computing L(S,2)"));
|
|
1528
|
+
|
|
1529
|
+
polrel = ext[1];
|
|
1530
|
+
alpha = Mod(Mod('y,nf.pol),polrel); \\ alpha est l'element primitif de K
|
|
1531
|
+
ttheta = Mod('x,polrel); \\ ttheta est la racine de P(x)
|
|
1532
|
+
|
|
1533
|
+
S = 6*lift(ellnf.disc);
|
|
1534
|
+
plist = idealfactor(nf,S)[,1];
|
|
1535
|
+
Lrnf = ext[3];
|
|
1536
|
+
SLprod = subst(lift(polrel'),'y,lift(ext[2][2]));
|
|
1537
|
+
if( DEBUGLEVEL_ell >= 3, print(" ",ext[2]));
|
|
1538
|
+
|
|
1539
|
+
while( 1,
|
|
1540
|
+
\\ Construction des S-unites
|
|
1541
|
+
LS2gen = bnfsunit(Lrnf, idealfactor(Lrnf,SLprod)[,1]~);
|
|
1542
|
+
if( DEBUGLEVEL_ell >= 4, print(" LS2gen = ",LS2gen));
|
|
1543
|
+
\\ si le groupe de classes est impair, on a fini.
|
|
1544
|
+
if( LS2gen[5][1]%2, break);
|
|
1545
|
+
if( DEBUGLEVEL_ell >= 3, print(" 2-class group ",LS2gen[5][3][1][1,1]));
|
|
1546
|
+
S *= LS2gen[5][3][1][1,1];
|
|
1547
|
+
SLprod = idealmul(Lrnf,SLprod,(LS2gen[5][3][1]));
|
|
1548
|
+
);
|
|
1549
|
+
|
|
1550
|
+
KS2gen = bnfsunit(bnf,idealfactor(nf,S)[,1]~);
|
|
1551
|
+
|
|
1552
|
+
if( DEBUGLEVEL_ell >= 3, print(" #KS2gen = ",#KS2gen[1]));
|
|
1553
|
+
if( DEBUGLEVEL_ell >= 3, print(" KS2gen = ",KS2gen[1]));
|
|
1554
|
+
|
|
1555
|
+
LS2gen = LS2gen[1];
|
|
1556
|
+
LS2 = vector(#LS2gen,i,lift(nfbasistoalg(Lrnf,LS2gen[i])));
|
|
1557
|
+
LS2 = concat(lift(concat(Lrnf.fu, Lrnf.tu[2])),LS2);
|
|
1558
|
+
|
|
1559
|
+
LS2 = subst(LS2,'x,ttheta);
|
|
1560
|
+
LS2 = LS2*Mod(1,polrel);
|
|
1561
|
+
if( DEBUGLEVEL_ell >= 3, print(" #LS2 = ",#LS2));
|
|
1562
|
+
if( DEBUGLEVEL_ell >= 3, print(" LS2 = ",LS2));
|
|
1563
|
+
|
|
1564
|
+
if( DEBUGLEVEL_ell >= 2, print(" L(S,2) = ",LS2));
|
|
1565
|
+
|
|
1566
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1567
|
+
\\ Construction of the Selmer group \\
|
|
1568
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1569
|
+
|
|
1570
|
+
if( DEBUGLEVEL_ell >= 2, print(); print(" Computing the Selmer group"));
|
|
1571
|
+
|
|
1572
|
+
\\ dans LS2gen, on ne garde que ceux dont la norme est un carre.
|
|
1573
|
+
|
|
1574
|
+
normLS2 = norm(LS2);
|
|
1575
|
+
if( DEBUGLEVEL_ell >= 4, print(" normLS2 = ",normLS2));
|
|
1576
|
+
|
|
1577
|
+
\\ matrice de l'application norme
|
|
1578
|
+
|
|
1579
|
+
normcoord = matrix(#KS2gen[1]+#bnf[8][5]+1,#normLS2,i,j,0);
|
|
1580
|
+
for( i = 1, #normLS2,
|
|
1581
|
+
normcoord[,i] = bnfissunit(bnf,KS2gen,normLS2[i]));
|
|
1582
|
+
if( DEBUGLEVEL_ell >= 4, print(" normcoord = ",normcoord));
|
|
1583
|
+
|
|
1584
|
+
\\ construction du noyau de la norme
|
|
1585
|
+
|
|
1586
|
+
LS2coordtilda = lift(matker(normcoord*Mod(1,2)));
|
|
1587
|
+
if( DEBUGLEVEL_ell >= 4, print(" LS2coordtilda = ",LS2coordtilda));
|
|
1588
|
+
LS2tilda = vector(#LS2coordtilda[1,],i,0);
|
|
1589
|
+
for( i = 1, #LS2coordtilda[1,],
|
|
1590
|
+
aux = 1;
|
|
1591
|
+
for( j = 1, #LS2coordtilda[,i],
|
|
1592
|
+
if( sign(LS2coordtilda[j,i]),
|
|
1593
|
+
aux *= LS2[j]));
|
|
1594
|
+
LS2tilda[i] = aux;
|
|
1595
|
+
);
|
|
1596
|
+
|
|
1597
|
+
if( DEBUGLEVEL_ell >= 3, print(" LS2tilda = ",LS2tilda));
|
|
1598
|
+
if( DEBUGLEVEL_ell >= 3, print(" norm(LS2tilda) = ",norm(LS2tilda)));
|
|
1599
|
+
|
|
1600
|
+
\\ Fin de la construction de L(S,2)
|
|
1601
|
+
|
|
1602
|
+
listgen = LS2tilda;
|
|
1603
|
+
if( DEBUGLEVEL_ell >= 2, print(" #LS2gen = ",#listgen));
|
|
1604
|
+
if( DEBUGLEVEL_ell >= 2, print(" LS2gen = ",listgen));
|
|
1605
|
+
|
|
1606
|
+
if( DEBUGLEVEL_ell >= 3, print(" (A,B,C) = ",[A,B,C]));
|
|
1607
|
+
|
|
1608
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1609
|
+
\\ Recherche de points triviaux \\
|
|
1610
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1611
|
+
|
|
1612
|
+
if( DEBUGLEVEL_ell >= 2, print(" Search for trivial points on the curve"));
|
|
1613
|
+
listpointstriv = nfratpoint(nf,'x^3+A*'x^2+B*'x+C,LIMTRIV,0);
|
|
1614
|
+
listpointstriv = concat(help,listpointstriv);
|
|
1615
|
+
if( DEBUGLEVEL_ell >= 1, print(" Trivial points on the curve = ",listpointstriv));
|
|
1616
|
+
|
|
1617
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1618
|
+
\\ parcours de L(S,2) \\
|
|
1619
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
1620
|
+
|
|
1621
|
+
listpoints = [];
|
|
1622
|
+
m1 = 0; m2 = 0; lastloc = -1;
|
|
1623
|
+
maskwhile = 1<<#listgen;
|
|
1624
|
+
listELS = [0]; listnotELS = [];
|
|
1625
|
+
iwhile = 1;
|
|
1626
|
+
|
|
1627
|
+
while( iwhile < maskwhile,
|
|
1628
|
+
if( DEBUGLEVEL_ell >= 4,
|
|
1629
|
+
print(" iwhile = ",iwhile);
|
|
1630
|
+
print(" listgen = ",listgen)
|
|
1631
|
+
);
|
|
1632
|
+
|
|
1633
|
+
\\ utilise la structure de groupe pour detecter une eventuelle solubilite locale.
|
|
1634
|
+
loc = 0;
|
|
1635
|
+
for( i = 1, #listELS,
|
|
1636
|
+
for( j = 1, #listnotELS,
|
|
1637
|
+
if( bitxor(listELS[i],listnotELS[j]) == iwhile,
|
|
1638
|
+
if( DEBUGLEVEL_ell >= 3, print(" Not ELS from group structure"));
|
|
1639
|
+
listnotELS = concat(listnotELS,[iwhile]);
|
|
1640
|
+
iwhile++;
|
|
1641
|
+
next(3)
|
|
1642
|
+
)));
|
|
1643
|
+
|
|
1644
|
+
for( i = 1, #listELS,
|
|
1645
|
+
for( j = i+1, #listELS,
|
|
1646
|
+
if( bitxor(listELS[i],listELS[j]) == iwhile,
|
|
1647
|
+
if( DEBUGLEVEL_ell >= 3, print(" ELS from group structure"));
|
|
1648
|
+
listELS = concat(listELS,[iwhile]);
|
|
1649
|
+
loc = 1;
|
|
1650
|
+
break(2)
|
|
1651
|
+
)));
|
|
1652
|
+
|
|
1653
|
+
iaux = vectorv(#listgen,i,bittest(iwhile,i-1));
|
|
1654
|
+
iaux = (LS2coordtilda*iaux)%2;
|
|
1655
|
+
zc = unnf*prod( i = 1, #LS2, LS2[i]^iaux[i]);
|
|
1656
|
+
|
|
1657
|
+
if( DEBUGLEVEL_ell >= 2, print(" zc = ",zc));
|
|
1658
|
+
liftzc = lift(zc);
|
|
1659
|
+
|
|
1660
|
+
\\ Est-ce un point trivial ?
|
|
1661
|
+
found = 0;
|
|
1662
|
+
ispointtriv = 0;
|
|
1663
|
+
for( i = 1, #listpointstriv,
|
|
1664
|
+
point = listpointstriv[i];
|
|
1665
|
+
if( #point == 2 || point[3] != 0,
|
|
1666
|
+
if( nfissquare(Lrnf.nf,subst((lift(point[1])-'x)*lift(liftzc),'y,lift(ext[2][2]))),
|
|
1667
|
+
if( DEBUGLEVEL_ell >= 2, print(" comes from the trivial point ",point));
|
|
1668
|
+
listpoints = concat(listpoints,[point]);
|
|
1669
|
+
found = 1; ispointtriv = 1; break
|
|
1670
|
+
)));
|
|
1671
|
+
|
|
1672
|
+
\\ \\\\\\\\\\\\\
|
|
1673
|
+
\\ On cherche a ecrire zc sous la forme a-b*theta
|
|
1674
|
+
\\ \\\\\\\\\\\\\
|
|
1675
|
+
|
|
1676
|
+
if( !found, \\ si ce n'est pas un point trivial
|
|
1677
|
+
a = polcoeff(liftzc,0);
|
|
1678
|
+
b =-polcoeff(liftzc,1);
|
|
1679
|
+
c = polcoeff(liftzc,2);
|
|
1680
|
+
|
|
1681
|
+
if( c != 0,
|
|
1682
|
+
alphac = (A*b+B*c-a)*c+b^2;
|
|
1683
|
+
if( DEBUGLEVEL_ell >= 3, print(" alphac = ",alphac));
|
|
1684
|
+
r = nfsqrt(nf,norm(zc))[1];
|
|
1685
|
+
if( alphac == 0,
|
|
1686
|
+
\\ cas particulier
|
|
1687
|
+
if( DEBUGLEVEL_ell >= 3, print(" continuing with 1/zc"));
|
|
1688
|
+
zc = norm(zc)*(1/zc);
|
|
1689
|
+
if( DEBUGLEVEL_ell >= 2, print(" zc = ",zc))
|
|
1690
|
+
,
|
|
1691
|
+
\\ Il faut resoudre une forme quadratique
|
|
1692
|
+
\\ Existence (locale = globale) d'une solution :
|
|
1693
|
+
denc = deno(lift(c));
|
|
1694
|
+
if( denc != 1, cp = c*denc^2, cp = c);
|
|
1695
|
+
dena = deno(lift(alphac));
|
|
1696
|
+
if( dena != 1, alphacp = alphac*dena^2, alphacp = alphac);
|
|
1697
|
+
if( DEBUGLEVEL_ell >= 2, print(" Hilbert symbol (",alphacp,",",cp,") = "));
|
|
1698
|
+
if( !loc && mynfhilbert(nf, alphacp,cp) < 0,
|
|
1699
|
+
if( DEBUGLEVEL_ell >= 3, print(" no local solution"));
|
|
1700
|
+
listnotELS = concat(listnotELS,[iwhile]);
|
|
1701
|
+
iwhile++;
|
|
1702
|
+
next
|
|
1703
|
+
);
|
|
1704
|
+
\\ Ici on a l'existence locale
|
|
1705
|
+
beta = A*(A*b*c+B*c^2+b^2)-C*c^2+a*b;
|
|
1706
|
+
mattr = matid(3);
|
|
1707
|
+
mattr[1,1] = c ;mattr[2,2] = alphac ;
|
|
1708
|
+
mattr[3,3] = r ;mattr[2,3] = -beta;
|
|
1709
|
+
mattr[1,2] = -(b +A*c) ;mattr[1,3] = a-B*c+A*(A*c+b);
|
|
1710
|
+
if( DEBUGLEVEL_ell >= 2, print1(" sol of quadratic equation = "));
|
|
1711
|
+
vec = bnfqfsolve(bnf,alphacp,cp,flag3,aut);
|
|
1712
|
+
if( DEBUGLEVEL_ell >= 2, print(lift(vec)));
|
|
1713
|
+
aux = vec[2]*dena;
|
|
1714
|
+
vec[2] = vec[1];vec[1] = aux;
|
|
1715
|
+
vec[3] = vec[3]*denc;
|
|
1716
|
+
vec = (mattr^(-1))*vec;
|
|
1717
|
+
vec /= content(lift(vec));
|
|
1718
|
+
z1 = (vec[3]*ttheta+vec[2])*ttheta+vec[1];
|
|
1719
|
+
if( DEBUGLEVEL_ell >= 3, print(" z1 = ",z1));
|
|
1720
|
+
zc *= z1^2;
|
|
1721
|
+
if( DEBUGLEVEL_ell >= 2, print(" zc*z1^2 = ",zc));
|
|
1722
|
+
)
|
|
1723
|
+
)
|
|
1724
|
+
);
|
|
1725
|
+
|
|
1726
|
+
\\ \\\\\\\\\\
|
|
1727
|
+
\\ Maintenant zc est de la forme a-b*theta
|
|
1728
|
+
\\ \\\\\\\\\\
|
|
1729
|
+
|
|
1730
|
+
if( !found,
|
|
1731
|
+
|
|
1732
|
+
if( DEBUGLEVEL_ell >= 3, print(" zc = ",zc));
|
|
1733
|
+
liftzc = lift(zc);
|
|
1734
|
+
a = polcoeff(liftzc,0);
|
|
1735
|
+
b =-polcoeff(liftzc,1);
|
|
1736
|
+
c = polcoeff(liftzc,2);
|
|
1737
|
+
if( c, error("bnfell2descent_gen : c <> 0"));
|
|
1738
|
+
|
|
1739
|
+
\\ remove denominators and try to simplify zc
|
|
1740
|
+
cont = idealadd(nf,a,b);
|
|
1741
|
+
if( cont != 1,
|
|
1742
|
+
cont = idealfactor(nf,cont);
|
|
1743
|
+
cont[,2] \= 2;
|
|
1744
|
+
aux = 1;
|
|
1745
|
+
for( i = 1, #cont[,1],
|
|
1746
|
+
\\ *****************************************************************
|
|
1747
|
+
\\ aux = idealmul(nf,aux,idealpow(nf,cont[i,1],cont[i,2]))
|
|
1748
|
+
aux = idealmul(nf,aux,idealpow(nf,idealhnf(nf,cont[i,1]),cont[i,2]))
|
|
1749
|
+
\\ *****************************************************************
|
|
1750
|
+
);
|
|
1751
|
+
cont = nfbasistoalg(nf,bnfisprincipal(bnf,aux)[2])^2;
|
|
1752
|
+
a /= cont;
|
|
1753
|
+
b /= cont;
|
|
1754
|
+
zc/= cont;
|
|
1755
|
+
liftzc = lift(zc);
|
|
1756
|
+
if( DEBUGLEVEL_ell >= 3, print(" new zc = ",zc));
|
|
1757
|
+
);
|
|
1758
|
+
|
|
1759
|
+
if( nfissquare(nf,b),
|
|
1760
|
+
if( DEBUGLEVEL_ell >= 3, print(" b is a square"));
|
|
1761
|
+
point = [a/b,nfsqrt(nf,(a/b)^3+A*(a/b)^2+B*(a/b)+C)[1]];
|
|
1762
|
+
if( DEBUGLEVEL_ell >= 2, print(" point found = ",point));
|
|
1763
|
+
listpoints = concat(listpoints,[point]);
|
|
1764
|
+
found = 1; ispointtriv = 1
|
|
1765
|
+
)
|
|
1766
|
+
);
|
|
1767
|
+
|
|
1768
|
+
\\ \\\\\\\\\\\
|
|
1769
|
+
\\ Construction de la quartique
|
|
1770
|
+
\\ \\\\\\\\\\\
|
|
1771
|
+
|
|
1772
|
+
if( !found, \\ si ce n'est pas un point trivial
|
|
1773
|
+
r = nfsqrt(nf,norm(zc))[1];
|
|
1774
|
+
if( DEBUGLEVEL_ell >= 4, print(" r = ",r));
|
|
1775
|
+
c = -2*(A*b+3*a);
|
|
1776
|
+
if( DEBUGLEVEL_ell >= 4, print(" c = ",c));
|
|
1777
|
+
d = 8*r;
|
|
1778
|
+
if( DEBUGLEVEL_ell >= 4, print(" d = ",d));
|
|
1779
|
+
e = (A^2*b^2 - 2*A*a*b-4*B*b^2-3*a^2);
|
|
1780
|
+
if( DEBUGLEVEL_ell >= 4, print(" e = ",e));
|
|
1781
|
+
polorig = b*('x^4+c*'x^2+d*'x+e)*unnf;
|
|
1782
|
+
if( DEBUGLEVEL_ell >= 2, print(" quartic: (",lift(b),")*Y^2 = ",lift(polorig/b)));
|
|
1783
|
+
pol = polorig;
|
|
1784
|
+
if( bigflag,
|
|
1785
|
+
redq = bnfredquartique(bnf,pol,r,a,b);
|
|
1786
|
+
if( DEBUGLEVEL_ell >= 2, print(" reduced: Y^2 = ",lift(redq[1])));
|
|
1787
|
+
pol = redq[1]; transl = redq[2]; multip = redq[3]
|
|
1788
|
+
);
|
|
1789
|
+
|
|
1790
|
+
\\ Search for a point on the quartic
|
|
1791
|
+
point = nfratpoint(nf,pol,LIM1,1);
|
|
1792
|
+
found = point != [];
|
|
1793
|
+
if( found,
|
|
1794
|
+
loc = 1
|
|
1795
|
+
);
|
|
1796
|
+
\\ If the quartic is not known to be ELS, check if it is
|
|
1797
|
+
if( !loc,
|
|
1798
|
+
if( bigflag,
|
|
1799
|
+
loc = nflocallysoluble(nf,pol,r,a,b)
|
|
1800
|
+
, loc = nflocallysoluble(nf,pol,0,1,1)
|
|
1801
|
+
));
|
|
1802
|
+
if( !loc,
|
|
1803
|
+
listnotELS = concat(listnotELS,[iwhile]);
|
|
1804
|
+
iwhile++;
|
|
1805
|
+
next
|
|
1806
|
+
)
|
|
1807
|
+
);
|
|
1808
|
+
|
|
1809
|
+
\\ If no point is found, search harder
|
|
1810
|
+
if( !found,
|
|
1811
|
+
if( DEBUGLEVEL_ell >= 2, print("quartic is ELS"));
|
|
1812
|
+
point = nfratpoint(nf,pol,LIM3,1);
|
|
1813
|
+
found = point != []
|
|
1814
|
+
);
|
|
1815
|
+
|
|
1816
|
+
if( found && !ispointtriv,
|
|
1817
|
+
if( bigflag,
|
|
1818
|
+
point[1] = point[1]*multip+transl;
|
|
1819
|
+
point[2] = nfsqrt(nf,subst(polorig,'x,point[1]/point[3]))[1]);
|
|
1820
|
+
mattr = matid(3);
|
|
1821
|
+
mattr[1,1] = -2*b^2; mattr[1,2] = (A*b+a)*b;
|
|
1822
|
+
mattr[1,3] = a^2+(2*B-A^2)*b^2; mattr[2,2] = -b;
|
|
1823
|
+
mattr[2,3] = a+A*b; mattr[3,3] =r;
|
|
1824
|
+
UVW = [point[1]^2,point[3]^2,point[1]*point[3]]~;
|
|
1825
|
+
vec = (mattr^(-1))*UVW;
|
|
1826
|
+
z1 = (vec[3]*ttheta+vec[2])*ttheta+vec[1];
|
|
1827
|
+
zc *= z1^2;
|
|
1828
|
+
zc /= -polcoeff(lift(zc),1);
|
|
1829
|
+
if( DEBUGLEVEL_ell >= 3, print(" zc*z1^2 = ",zc));
|
|
1830
|
+
pointxx = polcoeff(lift(zc),0);
|
|
1831
|
+
point2 = [ pointxx, nfsqrt(nf,subst('x^3+A*'x^2+B*'x+C,'x,pointxx))[1]];
|
|
1832
|
+
if( DEBUGLEVEL_ell >= 1, print(" point found = ",point2));
|
|
1833
|
+
listpoints = concat(listpoints,[point2]);
|
|
1834
|
+
);
|
|
1835
|
+
|
|
1836
|
+
listELS = concat(listELS,[iwhile]);
|
|
1837
|
+
if( degre(iwhile) > lastloc, m2++; lastloc = degre(iwhile));
|
|
1838
|
+
|
|
1839
|
+
if( found,
|
|
1840
|
+
m1++;
|
|
1841
|
+
found = 0; lastloc = -1;
|
|
1842
|
+
iwhile = 1<<degre(iwhile);
|
|
1843
|
+
maskwhile >>= 1;
|
|
1844
|
+
LS2coordtilda = vecextract(LS2coordtilda,1<<#listgen-iwhile-1);
|
|
1845
|
+
listgen = vecextract(listgen,1<<#listgen-iwhile-1);
|
|
1846
|
+
while( listELS[#listELS] >= iwhile,
|
|
1847
|
+
listELS = vecextract(listELS,1<<(#listELS-1)-1));
|
|
1848
|
+
while( #listnotELS && listnotELS[#listnotELS] >= iwhile,
|
|
1849
|
+
listnotELS = vecextract(listnotELS,1<<(#listnotELS-1)-1))
|
|
1850
|
+
, iwhile ++
|
|
1851
|
+
)
|
|
1852
|
+
);
|
|
1853
|
+
|
|
1854
|
+
if( DEBUGLEVEL_ell >= 2,
|
|
1855
|
+
print(" m1 = ",m1);
|
|
1856
|
+
print(" m2 = ",m2));
|
|
1857
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1858
|
+
print("#S(E/K)[2] = ",1<<m2));
|
|
1859
|
+
if( m1 == m2,
|
|
1860
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1861
|
+
print("#E(K)/2E(K) = ",1<<m1);
|
|
1862
|
+
print("#III(E/K)[2] = 1");
|
|
1863
|
+
print("rank(E/K) = ",m1));
|
|
1864
|
+
rang = m1
|
|
1865
|
+
,
|
|
1866
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1867
|
+
print("#E(K)/2E(K) >= ",1<<m1);
|
|
1868
|
+
print("#III(E/K)[2] <= ",1<<(m2-m1));
|
|
1869
|
+
print("rank(E/K) >= ",m1));
|
|
1870
|
+
rang = m1;
|
|
1871
|
+
if( (m2-m1)%2,
|
|
1872
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
1873
|
+
print(" III should be a square, hence ");
|
|
1874
|
+
if( m2-m1 > 1,
|
|
1875
|
+
print("#E(K)/2E(K) >= ",1<<(m1+1));
|
|
1876
|
+
print("#III(E/K)[2] <= ",1<<(m2-m1-1));
|
|
1877
|
+
print("rank(E/K) >= ",m1+1)
|
|
1878
|
+
,
|
|
1879
|
+
print("#E(K)/2E(K) = ",1<<(m1+1));
|
|
1880
|
+
print("#III(E/K)[2] = 1");
|
|
1881
|
+
print("rank(E/K) = ",m1+1)));
|
|
1882
|
+
rang = m1+1)
|
|
1883
|
+
);
|
|
1884
|
+
|
|
1885
|
+
if( DEBUGLEVEL_ell >= 1, print(" listpoints = ",listpoints));
|
|
1886
|
+
for( i = 1, #listpoints,
|
|
1887
|
+
if( #listpoints[i] == 3,
|
|
1888
|
+
listpoints[i] = vecextract(listpoints[i],3));
|
|
1889
|
+
if( !ellisoncurve(ellnf,listpoints[i]),
|
|
1890
|
+
error("bnfell2descent: WRONG POINT ")));
|
|
1891
|
+
if( DEBUGLEVEL_ell >= 4, print(" end of bnfell2descent_gen"));
|
|
1892
|
+
return([rang,m2,listpoints]);
|
|
1893
|
+
}
|
|
1894
|
+
{bnfellrank(bnf,ell,help=[],bigflag=1,flag3=1) =
|
|
1895
|
+
\\ Algorithme de la 2-descente sur la courbe elliptique ell.
|
|
1896
|
+
\\ help est une liste de points connus sur ell.
|
|
1897
|
+
|
|
1898
|
+
\\ attention bnf a un polynome en y.
|
|
1899
|
+
\\ si bigflag !=0, on reduit les quartiques
|
|
1900
|
+
\\ si flag3 != 0, on utilise bnfqfsolve2
|
|
1901
|
+
local(urst,urst1,den,factden,eqtheta,rnfeq,bbnf,ext,rang,f);
|
|
1902
|
+
|
|
1903
|
+
if( DEBUGLEVEL_ell >= 3, print(" starting bnfellrank"));
|
|
1904
|
+
if( #ell < 5, ell = ellinit(ell));
|
|
1905
|
+
ell = vector(5, i, ell[i]);
|
|
1906
|
+
|
|
1907
|
+
\\ removes the coefficients a1 and a3
|
|
1908
|
+
urst = [1,0,0,0];
|
|
1909
|
+
if( ell.a1 != 0 || ell.a3 != 0,
|
|
1910
|
+
urst1 = [1,0,-ell.a1/2,-ell.a3/2];
|
|
1911
|
+
ell = ellchangecurve(ell,urst1);
|
|
1912
|
+
urst = ellcomposeurst(urst,urst1)
|
|
1913
|
+
);
|
|
1914
|
+
|
|
1915
|
+
\\ removes denominators
|
|
1916
|
+
while( (den = idealinv(bnf,idealadd(bnf,idealadd(bnf,1,ell.a2),idealadd(bnf,ell.a4,ell.a6))))[1,1] > 1,
|
|
1917
|
+
factden = idealfactor(bnf,den)[,1];
|
|
1918
|
+
den = 1;
|
|
1919
|
+
for( i = 1, #factden,
|
|
1920
|
+
den = idealmul(bnf,den,factden[i]));
|
|
1921
|
+
den = den[1,1];
|
|
1922
|
+
urst1 = [1/den,0,0,0];
|
|
1923
|
+
ell = ellchangecurve(ell,urst1);
|
|
1924
|
+
urst = ellcomposeurst(urst,urst1);
|
|
1925
|
+
);
|
|
1926
|
+
|
|
1927
|
+
help = ellchangepoint(help,urst);
|
|
1928
|
+
|
|
1929
|
+
\\ choix de l'algorithme suivant la 2-torsion
|
|
1930
|
+
ell *= Mod(1,bnf.pol);
|
|
1931
|
+
eqtheta = Pol([1,ell.a2,ell.a4,ell.a6]);
|
|
1932
|
+
if( DEBUGLEVEL_ell >= 1, print(" elliptic curve: Y^2 = ",eqtheta));
|
|
1933
|
+
f = nfpolratroots(bnf,eqtheta);
|
|
1934
|
+
|
|
1935
|
+
if( #f == 0, \\ cas 1: 2-torsion triviale
|
|
1936
|
+
rnfeq = rnfequation(bnf,eqtheta,1);
|
|
1937
|
+
urst1 = [1,-rnfeq[3]*Mod('y,bnf.pol),0,0];
|
|
1938
|
+
if( rnfeq[3] != 0,
|
|
1939
|
+
ell = ellchangecurve(ell,urst1);
|
|
1940
|
+
urst = ellcomposeurst(urst,urst1);
|
|
1941
|
+
eqtheta = subst(eqtheta,'x,'x-rnfeq[3]*Mod('y,bnf.pol));
|
|
1942
|
+
rnfeq = rnfequation(bnf,eqtheta,1);
|
|
1943
|
+
if( DEBUGLEVEL_ell >= 2, print(" translation: working with Y^2 = ",eqtheta));
|
|
1944
|
+
);
|
|
1945
|
+
if( DEBUGLEVEL_ell >= 3, print1(" bbnfinit "));
|
|
1946
|
+
bbnf = bnfinit(rnfeq[1],1);
|
|
1947
|
+
if( DEBUGLEVEL_ell >= 3, print(" done"));
|
|
1948
|
+
ext = [eqtheta, rnfeq, bbnf];
|
|
1949
|
+
rang = bnfell2descent_gen(bnf,ell,ext,help,bigflag,flag3)
|
|
1950
|
+
,
|
|
1951
|
+
if( #f == 1, \\ cas 2: 2-torsion = Z/2Z
|
|
1952
|
+
if( f[1] != 0,
|
|
1953
|
+
urst1 = [1,f[1],0,0];
|
|
1954
|
+
ell = ellchangecurve(ell,urst1);
|
|
1955
|
+
urst = ellcomposeurst(urst,urst1)
|
|
1956
|
+
);
|
|
1957
|
+
rang = bnfell2descent_viaisog(bnf,ell)
|
|
1958
|
+
, \\ cas 3: 2-torsion = Z/2Z*Z/2Z
|
|
1959
|
+
rang = bnfell2descent_complete(bnf,f[1],f[2],f[3],flag3)
|
|
1960
|
+
));
|
|
1961
|
+
|
|
1962
|
+
rang[3] = ellchangepoint(rang[3],ellinverturst(urst));
|
|
1963
|
+
if( DEBUGLEVEL_ell >= 3, print(" end of bnfellrank"));
|
|
1964
|
+
|
|
1965
|
+
return(rang);
|
|
1966
|
+
}
|
|
1967
|
+
{bnfell2descent_complete(bnf,e1,e2,e3,flag3=1,aut=['y]) =
|
|
1968
|
+
\\ calcul du rang d'une courbe elliptique
|
|
1969
|
+
\\ par la methode de 2-descente complete.
|
|
1970
|
+
\\ Y^2 = (x-e1)*(x-e2)*(x-e3);
|
|
1971
|
+
\\ en suivant la methode decrite par J.Silverman
|
|
1972
|
+
\\ si flag3 ==1 alors on utilise bnfqfsolve2 (equation aux normes)
|
|
1973
|
+
\\ pour resoudre Legendre
|
|
1974
|
+
\\ on pourra alors utiliser aut=nfgaloisconj(bnf.pol)
|
|
1975
|
+
|
|
1976
|
+
\\ e1, e2 et e3 sont des entiers algebriques de bnf.
|
|
1977
|
+
|
|
1978
|
+
local(KS2prod,oddclass,KS2gen,vect,selmer,rang,b1,b2,vec,z1,z2,d31,quart0,quart,cont,fa,point,solx,soly,listepoints,strange);
|
|
1979
|
+
|
|
1980
|
+
if( DEBUGLEVEL_ell >= 2, print(" Algorithm of complete 2-descent"));
|
|
1981
|
+
|
|
1982
|
+
\\ calcul de K(S,2)
|
|
1983
|
+
|
|
1984
|
+
KS2prod = (e1-e2)*(e2-e3)*(e3-e1)*2;
|
|
1985
|
+
oddclass = 0;
|
|
1986
|
+
while( !oddclass,
|
|
1987
|
+
KS2gen = bnfsunit(bnf,idealfactor(bnf,KS2prod)[,1]~);
|
|
1988
|
+
oddclass = (KS2gen[5][1]%2);
|
|
1989
|
+
if( !oddclass,
|
|
1990
|
+
KS2prod = idealmul(bnf,KS2prod,(KS2gen[5][3][1])));
|
|
1991
|
+
);
|
|
1992
|
+
KS2gen = KS2gen[1];
|
|
1993
|
+
for( i = 1, #KS2gen,
|
|
1994
|
+
KS2gen[i] = nfbasistoalg(bnf, KS2gen[i]));
|
|
1995
|
+
KS2gen = concat(Mod(lift(concat(bnf.tu[2], bnf.fu)),bnf.pol),KS2gen);
|
|
1996
|
+
if( DEBUGLEVEL_ell >= 2,
|
|
1997
|
+
print(" #K(S,2)gen = ",#KS2gen);
|
|
1998
|
+
print(" K(S,2)gen = ",KS2gen)
|
|
1999
|
+
);
|
|
2000
|
+
|
|
2001
|
+
\\ parcours de K(S,2)*K(S,2)
|
|
2002
|
+
|
|
2003
|
+
vect = vector(#KS2gen,i,[0,1]);
|
|
2004
|
+
selmer = 0;
|
|
2005
|
+
rang = 0;
|
|
2006
|
+
listepoints = [];
|
|
2007
|
+
|
|
2008
|
+
forvec( X = vect,
|
|
2009
|
+
b1 = prod( i = 1, #KS2gen, KS2gen[i]^X[i]);
|
|
2010
|
+
forvec( Y = vect,
|
|
2011
|
+
b2 = prod( i = 1, #KS2gen, KS2gen[i]^Y[i]);
|
|
2012
|
+
|
|
2013
|
+
if( DEBUGLEVEL_ell >= 3, print(" [b1,b2] = ",lift([b1,b2])));
|
|
2014
|
+
|
|
2015
|
+
\\ points triviaux provenant de la 2-torsion
|
|
2016
|
+
|
|
2017
|
+
if( b1==1 && b2==1,
|
|
2018
|
+
if( DEBUGLEVEL_ell >= 2, print(" trivial point [0]"));
|
|
2019
|
+
selmer++; rang++; next);
|
|
2020
|
+
if( nfissquare(bnf.nf,(e2-e1)*b1)
|
|
2021
|
+
&& nfissquare(bnf.nf,(e2-e3)*(e2-e1)*b2),
|
|
2022
|
+
if( DEBUGLEVEL_ell >= 2, print(" trivial point [e2,0]"));
|
|
2023
|
+
selmer++; rang++; next);
|
|
2024
|
+
if( nfissquare(bnf.nf,(e1-e2)*b2)
|
|
2025
|
+
&& nfissquare(bnf.nf,(e1-e3)*(e1-e2)*b1),
|
|
2026
|
+
if( DEBUGLEVEL_ell >= 2, print(" trivial point [e1,0]"));
|
|
2027
|
+
selmer++; rang++; next);
|
|
2028
|
+
if( nfissquare(bnf.nf,(e3-e1)*b1)
|
|
2029
|
+
&& nfissquare(bnf.nf,(e3-e2)*b2),
|
|
2030
|
+
if( DEBUGLEVEL_ell >= 2, print(" trivial point [e3,0]"));
|
|
2031
|
+
selmer++; rang++; next);
|
|
2032
|
+
|
|
2033
|
+
\\ premier critere local : sur les formes quadratiques
|
|
2034
|
+
|
|
2035
|
+
if( mynfhilbert(bnf.nf,b1*b2,b1*(e2-e1)) < 0
|
|
2036
|
+
|| mynfhilbert(bnf.nf,b2,b1*(e3-e1)) < 0
|
|
2037
|
+
|| mynfhilbert(bnf.nf,b1,b2*(e3-e2)) < 0
|
|
2038
|
+
,
|
|
2039
|
+
if( DEBUGLEVEL_ell >= 3, print(" not ELS"));
|
|
2040
|
+
next);
|
|
2041
|
+
|
|
2042
|
+
if( DEBUGLEVEL_ell >= 2, print(" [b1,b2] = ",lift([b1,b2])));
|
|
2043
|
+
if( DEBUGLEVEL_ell >= 2, print(" quadratic forms locally soluble"));
|
|
2044
|
+
|
|
2045
|
+
\\ solution de la premiere forme quadratique
|
|
2046
|
+
|
|
2047
|
+
if( b1 != b2,
|
|
2048
|
+
vec = bnfqfsolve(bnf,b1*b2,b1*(e2-e1),flag3);
|
|
2049
|
+
if( DEBUGLEVEL_ell >= 3, print(" sol part = ",vec));
|
|
2050
|
+
if( vec[3] == 0, error("bnfell2descent_complete: BUG !!! : vec[3]=0 "));
|
|
2051
|
+
z1 = vec[1]/vec[3]/b1; z2 = vec[2]/vec[3]
|
|
2052
|
+
,
|
|
2053
|
+
z1 = (1+(e2-e1)/b1)/2; z2 = z1-1
|
|
2054
|
+
);
|
|
2055
|
+
d31 = e3-e1;
|
|
2056
|
+
quart0 = b2^2*(z1^2*b1 - d31)*'x^4 - 4*z1*b2^2*z2*b1*'x^3
|
|
2057
|
+
+ 2*b1*b2*(z1^2*b1 + 2*b2*z2^2 + d31)*'x^2 - 4*z1*b2*z2*b1^2*'x
|
|
2058
|
+
+ b1^2*(z1^2*b1 - d31);
|
|
2059
|
+
quart = quart0*b1*b2;
|
|
2060
|
+
if( DEBUGLEVEL_ell >= 4, print(" quart = ",quart));
|
|
2061
|
+
quart *= denominator(simplify(content(quart)))^2;
|
|
2062
|
+
cont = simplify(content(lift(quart)));
|
|
2063
|
+
fa = factor(cont);
|
|
2064
|
+
for( i = 1, #fa[,1], quart /= fa[i,1]^(2*(fa[i,2]\2)));
|
|
2065
|
+
if( DEBUGLEVEL_ell >= 3, print(" quartic reduced = ",quart));
|
|
2066
|
+
|
|
2067
|
+
\\ la quartique est-elle localement soluble ?
|
|
2068
|
+
|
|
2069
|
+
if( !nflocallysoluble(bnf.nf,quart),
|
|
2070
|
+
if( DEBUGLEVEL_ell >= 2, print(" quartic not ELS"));
|
|
2071
|
+
next);
|
|
2072
|
+
selmer++;
|
|
2073
|
+
|
|
2074
|
+
\\ recherche de points sur la quartique.
|
|
2075
|
+
|
|
2076
|
+
point = nfratpoint(bnf.nf,quart,LIM3,1);
|
|
2077
|
+
if( point != [],
|
|
2078
|
+
if( DEBUGLEVEL_ell >= 2, print(" point found on the quartic !!"));
|
|
2079
|
+
if( DEBUGLEVEL_ell >= 3, print(" ",point));
|
|
2080
|
+
if( point[3],
|
|
2081
|
+
point /= point[3];
|
|
2082
|
+
z1 = (2*b2*point[1]*z2-z1*(b1+b2*point[1]^2))/(b1-b2*point[1]^2);
|
|
2083
|
+
solx = b1*z1^2+e1;
|
|
2084
|
+
soly = nfsqrt(bnf.nf,(solx-e1)*(solx-e2)*(solx-e3))[1];
|
|
2085
|
+
listepoints = concat(listepoints,[[solx,soly]]);
|
|
2086
|
+
if( DEBUGLEVEL_ell >= 1, print(" point on the elliptic curve =",[solx,soly]))
|
|
2087
|
+
);
|
|
2088
|
+
rang++
|
|
2089
|
+
,
|
|
2090
|
+
if( DEBUGLEVEL_ell >= 2, print(" no point found on the quartic"))
|
|
2091
|
+
)
|
|
2092
|
+
)
|
|
2093
|
+
);
|
|
2094
|
+
|
|
2095
|
+
\\ fin
|
|
2096
|
+
|
|
2097
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
2098
|
+
print("#S^(2) = ",selmer));
|
|
2099
|
+
if( rang > selmer/2, rang = selmer);
|
|
2100
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
2101
|
+
strange = rang != selmer;
|
|
2102
|
+
if( strange,
|
|
2103
|
+
print("#E[K]/2E[K]>= ",rang)
|
|
2104
|
+
, print("#E[K]/2E[K] = ",rang));
|
|
2105
|
+
print("#E[2] = 4");
|
|
2106
|
+
);
|
|
2107
|
+
rang = ceil(log(rang)/log(2))-2;
|
|
2108
|
+
selmer = valuation(selmer,2);
|
|
2109
|
+
if( DEBUGLEVEL_ell >= 1,
|
|
2110
|
+
if( strange,
|
|
2111
|
+
print(selmer-2," >= rank >= ",rang)
|
|
2112
|
+
, print("rank = ",rang));
|
|
2113
|
+
if( rang, print("points = ",listepoints));
|
|
2114
|
+
);
|
|
2115
|
+
|
|
2116
|
+
return([rang,selmer,listepoints]);
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
2120
|
+
\\ HELP MESSAGES \\
|
|
2121
|
+
\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
|
2122
|
+
|
|
2123
|
+
{
|
|
2124
|
+
addhelp(bnfellrank,
|
|
2125
|
+
"bnfellrank(K,E,help=[]): E is a 5-component vector defining an elliptic curve defined over the number field K (output by bnfinit()). Returns a vector [r,s,v], where r is a lower bound for the rank of E(K), s is the rank of its 2-Selmer group and v is a list of independant points in E(K)/2E(K). If help is a vector of nontrivial points on E(K), the result might be faster. See also ?default_ell");
|
|
2126
|
+
\\ others
|
|
2127
|
+
addhelp(default_ell,
|
|
2128
|
+
"default_ell(DEBUGLEVEL_ell, LIM1, LIM3, LIMTRIV, MAXPROB, LIMBIGPRIME): output/set the value of the global variables used for ellrank() and other related functions. DEBUGLEVEL_ell: 0-5 : choose the quantity of information printed during the computation (default=0: print nothing); LIM1 (resp LIM3): search limit for easy (resp hard) points on quartics; LIMTRIV: search limit for trivial points on elliptic curves; MAXPROB, LIMBIGPRIME: technical.");
|
|
2129
|
+
}
|