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.

Files changed (331) hide show
  1. PARIKernel/__init__.py +2 -0
  2. PARIKernel/__main__.py +5 -0
  3. PARIKernel/io.cpython-314-x86_64-linux-musl.so +0 -0
  4. PARIKernel/io.pxd +7 -0
  5. PARIKernel/io.pyx +84 -0
  6. PARIKernel/kernel.cpython-314-x86_64-linux-musl.so +0 -0
  7. PARIKernel/kernel.pyx +260 -0
  8. PARIKernel/paridecl.pxd +95 -0
  9. PARIKernel/svg.cpython-314-x86_64-linux-musl.so +0 -0
  10. PARIKernel/svg.pyx +52 -0
  11. cypari2/__init__.py +8 -0
  12. cypari2/auto_paridecl.pxd +1070 -0
  13. cypari2/closure.cpython-314-x86_64-linux-musl.so +0 -0
  14. cypari2/closure.pxd +5 -0
  15. cypari2/closure.pyx +246 -0
  16. cypari2/convert.cpython-314-x86_64-linux-musl.so +0 -0
  17. cypari2/convert.pxd +80 -0
  18. cypari2/convert.pyx +613 -0
  19. cypari2/custom_block.cpython-314-x86_64-linux-musl.so +0 -0
  20. cypari2/custom_block.pyx +30 -0
  21. cypari2/cypari.h +13 -0
  22. cypari2/gen.cpython-314-x86_64-linux-musl.so +0 -0
  23. cypari2/gen.pxd +69 -0
  24. cypari2/gen.pyx +4819 -0
  25. cypari2/handle_error.cpython-314-x86_64-linux-musl.so +0 -0
  26. cypari2/handle_error.pxd +7 -0
  27. cypari2/handle_error.pyx +232 -0
  28. cypari2/pari_instance.cpython-314-x86_64-linux-musl.so +0 -0
  29. cypari2/pari_instance.pxd +27 -0
  30. cypari2/pari_instance.pyx +1438 -0
  31. cypari2/paridecl.pxd +5353 -0
  32. cypari2/paripriv.pxd +34 -0
  33. cypari2/pycore_long.h +98 -0
  34. cypari2/pycore_long.pxd +9 -0
  35. cypari2/stack.cpython-314-x86_64-linux-musl.so +0 -0
  36. cypari2/stack.pxd +27 -0
  37. cypari2/stack.pyx +278 -0
  38. cypari2/string_utils.cpython-314-x86_64-linux-musl.so +0 -0
  39. cypari2/string_utils.pxd +29 -0
  40. cypari2/string_utils.pyx +65 -0
  41. cypari2/types.pxd +147 -0
  42. passagemath_pari-10.6.32.data/data/etc/jupyter/nbconfig/notebook.d/gp-mode.json +5 -0
  43. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.js +28 -0
  44. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.json +6 -0
  45. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/logo-64x64.png +0 -0
  46. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/kernel.json +13 -0
  47. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-32x32.png +0 -0
  48. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-64x64.png +0 -0
  49. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-svg.svg +75 -0
  50. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/gp.js +284 -0
  51. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/main.js +15 -0
  52. passagemath_pari-10.6.32.dist-info/METADATA +209 -0
  53. passagemath_pari-10.6.32.dist-info/RECORD +331 -0
  54. passagemath_pari-10.6.32.dist-info/WHEEL +5 -0
  55. passagemath_pari-10.6.32.dist-info/top_level.txt +4 -0
  56. passagemath_pari.libs/libcrypto-f04afe95.so.3 +0 -0
  57. passagemath_pari.libs/libflint-fd6f12fc.so.21.0.0 +0 -0
  58. passagemath_pari.libs/libgcc_s-0cd532bd.so.1 +0 -0
  59. passagemath_pari.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  60. passagemath_pari.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
  61. passagemath_pari.libs/libgivaro-9a94c711.so.9.2.1 +0 -0
  62. passagemath_pari.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  63. passagemath_pari.libs/libgmpxx-9e08595c.so.4.7.0 +0 -0
  64. passagemath_pari.libs/libgsl-42cda06f.so.28.0.0 +0 -0
  65. passagemath_pari.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  66. passagemath_pari.libs/libncursesw-9c9e32c3.so.6.5 +0 -0
  67. passagemath_pari.libs/libntl-26885ca2.so.44.0.1 +0 -0
  68. passagemath_pari.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
  69. passagemath_pari.libs/libpari-gmp-tls-f31f908f.so.2.17.2 +0 -0
  70. passagemath_pari.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
  71. passagemath_pari.libs/libreadline-06542304.so.8.2 +0 -0
  72. passagemath_pari.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  73. passagemath_pari.libs/libuuid-f3770415.so.1.3.0 +0 -0
  74. passagemath_pari.libs/libxeus-735780ff.so.13.1.0 +0 -0
  75. passagemath_pari.libs/libxeus-zmq-c68577b4.so.6.0.1 +0 -0
  76. passagemath_pari.libs/libzmq-1ba9a3da.so.5.2.5 +0 -0
  77. sage/all__sagemath_pari.py +26 -0
  78. sage/databases/all__sagemath_pari.py +7 -0
  79. sage/databases/conway.py +274 -0
  80. sage/ext/all__sagemath_pari.py +1 -0
  81. sage/ext/memory.cpython-314-x86_64-linux-musl.so +0 -0
  82. sage/ext/memory.pyx +98 -0
  83. sage/ext_data/pari/buzzard/DimensionSk.g +286 -0
  84. sage/ext_data/pari/buzzard/Tpprog.g +179 -0
  85. sage/ext_data/pari/buzzard/genusn.g +129 -0
  86. sage/ext_data/pari/dokchitser/computel.gp +740 -0
  87. sage/ext_data/pari/dokchitser/computel.gp.template +740 -0
  88. sage/ext_data/pari/dokchitser/ex-bsw +43 -0
  89. sage/ext_data/pari/dokchitser/ex-chgen +48 -0
  90. sage/ext_data/pari/dokchitser/ex-chqua +37 -0
  91. sage/ext_data/pari/dokchitser/ex-delta +35 -0
  92. sage/ext_data/pari/dokchitser/ex-eisen +30 -0
  93. sage/ext_data/pari/dokchitser/ex-gen2 +38 -0
  94. sage/ext_data/pari/dokchitser/ex-gen3 +49 -0
  95. sage/ext_data/pari/dokchitser/ex-gen4 +54 -0
  96. sage/ext_data/pari/dokchitser/ex-nf +48 -0
  97. sage/ext_data/pari/dokchitser/ex-shin +50 -0
  98. sage/ext_data/pari/dokchitser/ex-tau2 +30 -0
  99. sage/ext_data/pari/dokchitser/ex-zeta +27 -0
  100. sage/ext_data/pari/dokchitser/ex-zeta2 +47 -0
  101. sage/ext_data/pari/dokchitser/testall +13 -0
  102. sage/ext_data/pari/simon/ell.gp +2129 -0
  103. sage/ext_data/pari/simon/ellQ.gp +2151 -0
  104. sage/ext_data/pari/simon/ellcommon.gp +126 -0
  105. sage/ext_data/pari/simon/qfsolve.gp +722 -0
  106. sage/ext_data/pari/simon/resultant3.gp +306 -0
  107. sage/groups/all__sagemath_pari.py +3 -0
  108. sage/groups/pari_group.py +175 -0
  109. sage/interfaces/all__sagemath_pari.py +1 -0
  110. sage/interfaces/genus2reduction.py +464 -0
  111. sage/interfaces/gp.py +1114 -0
  112. sage/libs/all__sagemath_pari.py +2 -0
  113. sage/libs/linkages/__init__.py +1 -0
  114. sage/libs/linkages/padics/API.pxi +617 -0
  115. sage/libs/linkages/padics/Polynomial_ram.pxi +388 -0
  116. sage/libs/linkages/padics/Polynomial_shared.pxi +554 -0
  117. sage/libs/linkages/padics/__init__.py +1 -0
  118. sage/libs/linkages/padics/fmpz_poly_unram.pxi +869 -0
  119. sage/libs/linkages/padics/mpz.pxi +691 -0
  120. sage/libs/linkages/padics/relaxed/API.pxi +518 -0
  121. sage/libs/linkages/padics/relaxed/__init__.py +1 -0
  122. sage/libs/linkages/padics/relaxed/flint.pxi +543 -0
  123. sage/libs/linkages/padics/unram_shared.pxi +247 -0
  124. sage/libs/pari/__init__.py +210 -0
  125. sage/libs/pari/all.py +5 -0
  126. sage/libs/pari/convert_flint.cpython-314-x86_64-linux-musl.so +0 -0
  127. sage/libs/pari/convert_flint.pxd +14 -0
  128. sage/libs/pari/convert_flint.pyx +159 -0
  129. sage/libs/pari/convert_gmp.cpython-314-x86_64-linux-musl.so +0 -0
  130. sage/libs/pari/convert_gmp.pxd +14 -0
  131. sage/libs/pari/convert_gmp.pyx +210 -0
  132. sage/libs/pari/convert_sage.cpython-314-x86_64-linux-musl.so +0 -0
  133. sage/libs/pari/convert_sage.pxd +16 -0
  134. sage/libs/pari/convert_sage.pyx +588 -0
  135. sage/libs/pari/convert_sage_complex_double.cpython-314-x86_64-linux-musl.so +0 -0
  136. sage/libs/pari/convert_sage_complex_double.pxd +14 -0
  137. sage/libs/pari/convert_sage_complex_double.pyx +132 -0
  138. sage/libs/pari/convert_sage_matrix.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/libs/pari/convert_sage_matrix.pyx +106 -0
  140. sage/libs/pari/convert_sage_real_double.cpython-314-x86_64-linux-musl.so +0 -0
  141. sage/libs/pari/convert_sage_real_double.pxd +5 -0
  142. sage/libs/pari/convert_sage_real_double.pyx +14 -0
  143. sage/libs/pari/convert_sage_real_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
  144. sage/libs/pari/convert_sage_real_mpfr.pxd +7 -0
  145. sage/libs/pari/convert_sage_real_mpfr.pyx +108 -0
  146. sage/libs/pari/misc.cpython-314-x86_64-linux-musl.so +0 -0
  147. sage/libs/pari/misc.pxd +4 -0
  148. sage/libs/pari/misc.pyx +26 -0
  149. sage/libs/pari/tests.py +1848 -0
  150. sage/matrix/all__sagemath_pari.py +1 -0
  151. sage/matrix/matrix_integer_pari.cpython-314-x86_64-linux-musl.so +0 -0
  152. sage/matrix/matrix_integer_pari.pyx +187 -0
  153. sage/matrix/matrix_rational_pari.cpython-314-x86_64-linux-musl.so +0 -0
  154. sage/matrix/matrix_rational_pari.pyx +160 -0
  155. sage/quadratic_forms/all__sagemath_pari.py +10 -0
  156. sage/quadratic_forms/genera/all.py +9 -0
  157. sage/quadratic_forms/genera/genus.py +3506 -0
  158. sage/quadratic_forms/genera/normal_form.py +1519 -0
  159. sage/quadratic_forms/genera/spinor_genus.py +243 -0
  160. sage/quadratic_forms/qfsolve.py +255 -0
  161. sage/quadratic_forms/quadratic_form__automorphisms.py +427 -0
  162. sage/quadratic_forms/quadratic_form__genus.py +141 -0
  163. sage/quadratic_forms/quadratic_form__local_density_interfaces.py +140 -0
  164. sage/quadratic_forms/quadratic_form__local_normal_form.py +421 -0
  165. sage/quadratic_forms/quadratic_form__local_representation_conditions.py +889 -0
  166. sage/quadratic_forms/quadratic_form__mass.py +69 -0
  167. sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +663 -0
  168. sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +373 -0
  169. sage/quadratic_forms/quadratic_form__siegel_product.py +198 -0
  170. sage/quadratic_forms/special_values.py +323 -0
  171. sage/rings/all__sagemath_pari.py +15 -0
  172. sage/rings/factorint_pari.cpython-314-x86_64-linux-musl.so +0 -0
  173. sage/rings/factorint_pari.pyx +80 -0
  174. sage/rings/finite_rings/all__sagemath_pari.py +1 -0
  175. sage/rings/finite_rings/element_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  176. sage/rings/finite_rings/element_givaro.pxd +91 -0
  177. sage/rings/finite_rings/element_givaro.pyx +1769 -0
  178. sage/rings/finite_rings/element_ntl_gf2e.cpython-314-x86_64-linux-musl.so +0 -0
  179. sage/rings/finite_rings/element_ntl_gf2e.pxd +22 -0
  180. sage/rings/finite_rings/element_ntl_gf2e.pyx +1333 -0
  181. sage/rings/finite_rings/element_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  182. sage/rings/finite_rings/element_pari_ffelt.pxd +13 -0
  183. sage/rings/finite_rings/element_pari_ffelt.pyx +1441 -0
  184. sage/rings/finite_rings/finite_field_givaro.py +612 -0
  185. sage/rings/finite_rings/finite_field_pari_ffelt.py +238 -0
  186. sage/rings/finite_rings/hom_finite_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  187. sage/rings/finite_rings/hom_finite_field_givaro.pxd +28 -0
  188. sage/rings/finite_rings/hom_finite_field_givaro.pyx +280 -0
  189. sage/rings/finite_rings/residue_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  190. sage/rings/finite_rings/residue_field_givaro.pyx +133 -0
  191. sage/rings/finite_rings/residue_field_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  192. sage/rings/finite_rings/residue_field_pari_ffelt.pyx +128 -0
  193. sage/rings/function_field/all__sagemath_pari.py +1 -0
  194. sage/rings/function_field/valuation.py +1450 -0
  195. sage/rings/function_field/valuation_ring.py +212 -0
  196. sage/rings/number_field/all__sagemath_pari.py +14 -0
  197. sage/rings/number_field/totallyreal.cpython-314-x86_64-linux-musl.so +0 -0
  198. sage/rings/number_field/totallyreal.pyx +509 -0
  199. sage/rings/number_field/totallyreal_data.cpython-314-x86_64-linux-musl.so +0 -0
  200. sage/rings/number_field/totallyreal_data.pxd +26 -0
  201. sage/rings/number_field/totallyreal_data.pyx +928 -0
  202. sage/rings/number_field/totallyreal_phc.py +144 -0
  203. sage/rings/number_field/totallyreal_rel.py +1018 -0
  204. sage/rings/padics/CA_template.pxi +1847 -0
  205. sage/rings/padics/CA_template_header.pxi +50 -0
  206. sage/rings/padics/CR_template.pxi +2563 -0
  207. sage/rings/padics/CR_template_header.pxi +57 -0
  208. sage/rings/padics/FM_template.pxi +1575 -0
  209. sage/rings/padics/FM_template_header.pxi +50 -0
  210. sage/rings/padics/FP_template.pxi +2176 -0
  211. sage/rings/padics/FP_template_header.pxi +57 -0
  212. sage/rings/padics/all.py +3 -0
  213. sage/rings/padics/all__sagemath_pari.py +11 -0
  214. sage/rings/padics/common_conversion.cpython-314-x86_64-linux-musl.so +0 -0
  215. sage/rings/padics/common_conversion.pxd +15 -0
  216. sage/rings/padics/common_conversion.pyx +508 -0
  217. sage/rings/padics/eisenstein_extension_generic.py +232 -0
  218. sage/rings/padics/factory.py +3623 -0
  219. sage/rings/padics/generic_nodes.py +1615 -0
  220. sage/rings/padics/lattice_precision.py +2889 -0
  221. sage/rings/padics/morphism.cpython-314-x86_64-linux-musl.so +0 -0
  222. sage/rings/padics/morphism.pxd +11 -0
  223. sage/rings/padics/morphism.pyx +366 -0
  224. sage/rings/padics/padic_base_generic.py +467 -0
  225. sage/rings/padics/padic_base_leaves.py +1235 -0
  226. sage/rings/padics/padic_capped_absolute_element.cpython-314-x86_64-linux-musl.so +0 -0
  227. sage/rings/padics/padic_capped_absolute_element.pxd +15 -0
  228. sage/rings/padics/padic_capped_absolute_element.pyx +520 -0
  229. sage/rings/padics/padic_capped_relative_element.cpython-314-x86_64-linux-musl.so +0 -0
  230. sage/rings/padics/padic_capped_relative_element.pxd +14 -0
  231. sage/rings/padics/padic_capped_relative_element.pyx +614 -0
  232. sage/rings/padics/padic_extension_generic.py +990 -0
  233. sage/rings/padics/padic_extension_leaves.py +738 -0
  234. sage/rings/padics/padic_fixed_mod_element.cpython-314-x86_64-linux-musl.so +0 -0
  235. sage/rings/padics/padic_fixed_mod_element.pxd +15 -0
  236. sage/rings/padics/padic_fixed_mod_element.pyx +584 -0
  237. sage/rings/padics/padic_floating_point_element.cpython-314-x86_64-linux-musl.so +0 -0
  238. sage/rings/padics/padic_floating_point_element.pxd +14 -0
  239. sage/rings/padics/padic_floating_point_element.pyx +447 -0
  240. sage/rings/padics/padic_generic_element.cpython-314-x86_64-linux-musl.so +0 -0
  241. sage/rings/padics/padic_generic_element.pxd +48 -0
  242. sage/rings/padics/padic_generic_element.pyx +4642 -0
  243. sage/rings/padics/padic_lattice_element.py +1342 -0
  244. sage/rings/padics/padic_printing.cpython-314-x86_64-linux-musl.so +0 -0
  245. sage/rings/padics/padic_printing.pxd +38 -0
  246. sage/rings/padics/padic_printing.pyx +1505 -0
  247. sage/rings/padics/padic_relaxed_element.cpython-314-x86_64-linux-musl.so +0 -0
  248. sage/rings/padics/padic_relaxed_element.pxd +56 -0
  249. sage/rings/padics/padic_relaxed_element.pyx +18 -0
  250. sage/rings/padics/padic_relaxed_errors.cpython-314-x86_64-linux-musl.so +0 -0
  251. sage/rings/padics/padic_relaxed_errors.pxd +11 -0
  252. sage/rings/padics/padic_relaxed_errors.pyx +71 -0
  253. sage/rings/padics/padic_template_element.pxi +1212 -0
  254. sage/rings/padics/padic_template_element_header.pxi +50 -0
  255. sage/rings/padics/padic_valuation.py +1423 -0
  256. sage/rings/padics/pow_computer_flint.cpython-314-x86_64-linux-musl.so +0 -0
  257. sage/rings/padics/pow_computer_flint.pxd +38 -0
  258. sage/rings/padics/pow_computer_flint.pyx +641 -0
  259. sage/rings/padics/pow_computer_relative.cpython-314-x86_64-linux-musl.so +0 -0
  260. sage/rings/padics/pow_computer_relative.pxd +29 -0
  261. sage/rings/padics/pow_computer_relative.pyx +415 -0
  262. sage/rings/padics/qadic_flint_CA.cpython-314-x86_64-linux-musl.so +0 -0
  263. sage/rings/padics/qadic_flint_CA.pxd +21 -0
  264. sage/rings/padics/qadic_flint_CA.pyx +130 -0
  265. sage/rings/padics/qadic_flint_CR.cpython-314-x86_64-linux-musl.so +0 -0
  266. sage/rings/padics/qadic_flint_CR.pxd +13 -0
  267. sage/rings/padics/qadic_flint_CR.pyx +172 -0
  268. sage/rings/padics/qadic_flint_FM.cpython-314-x86_64-linux-musl.so +0 -0
  269. sage/rings/padics/qadic_flint_FM.pxd +14 -0
  270. sage/rings/padics/qadic_flint_FM.pyx +111 -0
  271. sage/rings/padics/qadic_flint_FP.cpython-314-x86_64-linux-musl.so +0 -0
  272. sage/rings/padics/qadic_flint_FP.pxd +12 -0
  273. sage/rings/padics/qadic_flint_FP.pyx +165 -0
  274. sage/rings/padics/relative_extension_leaves.py +429 -0
  275. sage/rings/padics/relative_ramified_CA.cpython-314-x86_64-linux-musl.so +0 -0
  276. sage/rings/padics/relative_ramified_CA.pxd +9 -0
  277. sage/rings/padics/relative_ramified_CA.pyx +33 -0
  278. sage/rings/padics/relative_ramified_CR.cpython-314-x86_64-linux-musl.so +0 -0
  279. sage/rings/padics/relative_ramified_CR.pxd +8 -0
  280. sage/rings/padics/relative_ramified_CR.pyx +33 -0
  281. sage/rings/padics/relative_ramified_FM.cpython-314-x86_64-linux-musl.so +0 -0
  282. sage/rings/padics/relative_ramified_FM.pxd +9 -0
  283. sage/rings/padics/relative_ramified_FM.pyx +33 -0
  284. sage/rings/padics/relative_ramified_FP.cpython-314-x86_64-linux-musl.so +0 -0
  285. sage/rings/padics/relative_ramified_FP.pxd +8 -0
  286. sage/rings/padics/relative_ramified_FP.pyx +33 -0
  287. sage/rings/padics/relaxed_template.pxi +4229 -0
  288. sage/rings/padics/relaxed_template_header.pxi +160 -0
  289. sage/rings/padics/tests.py +35 -0
  290. sage/rings/padics/tutorial.py +341 -0
  291. sage/rings/padics/unramified_extension_generic.py +335 -0
  292. sage/rings/padics/witt_vector.py +917 -0
  293. sage/rings/padics/witt_vector_ring.py +934 -0
  294. sage/rings/pari_ring.py +235 -0
  295. sage/rings/polynomial/all__sagemath_pari.py +1 -0
  296. sage/rings/polynomial/padics/all.py +1 -0
  297. sage/rings/polynomial/padics/polynomial_padic.py +360 -0
  298. sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +1324 -0
  299. sage/rings/polynomial/padics/polynomial_padic_flat.py +72 -0
  300. sage/rings/power_series_pari.cpython-314-x86_64-linux-musl.so +0 -0
  301. sage/rings/power_series_pari.pxd +6 -0
  302. sage/rings/power_series_pari.pyx +934 -0
  303. sage/rings/tate_algebra.py +1282 -0
  304. sage/rings/tate_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
  305. sage/rings/tate_algebra_element.pxd +49 -0
  306. sage/rings/tate_algebra_element.pyx +3464 -0
  307. sage/rings/tate_algebra_ideal.cpython-314-x86_64-linux-musl.so +0 -0
  308. sage/rings/tate_algebra_ideal.pxd +7 -0
  309. sage/rings/tate_algebra_ideal.pyx +1307 -0
  310. sage/rings/valuation/all.py +7 -0
  311. sage/rings/valuation/augmented_valuation.py +2118 -0
  312. sage/rings/valuation/developing_valuation.py +362 -0
  313. sage/rings/valuation/gauss_valuation.py +812 -0
  314. sage/rings/valuation/inductive_valuation.py +1686 -0
  315. sage/rings/valuation/limit_valuation.py +946 -0
  316. sage/rings/valuation/mapped_valuation.py +656 -0
  317. sage/rings/valuation/scaled_valuation.py +322 -0
  318. sage/rings/valuation/trivial_valuation.py +382 -0
  319. sage/rings/valuation/valuation.py +1119 -0
  320. sage/rings/valuation/valuation_space.py +1615 -0
  321. sage/rings/valuation/valuations_catalog.py +10 -0
  322. sage/rings/valuation/value_group.py +697 -0
  323. sage/schemes/all__sagemath_pari.py +1 -0
  324. sage/schemes/elliptic_curves/all__sagemath_pari.py +1 -0
  325. sage/schemes/elliptic_curves/descent_two_isogeny_pari.cpython-314-x86_64-linux-musl.so +0 -0
  326. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pyx +46 -0
  327. sage_wheels/bin/gp +0 -0
  328. sage_wheels/bin/gp2c +0 -0
  329. sage_wheels/bin/gp2c-run +57 -0
  330. sage_wheels/bin/xeus-gp +0 -0
  331. 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
+ }