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,1441 @@
1
+ # sage_setup: distribution = sagemath-pari
2
+ """
3
+ Finite field elements implemented via PARI's FFELT type
4
+
5
+ AUTHORS:
6
+
7
+ - Peter Bruin (June 2013): initial version, based on
8
+ element_ext_pari.py by William Stein et al. and
9
+ element_ntl_gf2e.pyx by Martin Albrecht.
10
+ """
11
+ # ****************************************************************************
12
+ # Copyright (C) 2013 Peter Bruin <peter.bruin@math.uzh.ch>
13
+ #
14
+ # Distributed under the terms of the GNU General Public License (GPL)
15
+ # as published by the Free Software Foundation; either version 2 of
16
+ # the License, or (at your option) any later version.
17
+ # https://www.gnu.org/licenses/
18
+ # ****************************************************************************
19
+
20
+ from cysignals.signals cimport sig_on, sig_off
21
+
22
+ from cypari2.paridecl cimport *
23
+ from cypari2.paripriv cimport *
24
+ from sage.libs.pari.convert_gmp cimport _new_GEN_from_mpz_t
25
+ from cypari2.stack cimport new_gen, new_gen_noclear, clear_stack
26
+ from cypari2.gen cimport Gen as pari_gen, objtogen
27
+
28
+ from sage.rings.finite_rings.element_base cimport FinitePolyExtElement
29
+ from sage.rings.finite_rings.integer_mod import IntegerMod_abstract
30
+
31
+ import sage.rings.integer
32
+ from sage.rings.integer cimport Integer
33
+ from sage.rings.polynomial.polynomial_element import Polynomial
34
+ from sage.rings.polynomial.multi_polynomial_element import MPolynomial
35
+ from sage.rings.rational import Rational
36
+ from sage.structure.element cimport Vector
37
+ from sage.structure.richcmp cimport rich_to_bool
38
+
39
+ from sage.interfaces.abc import GapElement
40
+
41
+
42
+ cdef GEN _INT_to_FFELT(GEN g, GEN x) except NULL:
43
+ """
44
+ Convert the t_INT `x` to an element of the field of definition of
45
+ the t_FFELT `g`.
46
+
47
+ This function must be called within ``sig_on()`` ... ``sig_off()``.
48
+
49
+ TESTS:
50
+
51
+ Converting large integers to finite field elements does not lead
52
+ to overflow errors (see :issue:`16807`)::
53
+
54
+ sage: p = previous_prime(2^64)
55
+ sage: F.<x> = GF(p^2)
56
+ sage: x * 2^63
57
+ 9223372036854775808*x
58
+ """
59
+ cdef GEN f, p = gel(g, 4), result
60
+ cdef long t
61
+
62
+ x = modii(x, p)
63
+ if gequal0(x):
64
+ return FF_zero(g)
65
+ elif gequal1(x):
66
+ return FF_1(g)
67
+ else:
68
+ # In characteristic 2, we have already dealt with the
69
+ # two possible values of x, so we may assume that the
70
+ # characteristic is > 2.
71
+ t = g[1] # codeword: t_FF_FpXQ, t_FF_Flxq, t_FF_F2xq
72
+ if t == t_FF_FpXQ:
73
+ f = cgetg(3, t_POL)
74
+ set_gel(f, 1, gmael(g, 2, 1))
75
+ set_gel(f, 2, x)
76
+ elif t == t_FF_Flxq:
77
+ f = cgetg(3, t_VECSMALL)
78
+ set_gel(f, 1, gmael(g, 2, 1))
79
+ f[2] = itou(x)
80
+ else:
81
+ sig_off()
82
+ raise TypeError("unknown PARI finite field type")
83
+ result = cgetg(5, t_FFELT)
84
+ result[1] = t
85
+ set_gel(result, 2, f)
86
+ set_gel(result, 3, gel(g, 3)) # modulus
87
+ set_gel(result, 4, p)
88
+ return result
89
+
90
+ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):
91
+ """
92
+ An element of a finite field implemented using PARI.
93
+
94
+ EXAMPLES::
95
+
96
+ sage: K = FiniteField(10007^10, 'a', impl='pari_ffelt')
97
+ sage: a = K.gen(); a
98
+ a
99
+ sage: type(a)
100
+ <class 'sage.rings.finite_rings.element_pari_ffelt.FiniteFieldElement_pari_ffelt'>
101
+
102
+ TESTS::
103
+
104
+ sage: n = 63
105
+ sage: m = 3
106
+ sage: K.<a> = GF(2^n, impl='pari_ffelt')
107
+ sage: f = conway_polynomial(2, n)
108
+ sage: f(a) == 0
109
+ True
110
+ sage: e = (2^n - 1) / (2^m - 1)
111
+ sage: conway_polynomial(2, m)(a^e) == 0
112
+ True
113
+
114
+ sage: K.<a> = FiniteField(2^16, impl='pari_ffelt')
115
+ sage: K(0).is_zero()
116
+ True
117
+ sage: (a - a).is_zero()
118
+ True
119
+ sage: a - a
120
+ 0
121
+ sage: a == a
122
+ True
123
+ sage: a - a == 0
124
+ True
125
+ sage: a - a == K(0)
126
+ True
127
+ sage: TestSuite(a).run()
128
+
129
+ Test creating elements from basic Python types::
130
+
131
+ sage: K.<a> = FiniteField(7^20, impl='pari_ffelt')
132
+ sage: K(int(8))
133
+ 1
134
+
135
+ ::
136
+
137
+ sage: k = FiniteField(3^4, 'a', impl='pari_ffelt')
138
+ sage: b = k(5) # indirect doctest
139
+ sage: b.parent()
140
+ Finite Field in a of size 3^4
141
+ sage: a = k.gen()
142
+ sage: k(a + 2)
143
+ a + 2
144
+
145
+ Univariate polynomials coerce into finite fields by evaluating
146
+ the polynomial at the field's generator::
147
+
148
+ sage: R.<x> = QQ[]
149
+ sage: k.<a> = FiniteField(5^2, 'a', impl='pari_ffelt')
150
+ sage: k(R(2/3))
151
+ 4
152
+ sage: k(x^2)
153
+ a + 3
154
+
155
+ sage: R.<x> = GF(5)[]
156
+ sage: k(x^3-2*x+1)
157
+ 2*a + 4
158
+
159
+ sage: x = polygen(QQ)
160
+ sage: k(x^25)
161
+ a
162
+
163
+ sage: Q.<q> = FiniteField(5^7, 'q', impl='pari_ffelt')
164
+ sage: L = GF(5)
165
+ sage: LL.<xx> = L[]
166
+ sage: Q(xx^2 + 2*xx + 4)
167
+ q^2 + 2*q + 4
168
+
169
+ sage: k = FiniteField(3^11, 't', impl='pari_ffelt')
170
+ sage: k.polynomial()
171
+ t^11 + 2*t^2 + 1
172
+ sage: P = k.polynomial_ring()
173
+ sage: k(P.0^11)
174
+ t^2 + 2
175
+
176
+ An element can be specified by its vector of coordinates with
177
+ respect to the basis consisting of powers of the generator:
178
+
179
+ sage: # needs sage.modules
180
+ sage: k = FiniteField(3^11, 't', impl='pari_ffelt')
181
+ sage: V = k.vector_space(map=False)
182
+ sage: V
183
+ Vector space of dimension 11 over Finite Field of size 3
184
+ sage: v = V([0,1,2,0,1,2,0,1,2,0,1])
185
+ sage: k(v)
186
+ t^10 + 2*t^8 + t^7 + 2*t^5 + t^4 + 2*t^2 + t
187
+
188
+ Multivariate polynomials only coerce if constant::
189
+
190
+ sage: k = FiniteField(5^2, 'a', impl='pari_ffelt')
191
+ sage: R = k['x,y,z']; R
192
+ Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 5^2
193
+ sage: k(R(2))
194
+ 2
195
+ sage: R = QQ['x,y,z']
196
+ sage: k(R(1/5))
197
+ Traceback (most recent call last):
198
+ ...
199
+ ZeroDivisionError: inverse of Mod(0, 5) does not exist
200
+
201
+ Gap elements can also be coerced into finite fields::
202
+
203
+ sage: F = FiniteField(2^3, 'a', impl='pari_ffelt')
204
+ sage: a = F.multiplicative_generator(); a
205
+ a
206
+ sage: b = gap(a^3); b # needs sage.libs.gap
207
+ Z(2^3)^3
208
+ sage: F(b) # needs sage.libs.gap
209
+ a + 1
210
+ sage: a^3
211
+ a + 1
212
+
213
+ sage: a = GF(13)(gap('0*Z(13)')); a # needs sage.libs.gap
214
+ 0
215
+ sage: a.parent() # needs sage.libs.gap
216
+ Finite Field of size 13
217
+
218
+ sage: F = FiniteField(2^4, 'a', impl='pari_ffelt')
219
+ sage: F(gap('Z(16)^3')) # needs sage.libs.gap
220
+ a^3
221
+ sage: F(gap('Z(16)^2')) # needs sage.libs.gap
222
+ a^2
223
+
224
+ You can also call a finite extension field with a string
225
+ to produce an element of that field, like this::
226
+
227
+ sage: k = GF(2^8, 'a')
228
+ sage: k('a^200')
229
+ a^4 + a^3 + a^2
230
+
231
+ This is especially useful for conversion from Singular etc.
232
+
233
+ TESTS::
234
+
235
+ sage: k = FiniteField(3^2, 'a', impl='pari_ffelt')
236
+ sage: a = k(11); a
237
+ 2
238
+ sage: a.parent()
239
+ Finite Field in a of size 3^2
240
+ sage: V = k.vector_space(map=False); v = V((1,2)) # needs sage.modules
241
+ sage: k(v) # needs sage.modules
242
+ 2*a + 1
243
+
244
+ We create elements using a list and verify that :issue:`10486` has
245
+ been fixed::
246
+
247
+ sage: k = FiniteField(3^11, 't', impl='pari_ffelt')
248
+ sage: x = k([1,0,2,1]); x
249
+ t^3 + 2*t^2 + 1
250
+ sage: x + x + x
251
+ 0
252
+ sage: pari(x)
253
+ t^3 + 2*t^2 + 1
254
+
255
+ If the list is longer than the degree, we just get the result
256
+ modulo the modulus::
257
+
258
+ sage: from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt
259
+ sage: R.<a> = PolynomialRing(GF(5))
260
+ sage: k = FiniteField_pari_ffelt(5, a^2 - 2, 't')
261
+ sage: x = k([0,0,0,1]); x
262
+ 2*t
263
+ sage: pari(x)
264
+ 2*t
265
+
266
+ When initializing from a list, the elements are first coerced
267
+ to the prime field (:issue:`11685`)::
268
+
269
+ sage: k = FiniteField(3^11, 't', impl='pari_ffelt')
270
+ sage: k([ 0, 1/2 ])
271
+ 2*t
272
+ sage: k([ 0, 1/2, 0, 0, 0, 0, 0, 0, 0, -1, 0 ])
273
+ 2*t^9 + 2*t
274
+ sage: k([ k(0), k(1) ])
275
+ t
276
+ sage: k([ GF(3)(2), GF(3^5,'u')(1) ])
277
+ t + 2
278
+ sage: R.<x> = PolynomialRing(k)
279
+ sage: k([ x/x ])
280
+ 1
281
+ sage: k([ R(-1), x/x ])
282
+ t + 2
283
+ sage: k([ R(-1), R(0), 0 ])
284
+ 2
285
+
286
+ Check that zeros are created correctly (:issue:`11685`)::
287
+
288
+ sage: K = FiniteField(3^11, 't', impl='pari_ffelt'); a = K.0
289
+ sage: v = 0; pari(K(v))
290
+ 0
291
+ sage: v = Mod(0,3); pari(K(v))
292
+ 0
293
+ sage: v = pari(0); pari(K(v))
294
+ 0
295
+ sage: v = pari("Mod(0,3)"); pari(K(v))
296
+ 0
297
+ sage: v = []; pari(K(v))
298
+ 0
299
+ sage: v = [0]; pari(K(v))
300
+ 0
301
+ sage: v = [0,0]; pari(K(v))
302
+ 0
303
+ sage: v = pari("Pol(0)"); pari(K(v))
304
+ 0
305
+ sage: v = pari("Mod(0, %s)"%K.modulus()); pari(K(v))
306
+ 0
307
+ sage: v = pari("Mod(Pol(0), %s)"%K.modulus()); pari(K(v))
308
+ 0
309
+ sage: v = K(1) - K(1); pari(K(v))
310
+ 0
311
+ sage: v = K([1]) - K([1]); pari(K(v))
312
+ 0
313
+ sage: v = a - a; pari(K(v))
314
+ 0
315
+ sage: v = K(1)*0; pari(K(v))
316
+ 0
317
+ sage: v = K([1])*K([0]); pari(K(v))
318
+ 0
319
+ sage: v = a*0; pari(K(v))
320
+ 0
321
+ """
322
+
323
+ def __init__(self, parent, x):
324
+ """
325
+ Initialise ``self`` with the given ``parent`` and value
326
+ converted from ``x``.
327
+
328
+ This is called when constructing elements from Python.
329
+
330
+ TESTS::
331
+
332
+ sage: from sage.rings.finite_rings.element_pari_ffelt import FiniteFieldElement_pari_ffelt
333
+ sage: K = FiniteField(101^2, 'a', impl='pari_ffelt')
334
+ sage: x = FiniteFieldElement_pari_ffelt(K, 'a + 1')
335
+ sage: x
336
+ a + 1
337
+ """
338
+ # FinitePolyExtElement.__init__(self, parent)
339
+ self._parent = parent
340
+ self.construct_from(x)
341
+
342
+ def __dealloc__(self):
343
+ """
344
+ Cython destructor.
345
+ """
346
+ if self.val is not NULL:
347
+ gunclone_deep(self.val)
348
+
349
+ cdef FiniteFieldElement_pari_ffelt _new(self):
350
+ """
351
+ Create an empty element with the same parent as ``self``.
352
+ """
353
+ cdef FiniteFieldElement_pari_ffelt x
354
+ x = FiniteFieldElement_pari_ffelt.__new__(FiniteFieldElement_pari_ffelt)
355
+ x._parent = self._parent
356
+ return x
357
+
358
+ cdef void construct(self, GEN g) noexcept:
359
+ """
360
+ Initialise ``self`` to the FFELT ``g``, reset the PARI stack,
361
+ and call sig_off().
362
+
363
+ This should be called exactly once on every instance.
364
+ """
365
+ self.val = gcloneref(g)
366
+ clear_stack()
367
+
368
+ cdef int construct_from(self, x) except -1:
369
+ """
370
+ Initialise ``self`` to an FFELT constructed from the Sage
371
+ object `x`.
372
+
373
+ TESTS:
374
+
375
+ Conversion of elements of the underlying vector space works in
376
+ large characteristic (see :issue:`21186`)::
377
+
378
+ sage: p = 13189065031705623239
379
+ sage: Fq = FiniteField(p^3, "a")
380
+ sage: Fq_X = PolynomialRing(Fq, "x")
381
+ sage: pol = Fq_X("x^9 + 13189065031705622723*x^7 + 13189065031705622723*x^6 + 9288*x^5 + 18576*x^4 + 13189065031705590731*x^3 + 13189065031705497851*x^2 + 13189065031705497851*x + 13189065031705581443")
382
+ sage: R = [r[0] for r in pol.roots()]
383
+ sage: prod(Fq_X.gen() - r for r in R) == pol
384
+ True
385
+ """
386
+ cdef GEN f, g, result, x_GEN
387
+ cdef long i, n, t
388
+ cdef Integer xi
389
+
390
+ if isinstance(x, FiniteFieldElement_pari_ffelt):
391
+ if self._parent is (<FiniteFieldElement_pari_ffelt>x)._parent:
392
+ sig_on()
393
+ self.construct((<FiniteFieldElement_pari_ffelt>x).val)
394
+ else:
395
+ raise TypeError("no coercion defined")
396
+
397
+ elif isinstance(x, Integer):
398
+ g = (<pari_gen>self._parent._gen_pari).g
399
+ sig_on()
400
+ x_GEN = _new_GEN_from_mpz_t((<Integer>x).value)
401
+ self.construct(_INT_to_FFELT(g, x_GEN))
402
+
403
+ elif isinstance(x, int):
404
+ g = (<pari_gen>self._parent._gen_pari).g
405
+ x = objtogen(x)
406
+ sig_on()
407
+ x_GEN = (<pari_gen>x).g
408
+ self.construct(_INT_to_FFELT(g, x_GEN))
409
+
410
+ elif isinstance(x, IntegerMod_abstract):
411
+ if self._parent.characteristic().divides(x.modulus()):
412
+ g = (<pari_gen>self._parent._gen_pari).g
413
+ sig_on()
414
+ x_GEN = _new_GEN_from_mpz_t(Integer(x).value)
415
+ self.construct(_INT_to_FFELT(g, x_GEN))
416
+ else:
417
+ raise TypeError("no coercion defined")
418
+
419
+ elif x is None:
420
+ g = (<pari_gen>self._parent._gen_pari).g
421
+ sig_on()
422
+ self.construct(FF_zero(g))
423
+
424
+ elif isinstance(x, pari_gen):
425
+ g = (<pari_gen>self._parent._gen_pari).g
426
+ x_GEN = (<pari_gen>x).g
427
+
428
+ sig_on()
429
+ if gequal0(x_GEN):
430
+ self.construct(FF_zero(g))
431
+ return 0
432
+ elif gequal1(x_GEN):
433
+ self.construct(FF_1(g))
434
+ return 0
435
+
436
+ t = typ(x_GEN)
437
+ if t == t_FFELT:
438
+ if FF_samefield(x_GEN, g):
439
+ self.construct(x_GEN)
440
+ return 0
441
+ elif t == t_INT:
442
+ self.construct(_INT_to_FFELT(g, x_GEN))
443
+ return 0
444
+ elif t == t_INTMOD:
445
+ if gequal0(modii(gel(x_GEN, 1), FF_p_i(g))):
446
+ self.construct(_INT_to_FFELT(g, gel(x_GEN, 2)))
447
+ return 0
448
+ elif t == t_FRAC:
449
+ if not gequal0(modii(gel(x_GEN, 2), FF_p_i(g))):
450
+ elt = FF_div(_INT_to_FFELT(g, gel(x_GEN, 1)),
451
+ _INT_to_FFELT(g, gel(x_GEN, 2)))
452
+ self.construct(elt)
453
+ return 0
454
+ sig_off()
455
+ raise TypeError(f"unable to convert PARI {x.type()} to finite field element")
456
+
457
+ elif (isinstance(x, Vector)
458
+ and x.parent() is self._parent.vector_space(map=False)):
459
+ g = (<pari_gen>self._parent._gen_pari).g
460
+ t = g[1] # codeword: t_FF_FpXQ, t_FF_Flxq, t_FF_F2xq
461
+ n = len(x)
462
+ while n > 0 and x[n - 1] == 0:
463
+ n -= 1
464
+ sig_on()
465
+ if n == 0:
466
+ self.construct(FF_zero(g))
467
+ return 0
468
+ if t == t_FF_FpXQ:
469
+ f = cgetg(n + 2, t_POL)
470
+ set_gel(f, 1, gmael(g, 2, 1))
471
+ for i in range(n):
472
+ xi = Integer(x[i])
473
+ set_gel(f, i + 2, _new_GEN_from_mpz_t(xi.value))
474
+ elif t == t_FF_Flxq or t == t_FF_F2xq:
475
+ f = cgetg(n + 2, t_VECSMALL)
476
+ set_gel(f, 1, gmael(g, 2, 1))
477
+ for i in range(n):
478
+ set_uel(f, i + 2, x[i])
479
+ if t == t_FF_F2xq:
480
+ f = Flx_to_F2x(f)
481
+ else:
482
+ sig_off()
483
+ raise TypeError("unknown PARI finite field type")
484
+ result = cgetg(5, t_FFELT)
485
+ result[1] = t
486
+ set_gel(result, 2, f)
487
+ set_gel(result, 3, gel(g, 3)) # modulus
488
+ set_gel(result, 4, gel(g, 4)) # p
489
+ self.construct(result)
490
+
491
+ elif isinstance(x, Rational):
492
+ self.construct_from(x % self._parent.characteristic())
493
+
494
+ elif isinstance(x, Polynomial):
495
+ if x.base_ring() is not self._parent.base_ring():
496
+ x = x.change_ring(self._parent.base_ring())
497
+ self.construct_from(x.substitute(self._parent.gen()))
498
+
499
+ elif isinstance(x, MPolynomial) and x.is_constant():
500
+ self.construct_from(x.constant_coefficient())
501
+
502
+ elif isinstance(x, list):
503
+ n = len(x)
504
+ if n == 0:
505
+ self.construct_from(None)
506
+ elif n == 1:
507
+ Fp = self._parent.base_ring()
508
+ self.construct_from(Fp(x[0]))
509
+ elif n == self._parent.degree():
510
+ self.construct_from(self._parent.vector_space(map=False)(x))
511
+ else:
512
+ Fp = self._parent.base_ring()
513
+ self.construct_from(self._parent.polynomial_ring()([Fp(y) for y in x]))
514
+
515
+ elif isinstance(x, str):
516
+ self.construct_from(self._parent.polynomial_ring()(x))
517
+
518
+ elif isinstance(x, GapElement):
519
+ try:
520
+ from sage.libs.gap.libgap import libgap
521
+ self.construct_from(libgap(x).sage(ring=self._parent))
522
+ except (ValueError, IndexError, TypeError):
523
+ raise TypeError("no coercion defined")
524
+
525
+ else:
526
+ try:
527
+ from sage.libs.gap.element import GapElement_FiniteField
528
+ except ImportError:
529
+ raise TypeError("no coercion defined")
530
+ else:
531
+ if isinstance(x, GapElement_FiniteField):
532
+ try:
533
+ self.construct_from(x.sage(ring=self._parent))
534
+ except (ValueError, IndexError, TypeError):
535
+ raise TypeError("no coercion defined")
536
+ else:
537
+ raise TypeError("no coercion defined")
538
+
539
+ def _repr_(self):
540
+ """
541
+ Return the string representation of ``self``.
542
+
543
+ EXAMPLES::
544
+
545
+ sage: k.<c> = GF(3^17, impl='pari_ffelt')
546
+ sage: c^20 # indirect doctest
547
+ c^4 + 2*c^3
548
+ """
549
+ return str(new_gen_noclear(self.val))
550
+
551
+ def __hash__(self):
552
+ """
553
+ Return the hash of ``self``. This is by definition equal to
554
+ the hash of ``self.polynomial()``.
555
+
556
+ EXAMPLES::
557
+
558
+ sage: k.<a> = GF(3^15, impl='pari_ffelt')
559
+ sage: R = GF(3)['a']; aa = R.gen()
560
+ sage: hash(a^2 + 1) == hash(aa^2 + 1)
561
+ True
562
+ """
563
+ return hash(self.polynomial())
564
+
565
+ def __reduce__(self):
566
+ """
567
+ For pickling.
568
+
569
+ TESTS::
570
+
571
+ sage: K.<a> = FiniteField(10007^10, impl='pari_ffelt')
572
+ sage: loads(a.dumps()) == a
573
+ True
574
+ """
575
+ return unpickle_FiniteFieldElement_pari_ffelt, (self._parent, str(self))
576
+
577
+ def __copy__(self):
578
+ """
579
+ TESTS::
580
+
581
+ sage: k.<a> = FiniteField(3^3, impl='pari_ffelt')
582
+ sage: a
583
+ a
584
+ sage: b = copy(a); b
585
+ a
586
+ sage: a is b
587
+ True
588
+ """
589
+ # immutable
590
+ return self
591
+
592
+ def __deepcopy__(self, memo):
593
+ """
594
+ TESTS::
595
+
596
+ sage: k.<a> = FiniteField(3^3, impl='pari_ffelt')
597
+ sage: a
598
+ a
599
+ sage: b = deepcopy(a); b
600
+ a
601
+ sage: a is b
602
+ True
603
+ """
604
+ # immutable
605
+ return self
606
+
607
+ cpdef _richcmp_(self, other, int op):
608
+ """
609
+ Comparison of finite field elements.
610
+
611
+ .. NOTE::
612
+
613
+ Finite fields are unordered. However, for the purpose of
614
+ this function, we adopt the lexicographic ordering on the
615
+ representing polynomials.
616
+
617
+ EXAMPLES::
618
+
619
+ sage: # needs sage.modules
620
+ sage: k.<a> = GF(2^20, impl='pari_ffelt')
621
+ sage: e = k.random_element()
622
+ sage: f = loads(dumps(e))
623
+ sage: e is f
624
+ False
625
+ sage: e == f
626
+ True
627
+ sage: e != (e + 1)
628
+ True
629
+
630
+ ::
631
+
632
+ sage: K.<a> = GF(2^100, impl='pari_ffelt')
633
+ sage: a < a^2
634
+ True
635
+ sage: a > a^2
636
+ False
637
+ sage: a+1 > a^2
638
+ False
639
+ sage: a+1 < a^2
640
+ True
641
+ sage: a+1 < a
642
+ False
643
+ sage: a+1 == a
644
+ False
645
+ sage: a == a
646
+ True
647
+
648
+ TESTS::
649
+
650
+ sage: k.<a> = FiniteField(3^3, impl='pari_ffelt')
651
+ sage: a == 1
652
+ False
653
+ sage: a^0 == 1
654
+ True
655
+ sage: a == a
656
+ True
657
+ sage: a < a^2
658
+ True
659
+ sage: a > a^2
660
+ False
661
+ """
662
+ cdef int r
663
+ sig_on()
664
+ r = cmp_universal(self.val, (<FiniteFieldElement_pari_ffelt>other).val)
665
+ sig_off()
666
+ return rich_to_bool(op, r)
667
+
668
+ cpdef _add_(self, right):
669
+ """
670
+ Addition.
671
+
672
+ EXAMPLES::
673
+
674
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
675
+ sage: a + a^2 # indirect doctest
676
+ a^2 + a
677
+ """
678
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
679
+ sig_on()
680
+ x.construct(FF_add((<FiniteFieldElement_pari_ffelt>self).val,
681
+ (<FiniteFieldElement_pari_ffelt>right).val))
682
+ return x
683
+
684
+ cpdef _sub_(self, right):
685
+ """
686
+ Subtraction.
687
+
688
+ EXAMPLES::
689
+
690
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
691
+ sage: a - a # indirect doctest
692
+ 0
693
+ """
694
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
695
+ sig_on()
696
+ x.construct(FF_sub((<FiniteFieldElement_pari_ffelt>self).val,
697
+ (<FiniteFieldElement_pari_ffelt>right).val))
698
+ return x
699
+
700
+ cpdef _mul_(self, right):
701
+ """
702
+ Multiplication.
703
+
704
+ EXAMPLES::
705
+
706
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
707
+ sage: (a^12 + 1)*(a^15 - 1) # indirect doctest
708
+ a^15 + 2*a^12 + a^11 + 2*a^10 + 2
709
+ """
710
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
711
+ sig_on()
712
+ x.construct(FF_mul((<FiniteFieldElement_pari_ffelt>self).val,
713
+ (<FiniteFieldElement_pari_ffelt>right).val))
714
+ return x
715
+
716
+ cpdef _div_(self, right):
717
+ """
718
+ Division.
719
+
720
+ EXAMPLES::
721
+
722
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
723
+ sage: (a - 1) / (a + 1) # indirect doctest
724
+ 2*a^16 + a^15 + 2*a^14 + a^13 + 2*a^12 + a^11 + 2*a^10 + a^9 + 2*a^8 + a^7 + 2*a^6 + a^5 + 2*a^4 + a^3 + 2*a^2 + a + 1
725
+ """
726
+ if FF_equal0((<FiniteFieldElement_pari_ffelt>right).val):
727
+ raise ZeroDivisionError
728
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
729
+ sig_on()
730
+ x.construct(FF_div((<FiniteFieldElement_pari_ffelt>self).val,
731
+ (<FiniteFieldElement_pari_ffelt>right).val))
732
+ return x
733
+
734
+ def is_zero(self):
735
+ """
736
+ Return ``True`` if ``self`` equals 0.
737
+
738
+ EXAMPLES::
739
+
740
+ sage: F.<a> = FiniteField(5^3, impl='pari_ffelt')
741
+ sage: a.is_zero()
742
+ False
743
+ sage: (a - a).is_zero()
744
+ True
745
+ """
746
+ return bool(FF_equal0(self.val))
747
+
748
+ def is_one(self):
749
+ """
750
+ Return ``True`` if ``self`` equals 1.
751
+
752
+ EXAMPLES::
753
+
754
+ sage: F.<a> = FiniteField(5^3, impl='pari_ffelt')
755
+ sage: a.is_one()
756
+ False
757
+ sage: (a/a).is_one()
758
+ True
759
+ """
760
+ return bool(FF_equal1(self.val))
761
+
762
+ def is_unit(self):
763
+ """
764
+ Return ``True`` if ``self`` is nonzero.
765
+
766
+ EXAMPLES::
767
+
768
+ sage: F.<a> = FiniteField(5^3, impl='pari_ffelt')
769
+ sage: a.is_unit()
770
+ True
771
+ """
772
+ return not bool(FF_equal0(self.val))
773
+
774
+ __bool__ = is_unit
775
+
776
+ def __pos__(self):
777
+ """
778
+ Unitary positive operator...
779
+
780
+ EXAMPLES::
781
+
782
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
783
+ sage: +a
784
+ a
785
+ """
786
+ return self
787
+
788
+ def __neg__(self):
789
+ """
790
+ Negation.
791
+
792
+ EXAMPLES::
793
+
794
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
795
+ sage: -a
796
+ 2*a
797
+ """
798
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
799
+ sig_on()
800
+ x.construct(FF_neg_i((<FiniteFieldElement_pari_ffelt>self).val))
801
+ return x
802
+
803
+ def __invert__(self):
804
+ """
805
+ Return the multiplicative inverse of ``self``.
806
+
807
+ EXAMPLES::
808
+
809
+ sage: k.<a> = FiniteField(3^2, impl='pari_ffelt')
810
+ sage: ~a
811
+ a + 2
812
+ sage: (a+1)*a
813
+ 2*a + 1
814
+ sage: ~((2*a)/a)
815
+ 2
816
+ """
817
+ if FF_equal0(self.val):
818
+ raise ZeroDivisionError
819
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
820
+ sig_on()
821
+ x.construct(FF_inv((<FiniteFieldElement_pari_ffelt>self).val))
822
+ return x
823
+
824
+ def __pow__(FiniteFieldElement_pari_ffelt self, exp, other):
825
+ """
826
+ Exponentiation.
827
+
828
+ TESTS::
829
+
830
+ sage: K.<a> = GF(5^10, impl='pari_ffelt')
831
+ sage: n = (2*a)/a
832
+ sage: n^-15
833
+ 2
834
+
835
+ Large exponents are not a problem::
836
+
837
+ sage: e = 3^10000
838
+ sage: a^e
839
+ 2*a^9 + a^5 + 4*a^4 + 4*a^3 + a^2 + 3*a
840
+ sage: a^(e % (5^10 - 1))
841
+ 2*a^9 + a^5 + 4*a^4 + 4*a^3 + a^2 + 3*a
842
+
843
+ The exponent is converted to an integer (see :issue:`16540`)::
844
+
845
+ sage: q = 11^23
846
+ sage: F.<a> = FiniteField(q)
847
+ sage: a^Mod(1, q - 1)
848
+ a
849
+
850
+ .. WARNING::
851
+
852
+ For efficiency reasons, we do not verify that the
853
+ exponentiation is well defined before converting the
854
+ exponent to an integer. This means that ``a^Mod(1, n)``
855
+ returns `a` even if `n` is not a multiple of the
856
+ multiplicative order of `a`.
857
+ """
858
+ if exp == 0:
859
+ return self._parent.one()
860
+ if exp < 0 and FF_equal0(self.val):
861
+ raise ZeroDivisionError
862
+ exp = Integer(exp).__pari__()
863
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
864
+ sig_on()
865
+ x.construct(FF_pow(self.val, (<pari_gen>exp).g))
866
+ return x
867
+
868
+ def pth_power(FiniteFieldElement_pari_ffelt self, int k=1):
869
+ r"""
870
+ Return the `(p^k)`-th power of ``self``, where `p` is the
871
+ characteristic of the field.
872
+
873
+ INPUT:
874
+
875
+ - ``k`` -- integer (default: 1); must fit in a C ``int``
876
+
877
+ Note that if `k` is negative, then this computes the appropriate root.
878
+
879
+ TESTS::
880
+
881
+ sage: # needs sage.modules
882
+ sage: F.<a> = GF(13^64, impl='pari_ffelt'); F
883
+ Finite Field in a of size 13^64
884
+ sage: x = F.random_element()
885
+ sage: x.pth_power(0) == x
886
+ True
887
+ sage: x.pth_power(1) == x**13
888
+ True
889
+ sage: x.pth_power(2) == x**(13**2)
890
+ True
891
+ sage: x.pth_power(-1)**13 == x
892
+ True
893
+
894
+ sage: # needs sage.modules
895
+ sage: F.<a> = GF(127^16, impl='pari_ffelt'); F
896
+ Finite Field in a of size 127^16
897
+ sage: x = F.random_element()
898
+ sage: x.pth_power(0) == x
899
+ True
900
+ sage: x.pth_power(1) == x**127
901
+ True
902
+ sage: x.pth_power(2) == x**(127**2)
903
+ True
904
+ sage: x.pth_power(-1)**127 == x
905
+ True
906
+ """
907
+ cdef int n = int(self._parent.degree())
908
+ if k % n == 0:
909
+ return self
910
+ cdef Integer p = self._parent.characteristic()
911
+ if k == 1 and (p < 100 or p.bit_length()**2 < n):
912
+ # For extremely small primes or very large extension degrees,
913
+ # exponentiation is faster.
914
+ return self**p
915
+ # Otherwise use PARI field morphism (evaluation of a Fp polynomial
916
+ # at the image of the generator).
917
+ f = self._parent._pari_frobenius(k)
918
+ cdef FiniteFieldElement_pari_ffelt x = self._new()
919
+ sig_on()
920
+ x.construct(ffmap((<pari_gen>f).g, self.val))
921
+ return x
922
+
923
+ frobenius = pth_power
924
+
925
+ def polynomial(self, name=None):
926
+ """
927
+ Return the unique representative of ``self`` as a polynomial
928
+ over the prime field whose degree is less than the degree of
929
+ the finite field over its prime field.
930
+
931
+ INPUT:
932
+
933
+ - ``name`` -- (optional) variable name
934
+
935
+ EXAMPLES::
936
+
937
+ sage: k.<a> = FiniteField(3^2, impl='pari_ffelt')
938
+ sage: pol = a.polynomial()
939
+ sage: pol
940
+ a
941
+ sage: parent(pol)
942
+ Univariate Polynomial Ring in a over Finite Field of size 3
943
+
944
+ ::
945
+
946
+ sage: k = FiniteField(3^4, 'alpha', impl='pari_ffelt')
947
+ sage: a = k.gen()
948
+ sage: a.polynomial()
949
+ alpha
950
+ sage: (a**2 + 1).polynomial('beta')
951
+ beta^2 + 1
952
+ sage: (a**2 + 1).polynomial().parent()
953
+ Univariate Polynomial Ring in alpha over Finite Field of size 3
954
+ sage: (a**2 + 1).polynomial('beta').parent()
955
+ Univariate Polynomial Ring in beta over Finite Field of size 3
956
+ """
957
+ sig_on()
958
+ pol = new_gen(FF_to_FpXQ(self.val))
959
+ return self._parent.polynomial_ring(name)(pol)
960
+
961
+ def minpoly(self, var='x'):
962
+ """
963
+ Return the minimal polynomial of ``self``.
964
+
965
+ INPUT:
966
+
967
+ - ``var`` -- string (default: ``'x'``); variable name to use
968
+
969
+ EXAMPLES::
970
+
971
+ sage: R.<x> = PolynomialRing(FiniteField(3))
972
+ sage: F.<a> = FiniteField(3^2, modulus=x^2 + 1, impl='pari_ffelt')
973
+ sage: a.minpoly('y')
974
+ y^2 + 1
975
+ """
976
+ sig_on()
977
+ pol = new_gen(FF_minpoly(self.val))
978
+ return self._parent.polynomial_ring(var)(pol)
979
+
980
+ def charpoly(self, var='x'):
981
+ """
982
+ Return the characteristic polynomial of ``self``.
983
+
984
+ INPUT:
985
+
986
+ - ``var`` -- string (default: ``'x'``); variable name to use
987
+
988
+ EXAMPLES::
989
+
990
+ sage: R.<x> = PolynomialRing(FiniteField(3))
991
+ sage: F.<a> = FiniteField(3^2, modulus=x^2 + 1, impl='pari_ffelt')
992
+ sage: a.charpoly('y')
993
+ y^2 + 1
994
+ """
995
+ sig_on()
996
+ pol = new_gen(FF_charpoly(self.val))
997
+ return self._parent.polynomial_ring(var)(pol)
998
+
999
+ def is_square(self):
1000
+ """
1001
+ Return ``True`` if and only if ``self`` is a square in the
1002
+ finite field.
1003
+
1004
+ EXAMPLES::
1005
+
1006
+ sage: k.<a> = FiniteField(3^2, impl='pari_ffelt')
1007
+ sage: a.is_square()
1008
+ False
1009
+ sage: (a**2).is_square()
1010
+ True
1011
+
1012
+ sage: k.<a> = FiniteField(2^2, impl='pari_ffelt')
1013
+ sage: (a**2).is_square()
1014
+ True
1015
+
1016
+ sage: k.<a> = FiniteField(17^5, impl='pari_ffelt')
1017
+ sage: (a**2).is_square()
1018
+ True
1019
+ sage: a.is_square()
1020
+ False
1021
+ sage: k(0).is_square()
1022
+ True
1023
+ """
1024
+ cdef long i
1025
+ sig_on()
1026
+ i = FF_issquare(self.val)
1027
+ sig_off()
1028
+ return bool(i)
1029
+
1030
+ def sqrt(self, extend=False, all=False):
1031
+ """
1032
+ Return a square root of ``self``, if it exists.
1033
+
1034
+ INPUT:
1035
+
1036
+ - ``extend`` -- boolean (default: ``False``)
1037
+
1038
+ .. WARNING::
1039
+
1040
+ This option is not implemented.
1041
+
1042
+ - ``all`` -- boolean (default: ``False``)
1043
+
1044
+ OUTPUT:
1045
+
1046
+ A square root of ``self``, if it exists. If ``all`` is
1047
+ ``True``, a list containing all square roots of ``self``
1048
+ (of length zero, one or two) is returned instead.
1049
+
1050
+ If ``extend`` is ``True``, a square root is chosen in an
1051
+ extension field if necessary. If ``extend`` is ``False``, a
1052
+ :exc:`ValueError` is raised if the element is not a square in the
1053
+ base field.
1054
+
1055
+ .. WARNING::
1056
+
1057
+ The ``extend`` option is not implemented (yet).
1058
+
1059
+ EXAMPLES::
1060
+
1061
+ sage: F = FiniteField(7^2, 'a', impl='pari_ffelt')
1062
+ sage: F(2).sqrt()
1063
+ 4
1064
+ sage: F(3).sqrt() in (2*F.gen() + 6, 5*F.gen() + 1)
1065
+ True
1066
+ sage: F(3).sqrt()**2
1067
+ 3
1068
+ sage: F(4).sqrt(all=True)
1069
+ [2, 5]
1070
+
1071
+ sage: K = FiniteField(7^3, 'alpha', impl='pari_ffelt')
1072
+ sage: K(3).sqrt()
1073
+ Traceback (most recent call last):
1074
+ ...
1075
+ ValueError: element is not a square
1076
+ sage: K(3).sqrt(all=True)
1077
+ []
1078
+
1079
+ sage: K.<a> = GF(3^17, impl='pari_ffelt')
1080
+ sage: (a^3 - a - 1).sqrt()
1081
+ a^16 + 2*a^15 + a^13 + 2*a^12 + a^10 + 2*a^9 + 2*a^8 + a^7 + a^6 + 2*a^5 + a^4 + 2*a^2 + 2*a + 2
1082
+ """
1083
+ if extend:
1084
+ raise NotImplementedError
1085
+ cdef GEN s
1086
+ cdef FiniteFieldElement_pari_ffelt x, mx
1087
+ sig_on()
1088
+ if FF_issquareall(self.val, &s):
1089
+ x = self._new()
1090
+ x.construct(s)
1091
+ if not all:
1092
+ return x
1093
+ elif gequal0(x.val) or self._parent.characteristic() == 2:
1094
+ return [x]
1095
+ else:
1096
+ sig_on()
1097
+ mx = self._new()
1098
+ mx.construct(FF_neg_i(x.val))
1099
+ return [x, mx]
1100
+ else:
1101
+ sig_off()
1102
+ if all:
1103
+ return []
1104
+ else:
1105
+ raise ValueError("element is not a square")
1106
+
1107
+ def log(self, base, order=None, *, check=False):
1108
+ """
1109
+ Return a discrete logarithm of ``self`` with respect to the
1110
+ given base.
1111
+
1112
+ INPUT:
1113
+
1114
+ - ``base`` -- nonzero field element
1115
+ - ``order`` -- integer (optional), the order of the base
1116
+ - ``check`` -- boolean (default: ``False``); if set,
1117
+ test whether the given ``order`` is correct
1118
+
1119
+ OUTPUT:
1120
+
1121
+ An integer `x` such that ``self`` equals ``base`` raised to
1122
+ the power `x`. If no such `x` exists, a :exc:`ValueError` is
1123
+ raised.
1124
+
1125
+ EXAMPLES::
1126
+
1127
+ sage: F.<g> = FiniteField(2^10, impl='pari_ffelt')
1128
+ sage: b = g; a = g^37
1129
+ sage: a.log(b)
1130
+ 37
1131
+ sage: b^37; a
1132
+ g^8 + g^7 + g^4 + g + 1
1133
+ g^8 + g^7 + g^4 + g + 1
1134
+
1135
+ ::
1136
+
1137
+ sage: F.<a> = FiniteField(5^2, impl='pari_ffelt')
1138
+ sage: F(-1).log(F(2))
1139
+ 2
1140
+ sage: F(1).log(a)
1141
+ 0
1142
+
1143
+ ::
1144
+
1145
+ sage: # needs sage.modules
1146
+ sage: p = 2^127 - 1
1147
+ sage: F.<t> = GF((p, 3))
1148
+ sage: elt = F.random_element()^(p^2+p+1)
1149
+ sage: (elt^2).log(elt, p-1)
1150
+ 2
1151
+
1152
+ Passing the ``order`` argument can lead to huge speedups when
1153
+ factoring the order of the entire unit group is expensive but
1154
+ the order of the base element is much smaller::
1155
+
1156
+ sage: %timeit (elt^2).log(elt) # not tested
1157
+ 6.18 s ± 85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1158
+ sage: %timeit (elt^2).log(elt, p-1) # not tested
1159
+ 147 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
1160
+
1161
+ Some cases where the logarithm is not defined or does not exist::
1162
+
1163
+ sage: F.<a> = GF(3^10, impl='pari_ffelt')
1164
+ sage: a.log(-1)
1165
+ Traceback (most recent call last):
1166
+ ...
1167
+ ArithmeticError: element a does not lie in group generated by 2
1168
+ sage: a.log(0)
1169
+ Traceback (most recent call last):
1170
+ ...
1171
+ ArithmeticError: discrete logarithm with base 0 is not defined
1172
+ sage: F(0).log(1)
1173
+ Traceback (most recent call last):
1174
+ ...
1175
+ ArithmeticError: discrete logarithm of 0 is not defined
1176
+
1177
+ TESTS:
1178
+
1179
+ An example for ``check=True``::
1180
+
1181
+ sage: a = GF(101^5).primitive_element()
1182
+ sage: a.log(a, 10510100500, check=True)
1183
+ 1
1184
+ sage: a.log(a, 5255050250, check=True)
1185
+ Traceback (most recent call last):
1186
+ ...
1187
+ ValueError: element does not have the provided order
1188
+ """
1189
+ base = self._parent(base)
1190
+ if self.is_zero():
1191
+ raise ArithmeticError("discrete logarithm of 0 is not defined")
1192
+ if base.is_zero():
1193
+ raise ArithmeticError("discrete logarithm with base 0 is not defined")
1194
+
1195
+ # Compute the order of the base to check whether the element actually
1196
+ # lies in the group generated by the base. PARI may otherwise enter an
1197
+ # infinite loop.
1198
+ # We also have to specify the order of the base anyway as PARI assumes
1199
+ # by default that the base generates the entire multiplicative group.
1200
+ cdef GEN x, base_order
1201
+ sig_on()
1202
+ if order is None:
1203
+ base_order = FF_order((<FiniteFieldElement_pari_ffelt>base).val, NULL)
1204
+ else:
1205
+ if check:
1206
+ from sage.groups.generic import has_order
1207
+ if not has_order(base, order, '*'):
1208
+ clear_stack()
1209
+ raise ValueError('element does not have the provided order')
1210
+ base_order = _new_GEN_from_mpz_t((<Integer>order).value)
1211
+ if not gequal1(powgi(self.val, base_order)):
1212
+ clear_stack()
1213
+ raise ArithmeticError(f'element {self} does not lie in group generated by {base}')
1214
+ x = FF_log(self.val, (<FiniteFieldElement_pari_ffelt>base).val, base_order)
1215
+ return Integer(new_gen(x))
1216
+
1217
+ def multiplicative_order(self):
1218
+ """
1219
+ Return the order of ``self`` in the multiplicative group.
1220
+
1221
+ EXAMPLES::
1222
+
1223
+ sage: a = FiniteField(5^3, 'a', impl='pari_ffelt').0
1224
+ sage: a.multiplicative_order()
1225
+ 124
1226
+ sage: a**124
1227
+ 1
1228
+ """
1229
+ if self.is_zero():
1230
+ raise ArithmeticError("Multiplicative order of 0 not defined.")
1231
+ cdef GEN order
1232
+ sig_on()
1233
+ order = FF_order(self.val, NULL)
1234
+ return Integer(new_gen(order))
1235
+
1236
+ def lift(self):
1237
+ """
1238
+ If ``self`` is an element of the prime field, return a lift of
1239
+ this element to an integer.
1240
+
1241
+ EXAMPLES::
1242
+
1243
+ sage: k = FiniteField(next_prime(10^10)^2, 'u', impl='pari_ffelt')
1244
+ sage: a = k(17)/k(19)
1245
+ sage: b = a.lift(); b
1246
+ 7894736858
1247
+ sage: b.parent()
1248
+ Integer Ring
1249
+ """
1250
+ if FF_equal0(self.val):
1251
+ return Integer(0)
1252
+ f = self.polynomial()
1253
+ if f.degree() == 0:
1254
+ return f.constant_coefficient().lift()
1255
+ else:
1256
+ raise ValueError("element is not in the prime field")
1257
+
1258
+ def _integer_(self, ZZ=None):
1259
+ """
1260
+ Lift to a Sage integer, if possible.
1261
+
1262
+ EXAMPLES::
1263
+
1264
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
1265
+ sage: b = k(2)
1266
+ sage: b._integer_()
1267
+ 2
1268
+ sage: a._integer_()
1269
+ Traceback (most recent call last):
1270
+ ...
1271
+ ValueError: element is not in the prime field
1272
+ """
1273
+ return self.lift()
1274
+
1275
+ def __int__(self):
1276
+ """
1277
+ Lift to a python int, if possible.
1278
+
1279
+ EXAMPLES::
1280
+
1281
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
1282
+ sage: b = k(2)
1283
+ sage: int(b)
1284
+ 2
1285
+ sage: int(a)
1286
+ Traceback (most recent call last):
1287
+ ...
1288
+ ValueError: element is not in the prime field
1289
+ """
1290
+ return int(self.lift())
1291
+
1292
+ def __float__(self):
1293
+ """
1294
+ Lift to a python float, if possible.
1295
+
1296
+ EXAMPLES::
1297
+
1298
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
1299
+ sage: b = k(2)
1300
+ sage: float(b)
1301
+ 2.0
1302
+ """
1303
+ return float(self.lift())
1304
+
1305
+ def __pari__(self, var=None):
1306
+ """
1307
+ Return a PARI object representing ``self``.
1308
+
1309
+ EXAMPLES::
1310
+
1311
+ sage: k.<a> = FiniteField(3^3, impl='pari_ffelt')
1312
+ sage: b = a**2 + 2*a + 1
1313
+ sage: b.__pari__()
1314
+ a^2 + 2*a + 1
1315
+ """
1316
+ return new_gen_noclear(self.val)
1317
+
1318
+ def _pari_init_(self):
1319
+ """
1320
+ Return a string representing ``self`` in PARI.
1321
+
1322
+ EXAMPLES::
1323
+
1324
+ sage: k.<a> = GF(3^17, impl='pari_ffelt')
1325
+ sage: a._pari_init_()
1326
+ 'subst(a+3*a,a,ffgen(Mod(1, 3)*x^17 + Mod(2, 3)*x + Mod(1, 3),a))'
1327
+ sage: k(1)._pari_init_()
1328
+ 'subst(1+3*a,a,ffgen(Mod(1, 3)*x^17 + Mod(2, 3)*x + Mod(1, 3),a))'
1329
+
1330
+ This is used for conversion to GP. The element is displayed
1331
+ as "a" but has correct arithmetic::
1332
+
1333
+ sage: gp(a)
1334
+ a
1335
+ sage: gp(a).type()
1336
+ t_FFELT
1337
+ sage: gp(a)^100
1338
+ 2*a^16 + 2*a^15 + a^4 + a + 1
1339
+ sage: gp(a^100)
1340
+ 2*a^16 + 2*a^15 + a^4 + a + 1
1341
+ sage: gp(k(0))
1342
+ 0
1343
+ sage: gp(k(0)).type()
1344
+ t_FFELT
1345
+ """
1346
+ ffgen = "ffgen(%s,a)" % self._parent.modulus()._pari_init_()
1347
+ # Add this "zero" to ensure that the polynomial is not constant
1348
+ zero = "%s*a" % self._parent.characteristic()
1349
+ return "subst(%s+%s,a,%s)" % (self, zero, ffgen)
1350
+
1351
+ def _magma_init_(self, magma):
1352
+ """
1353
+ Return a string representing ``self`` in Magma.
1354
+
1355
+ EXAMPLES::
1356
+
1357
+ sage: GF(7)(3)._magma_init_(magma) # optional - magma
1358
+ 'GF(7)!3'
1359
+ """
1360
+ k = self._parent
1361
+ km = magma(k)
1362
+ return str(self).replace(k.variable_name(), km.gen(1).name())
1363
+
1364
+ def _gap_init_(self):
1365
+ r"""
1366
+ Return the string representing ``self`` in GAP.
1367
+
1368
+ .. NOTE::
1369
+
1370
+ The order of the parent field must be `\leq 65536`. This
1371
+ function can be slow since elements of non-prime finite
1372
+ fields are represented in GAP as powers of a generator for
1373
+ the multiplicative group, so a discrete logarithm must be
1374
+ computed.
1375
+
1376
+ EXAMPLES::
1377
+
1378
+ sage: # needs sage.libs.gap
1379
+ sage: F = FiniteField(2^3, 'aa', impl='pari_ffelt')
1380
+ sage: aa = F.multiplicative_generator()
1381
+ sage: gap(aa) # indirect doctest
1382
+ Z(2^3)
1383
+ sage: b = F.multiplicative_generator()
1384
+ sage: a = b^3
1385
+ sage: gap(a)
1386
+ Z(2^3)^3
1387
+ sage: gap(a^3)
1388
+ Z(2^3)^2
1389
+ sage: F(gap('Z(8)^3'))
1390
+ aa + 1
1391
+ sage: F(libgap.Z(8)^3)
1392
+ aa + 1
1393
+
1394
+ You can specify the instance of the Gap interpreter that is used::
1395
+
1396
+ sage: # needs sage.libs.gap
1397
+ sage: F = FiniteField(next_prime(200)^2, 'a', impl='pari_ffelt')
1398
+ sage: a = F.multiplicative_generator()
1399
+ sage: a._gap_ (gap)
1400
+ Z(211^2)
1401
+ sage: (a^20)._gap_(gap)
1402
+ Z(211^2)^20
1403
+
1404
+ Gap only supports relatively small finite fields::
1405
+
1406
+ sage: # needs sage.libs.gap
1407
+ sage: F = FiniteField(next_prime(1000)^2, 'a', impl='pari_ffelt')
1408
+ sage: a = F.multiplicative_generator()
1409
+ sage: a._gap_init_()
1410
+ Traceback (most recent call last):
1411
+ ...
1412
+ TypeError: order must be at most 65536
1413
+ sage: gap.coerce(a)
1414
+ Traceback (most recent call last):
1415
+ ...
1416
+ TypeError: no canonical coercion from Finite Field in a of size 1009^2 to Gap
1417
+ """
1418
+ F = self._parent
1419
+ if F.order() > 65536:
1420
+ raise TypeError("order must be at most 65536")
1421
+
1422
+ if self == 0:
1423
+ return '0*Z(%s)' % F.order()
1424
+ assert F.degree() > 1
1425
+ g = F.multiplicative_generator()
1426
+ n = self.log(g)
1427
+ return 'Z(%s)^%s' % (F.order(), n)
1428
+
1429
+
1430
+ def unpickle_FiniteFieldElement_pari_ffelt(parent, elem):
1431
+ """
1432
+ EXAMPLES::
1433
+
1434
+ sage: # needs sage.modules
1435
+ sage: k.<a> = GF(2^20, impl='pari_ffelt')
1436
+ sage: e = k.random_element()
1437
+ sage: f = loads(dumps(e)) # indirect doctest
1438
+ sage: e == f
1439
+ True
1440
+ """
1441
+ return parent(elem)