passagemath-singular 10.6.31rc3__cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_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-singular might be problematic. Click here for more details.

Files changed (491) hide show
  1. PySingular.cpython-314-x86_64-linux-gnu.so +0 -0
  2. passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
  3. passagemath_singular-10.6.31rc3.dist-info/RECORD +491 -0
  4. passagemath_singular-10.6.31rc3.dist-info/WHEEL +6 -0
  5. passagemath_singular-10.6.31rc3.dist-info/top_level.txt +3 -0
  6. passagemath_singular.libs/libSingular-4-20aec911.4.1.so +0 -0
  7. passagemath_singular.libs/libcddgmp-21acf0c6.so.0.1.3 +0 -0
  8. passagemath_singular.libs/libfactory-4-fcee31da.4.1.so +0 -0
  9. passagemath_singular.libs/libflint-66e12231.so.21.0.0 +0 -0
  10. passagemath_singular.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  11. passagemath_singular.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
  12. passagemath_singular.libs/libgmp-6e109695.so.10.5.0 +0 -0
  13. passagemath_singular.libs/libgsl-cda90e79.so.28.0.0 +0 -0
  14. passagemath_singular.libs/libmpfr-82690d50.so.6.2.1 +0 -0
  15. passagemath_singular.libs/libntl-e6f0d543.so.44.0.1 +0 -0
  16. passagemath_singular.libs/libomalloc-0-5c9e866e.9.6.so +0 -0
  17. passagemath_singular.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
  18. passagemath_singular.libs/libpolys-4-5c0a87e0.4.1.so +0 -0
  19. passagemath_singular.libs/libquadmath-2284e583.so.0.0.0 +0 -0
  20. passagemath_singular.libs/libreadline-ea270e21.so.8.2 +0 -0
  21. passagemath_singular.libs/libsingular_resources-4-a1aafc6d.4.1.so +0 -0
  22. passagemath_singular.libs/libtinfo-ceb117d9.so.6.3 +0 -0
  23. sage/algebras/all__sagemath_singular.py +3 -0
  24. sage/algebras/fusion_rings/all.py +19 -0
  25. sage/algebras/fusion_rings/f_matrix.py +2448 -0
  26. sage/algebras/fusion_rings/fast_parallel_fmats_methods.cpython-314-x86_64-linux-gnu.so +0 -0
  27. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pxd +5 -0
  28. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +538 -0
  29. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.cpython-314-x86_64-linux-gnu.so +0 -0
  30. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pxd +3 -0
  31. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +331 -0
  32. sage/algebras/fusion_rings/fusion_double.py +899 -0
  33. sage/algebras/fusion_rings/fusion_ring.py +1580 -0
  34. sage/algebras/fusion_rings/poly_tup_engine.cpython-314-x86_64-linux-gnu.so +0 -0
  35. sage/algebras/fusion_rings/poly_tup_engine.pxd +24 -0
  36. sage/algebras/fusion_rings/poly_tup_engine.pyx +579 -0
  37. sage/algebras/fusion_rings/shm_managers.cpython-314-x86_64-linux-gnu.so +0 -0
  38. sage/algebras/fusion_rings/shm_managers.pxd +24 -0
  39. sage/algebras/fusion_rings/shm_managers.pyx +780 -0
  40. sage/algebras/letterplace/all.py +1 -0
  41. sage/algebras/letterplace/free_algebra_element_letterplace.cpython-314-x86_64-linux-gnu.so +0 -0
  42. sage/algebras/letterplace/free_algebra_element_letterplace.pxd +18 -0
  43. sage/algebras/letterplace/free_algebra_element_letterplace.pyx +755 -0
  44. sage/algebras/letterplace/free_algebra_letterplace.cpython-314-x86_64-linux-gnu.so +0 -0
  45. sage/algebras/letterplace/free_algebra_letterplace.pxd +35 -0
  46. sage/algebras/letterplace/free_algebra_letterplace.pyx +914 -0
  47. sage/algebras/letterplace/letterplace_ideal.cpython-314-x86_64-linux-gnu.so +0 -0
  48. sage/algebras/letterplace/letterplace_ideal.pyx +408 -0
  49. sage/algebras/quatalg/all.py +2 -0
  50. sage/algebras/quatalg/quaternion_algebra.py +4778 -0
  51. sage/algebras/quatalg/quaternion_algebra_cython.cpython-314-x86_64-linux-gnu.so +0 -0
  52. sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
  53. sage/algebras/quatalg/quaternion_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
  54. sage/algebras/quatalg/quaternion_algebra_element.pxd +29 -0
  55. sage/algebras/quatalg/quaternion_algebra_element.pyx +2176 -0
  56. sage/all__sagemath_singular.py +11 -0
  57. sage/ext_data/all__sagemath_singular.py +1 -0
  58. sage/ext_data/singular/function_field/core.lib +98 -0
  59. sage/interfaces/all__sagemath_singular.py +1 -0
  60. sage/interfaces/singular.py +2835 -0
  61. sage/libs/all__sagemath_singular.py +1 -0
  62. sage/libs/singular/__init__.py +1 -0
  63. sage/libs/singular/decl.pxd +1168 -0
  64. sage/libs/singular/function.cpython-314-x86_64-linux-gnu.so +0 -0
  65. sage/libs/singular/function.pxd +87 -0
  66. sage/libs/singular/function.pyx +1901 -0
  67. sage/libs/singular/function_factory.py +61 -0
  68. sage/libs/singular/groebner_strategy.cpython-314-x86_64-linux-gnu.so +0 -0
  69. sage/libs/singular/groebner_strategy.pxd +22 -0
  70. sage/libs/singular/groebner_strategy.pyx +582 -0
  71. sage/libs/singular/option.cpython-314-x86_64-linux-gnu.so +0 -0
  72. sage/libs/singular/option.pyx +671 -0
  73. sage/libs/singular/polynomial.cpython-314-x86_64-linux-gnu.so +0 -0
  74. sage/libs/singular/polynomial.pxd +39 -0
  75. sage/libs/singular/polynomial.pyx +661 -0
  76. sage/libs/singular/ring.cpython-314-x86_64-linux-gnu.so +0 -0
  77. sage/libs/singular/ring.pxd +58 -0
  78. sage/libs/singular/ring.pyx +893 -0
  79. sage/libs/singular/singular.cpython-314-x86_64-linux-gnu.so +0 -0
  80. sage/libs/singular/singular.pxd +72 -0
  81. sage/libs/singular/singular.pyx +1944 -0
  82. sage/libs/singular/standard_options.py +145 -0
  83. sage/matrix/all__sagemath_singular.py +1 -0
  84. sage/matrix/matrix_mpolynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
  85. sage/matrix/matrix_mpolynomial_dense.pxd +7 -0
  86. sage/matrix/matrix_mpolynomial_dense.pyx +615 -0
  87. sage/rings/all__sagemath_singular.py +1 -0
  88. sage/rings/function_field/all__sagemath_singular.py +1 -0
  89. sage/rings/function_field/derivations_polymod.py +911 -0
  90. sage/rings/function_field/element_polymod.cpython-314-x86_64-linux-gnu.so +0 -0
  91. sage/rings/function_field/element_polymod.pyx +406 -0
  92. sage/rings/function_field/function_field_polymod.py +2611 -0
  93. sage/rings/function_field/ideal_polymod.py +1775 -0
  94. sage/rings/function_field/order_polymod.py +1475 -0
  95. sage/rings/function_field/place_polymod.py +681 -0
  96. sage/rings/polynomial/all__sagemath_singular.py +1 -0
  97. sage/rings/polynomial/multi_polynomial_ideal_libsingular.cpython-314-x86_64-linux-gnu.so +0 -0
  98. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pxd +5 -0
  99. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +339 -0
  100. sage/rings/polynomial/multi_polynomial_libsingular.cpython-314-x86_64-linux-gnu.so +0 -0
  101. sage/rings/polynomial/multi_polynomial_libsingular.pxd +30 -0
  102. sage/rings/polynomial/multi_polynomial_libsingular.pyx +6277 -0
  103. sage/rings/polynomial/plural.cpython-314-x86_64-linux-gnu.so +0 -0
  104. sage/rings/polynomial/plural.pxd +48 -0
  105. sage/rings/polynomial/plural.pyx +3171 -0
  106. sage/symbolic/all__sagemath_singular.py +1 -0
  107. sage/symbolic/comparison_impl.pxi +428 -0
  108. sage/symbolic/constants_c_impl.pxi +178 -0
  109. sage/symbolic/expression.cpython-314-x86_64-linux-gnu.so +0 -0
  110. sage/symbolic/expression.pxd +7 -0
  111. sage/symbolic/expression.pyx +14200 -0
  112. sage/symbolic/getitem_impl.pxi +202 -0
  113. sage/symbolic/pynac.pxi +572 -0
  114. sage/symbolic/pynac_constant_impl.pxi +133 -0
  115. sage/symbolic/pynac_function_impl.pxi +206 -0
  116. sage/symbolic/pynac_impl.pxi +2576 -0
  117. sage/symbolic/pynac_wrap.h +124 -0
  118. sage/symbolic/series_impl.pxi +272 -0
  119. sage/symbolic/substitution_map_impl.pxi +94 -0
  120. sage_wheels/bin/ESingular +0 -0
  121. sage_wheels/bin/Singular +0 -0
  122. sage_wheels/bin/TSingular +0 -0
  123. sage_wheels/lib/singular/MOD/cohomo.la +41 -0
  124. sage_wheels/lib/singular/MOD/cohomo.so +0 -0
  125. sage_wheels/lib/singular/MOD/customstd.la +41 -0
  126. sage_wheels/lib/singular/MOD/customstd.so +0 -0
  127. sage_wheels/lib/singular/MOD/freealgebra.la +41 -0
  128. sage_wheels/lib/singular/MOD/freealgebra.so +0 -0
  129. sage_wheels/lib/singular/MOD/gfanlib.la +41 -0
  130. sage_wheels/lib/singular/MOD/gfanlib.so +0 -0
  131. sage_wheels/lib/singular/MOD/gitfan.la +41 -0
  132. sage_wheels/lib/singular/MOD/gitfan.so +0 -0
  133. sage_wheels/lib/singular/MOD/interval.la +41 -0
  134. sage_wheels/lib/singular/MOD/interval.so +0 -0
  135. sage_wheels/lib/singular/MOD/loctriv.la +41 -0
  136. sage_wheels/lib/singular/MOD/loctriv.so +0 -0
  137. sage_wheels/lib/singular/MOD/machinelearning.la +41 -0
  138. sage_wheels/lib/singular/MOD/machinelearning.so +0 -0
  139. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.la +41 -0
  140. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.so +0 -0
  141. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.la +41 -0
  142. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.so +0 -0
  143. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.la +41 -0
  144. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.so +0 -0
  145. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.la +41 -0
  146. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.so +0 -0
  147. sage_wheels/lib/singular/MOD/partialgb.la +41 -0
  148. sage_wheels/lib/singular/MOD/partialgb.so +0 -0
  149. sage_wheels/lib/singular/MOD/pyobject.la +41 -0
  150. sage_wheels/lib/singular/MOD/pyobject.so +0 -0
  151. sage_wheels/lib/singular/MOD/singmathic.la +41 -0
  152. sage_wheels/lib/singular/MOD/singmathic.so +0 -0
  153. sage_wheels/lib/singular/MOD/sispasm.la +41 -0
  154. sage_wheels/lib/singular/MOD/sispasm.so +0 -0
  155. sage_wheels/lib/singular/MOD/subsets.la +41 -0
  156. sage_wheels/lib/singular/MOD/subsets.so +0 -0
  157. sage_wheels/lib/singular/MOD/systhreads.la +41 -0
  158. sage_wheels/lib/singular/MOD/systhreads.so +0 -0
  159. sage_wheels/lib/singular/MOD/syzextra.la +41 -0
  160. sage_wheels/lib/singular/MOD/syzextra.so +0 -0
  161. sage_wheels/libexec/singular/MOD/change_cost +0 -0
  162. sage_wheels/libexec/singular/MOD/singularsurf +11 -0
  163. sage_wheels/libexec/singular/MOD/singularsurf_jupyter +9 -0
  164. sage_wheels/libexec/singular/MOD/singularsurf_win +10 -0
  165. sage_wheels/libexec/singular/MOD/solve_IP +0 -0
  166. sage_wheels/libexec/singular/MOD/surfex +16 -0
  167. sage_wheels/libexec/singular/MOD/toric_ideal +0 -0
  168. sage_wheels/share/factory/gftables/10201 +342 -0
  169. sage_wheels/share/factory/gftables/1024 +37 -0
  170. sage_wheels/share/factory/gftables/10609 +356 -0
  171. sage_wheels/share/factory/gftables/11449 +384 -0
  172. sage_wheels/share/factory/gftables/11881 +398 -0
  173. sage_wheels/share/factory/gftables/121 +6 -0
  174. sage_wheels/share/factory/gftables/12167 +408 -0
  175. sage_wheels/share/factory/gftables/125 +7 -0
  176. sage_wheels/share/factory/gftables/12769 +428 -0
  177. sage_wheels/share/factory/gftables/128 +7 -0
  178. sage_wheels/share/factory/gftables/1331 +47 -0
  179. sage_wheels/share/factory/gftables/1369 +48 -0
  180. sage_wheels/share/factory/gftables/14641 +490 -0
  181. sage_wheels/share/factory/gftables/15625 +523 -0
  182. sage_wheels/share/factory/gftables/16 +3 -0
  183. sage_wheels/share/factory/gftables/16129 +540 -0
  184. sage_wheels/share/factory/gftables/16384 +549 -0
  185. sage_wheels/share/factory/gftables/16807 +563 -0
  186. sage_wheels/share/factory/gftables/1681 +58 -0
  187. sage_wheels/share/factory/gftables/169 +8 -0
  188. sage_wheels/share/factory/gftables/17161 +574 -0
  189. sage_wheels/share/factory/gftables/1849 +64 -0
  190. sage_wheels/share/factory/gftables/18769 +628 -0
  191. sage_wheels/share/factory/gftables/19321 +646 -0
  192. sage_wheels/share/factory/gftables/19683 +659 -0
  193. sage_wheels/share/factory/gftables/2048 +71 -0
  194. sage_wheels/share/factory/gftables/2187 +75 -0
  195. sage_wheels/share/factory/gftables/2197 +76 -0
  196. sage_wheels/share/factory/gftables/2209 +76 -0
  197. sage_wheels/share/factory/gftables/22201 +742 -0
  198. sage_wheels/share/factory/gftables/22801 +762 -0
  199. sage_wheels/share/factory/gftables/2401 +82 -0
  200. sage_wheels/share/factory/gftables/243 +11 -0
  201. sage_wheels/share/factory/gftables/24389 +815 -0
  202. sage_wheels/share/factory/gftables/24649 +824 -0
  203. sage_wheels/share/factory/gftables/25 +3 -0
  204. sage_wheels/share/factory/gftables/256 +11 -0
  205. sage_wheels/share/factory/gftables/26569 +888 -0
  206. sage_wheels/share/factory/gftables/27 +3 -0
  207. sage_wheels/share/factory/gftables/27889 +932 -0
  208. sage_wheels/share/factory/gftables/2809 +96 -0
  209. sage_wheels/share/factory/gftables/28561 +954 -0
  210. sage_wheels/share/factory/gftables/289 +12 -0
  211. sage_wheels/share/factory/gftables/29791 +995 -0
  212. sage_wheels/share/factory/gftables/29929 +1000 -0
  213. sage_wheels/share/factory/gftables/3125 +107 -0
  214. sage_wheels/share/factory/gftables/32 +4 -0
  215. sage_wheels/share/factory/gftables/32041 +1070 -0
  216. sage_wheels/share/factory/gftables/32761 +1094 -0
  217. sage_wheels/share/factory/gftables/32768 +1095 -0
  218. sage_wheels/share/factory/gftables/343 +14 -0
  219. sage_wheels/share/factory/gftables/3481 +118 -0
  220. sage_wheels/share/factory/gftables/361 +14 -0
  221. sage_wheels/share/factory/gftables/36481 +1218 -0
  222. sage_wheels/share/factory/gftables/3721 +126 -0
  223. sage_wheels/share/factory/gftables/37249 +1244 -0
  224. sage_wheels/share/factory/gftables/38809 +1296 -0
  225. sage_wheels/share/factory/gftables/39601 +1322 -0
  226. sage_wheels/share/factory/gftables/4 +3 -0
  227. sage_wheels/share/factory/gftables/4096 +139 -0
  228. sage_wheels/share/factory/gftables/44521 +1486 -0
  229. sage_wheels/share/factory/gftables/4489 +152 -0
  230. sage_wheels/share/factory/gftables/49 +4 -0
  231. sage_wheels/share/factory/gftables/4913 +166 -0
  232. sage_wheels/share/factory/gftables/49729 +1660 -0
  233. sage_wheels/share/factory/gftables/5041 +170 -0
  234. sage_wheels/share/factory/gftables/50653 +1691 -0
  235. sage_wheels/share/factory/gftables/512 +20 -0
  236. sage_wheels/share/factory/gftables/51529 +1720 -0
  237. sage_wheels/share/factory/gftables/52441 +1750 -0
  238. sage_wheels/share/factory/gftables/529 +20 -0
  239. sage_wheels/share/factory/gftables/5329 +180 -0
  240. sage_wheels/share/factory/gftables/54289 +1812 -0
  241. sage_wheels/share/factory/gftables/57121 +1906 -0
  242. sage_wheels/share/factory/gftables/58081 +1938 -0
  243. sage_wheels/share/factory/gftables/59049 +1971 -0
  244. sage_wheels/share/factory/gftables/6241 +210 -0
  245. sage_wheels/share/factory/gftables/625 +23 -0
  246. sage_wheels/share/factory/gftables/63001 +2102 -0
  247. sage_wheels/share/factory/gftables/64 +5 -0
  248. sage_wheels/share/factory/gftables/6561 +221 -0
  249. sage_wheels/share/factory/gftables/6859 +231 -0
  250. sage_wheels/share/factory/gftables/6889 +232 -0
  251. sage_wheels/share/factory/gftables/729 +27 -0
  252. sage_wheels/share/factory/gftables/7921 +266 -0
  253. sage_wheels/share/factory/gftables/8 +3 -0
  254. sage_wheels/share/factory/gftables/81 +5 -0
  255. sage_wheels/share/factory/gftables/8192 +276 -0
  256. sage_wheels/share/factory/gftables/841 +30 -0
  257. sage_wheels/share/factory/gftables/9 +3 -0
  258. sage_wheels/share/factory/gftables/9409 +316 -0
  259. sage_wheels/share/factory/gftables/961 +34 -0
  260. sage_wheels/share/info/singular.info +191898 -0
  261. sage_wheels/share/singular/LIB/GND.lib +1359 -0
  262. sage_wheels/share/singular/LIB/JMBTest.lib +976 -0
  263. sage_wheels/share/singular/LIB/JMSConst.lib +1363 -0
  264. sage_wheels/share/singular/LIB/KVequiv.lib +699 -0
  265. sage_wheels/share/singular/LIB/SingularityDBM.lib +491 -0
  266. sage_wheels/share/singular/LIB/VecField.lib +1542 -0
  267. sage_wheels/share/singular/LIB/absfact.lib +959 -0
  268. sage_wheels/share/singular/LIB/ainvar.lib +730 -0
  269. sage_wheels/share/singular/LIB/aksaka.lib +419 -0
  270. sage_wheels/share/singular/LIB/alexpoly.lib +2542 -0
  271. sage_wheels/share/singular/LIB/algebra.lib +1193 -0
  272. sage_wheels/share/singular/LIB/all.lib +136 -0
  273. sage_wheels/share/singular/LIB/arcpoint.lib +514 -0
  274. sage_wheels/share/singular/LIB/arnold.lib +4553 -0
  275. sage_wheels/share/singular/LIB/arnoldclassify.lib +2058 -0
  276. sage_wheels/share/singular/LIB/arr.lib +3486 -0
  277. sage_wheels/share/singular/LIB/assprimeszerodim.lib +755 -0
  278. sage_wheels/share/singular/LIB/autgradalg.lib +3361 -0
  279. sage_wheels/share/singular/LIB/bfun.lib +1964 -0
  280. sage_wheels/share/singular/LIB/bimodules.lib +774 -0
  281. sage_wheels/share/singular/LIB/brillnoether.lib +226 -0
  282. sage_wheels/share/singular/LIB/brnoeth.lib +5017 -0
  283. sage_wheels/share/singular/LIB/central.lib +2169 -0
  284. sage_wheels/share/singular/LIB/chern.lib +4162 -0
  285. sage_wheels/share/singular/LIB/cimonom.lib +571 -0
  286. sage_wheels/share/singular/LIB/cisimplicial.lib +1835 -0
  287. sage_wheels/share/singular/LIB/classify.lib +3239 -0
  288. sage_wheels/share/singular/LIB/classify2.lib +1462 -0
  289. sage_wheels/share/singular/LIB/classifyMapGerms.lib +1515 -0
  290. sage_wheels/share/singular/LIB/classify_aeq.lib +3253 -0
  291. sage_wheels/share/singular/LIB/classifyceq.lib +2092 -0
  292. sage_wheels/share/singular/LIB/classifyci.lib +1133 -0
  293. sage_wheels/share/singular/LIB/combinat.lib +91 -0
  294. sage_wheels/share/singular/LIB/compregb.lib +276 -0
  295. sage_wheels/share/singular/LIB/control.lib +1636 -0
  296. sage_wheels/share/singular/LIB/crypto.lib +3795 -0
  297. sage_wheels/share/singular/LIB/curveInv.lib +667 -0
  298. sage_wheels/share/singular/LIB/curvepar.lib +1817 -0
  299. sage_wheels/share/singular/LIB/customstd.lib +100 -0
  300. sage_wheels/share/singular/LIB/deRham.lib +5979 -0
  301. sage_wheels/share/singular/LIB/decodegb.lib +2134 -0
  302. sage_wheels/share/singular/LIB/decomp.lib +1655 -0
  303. sage_wheels/share/singular/LIB/deflation.lib +872 -0
  304. sage_wheels/share/singular/LIB/deform.lib +925 -0
  305. sage_wheels/share/singular/LIB/difform.lib +3055 -0
  306. sage_wheels/share/singular/LIB/divisors.lib +750 -0
  307. sage_wheels/share/singular/LIB/dmod.lib +5817 -0
  308. sage_wheels/share/singular/LIB/dmodapp.lib +3269 -0
  309. sage_wheels/share/singular/LIB/dmodideal.lib +1211 -0
  310. sage_wheels/share/singular/LIB/dmodloc.lib +2645 -0
  311. sage_wheels/share/singular/LIB/dmodvar.lib +818 -0
  312. sage_wheels/share/singular/LIB/dummy.lib +17 -0
  313. sage_wheels/share/singular/LIB/elim.lib +1009 -0
  314. sage_wheels/share/singular/LIB/ellipticcovers.lib +548 -0
  315. sage_wheels/share/singular/LIB/enumpoints.lib +146 -0
  316. sage_wheels/share/singular/LIB/equising.lib +2127 -0
  317. sage_wheels/share/singular/LIB/ffmodstd.lib +2384 -0
  318. sage_wheels/share/singular/LIB/ffsolve.lib +1289 -0
  319. sage_wheels/share/singular/LIB/findifs.lib +778 -0
  320. sage_wheels/share/singular/LIB/finitediff.lib +1768 -0
  321. sage_wheels/share/singular/LIB/finvar.lib +7989 -0
  322. sage_wheels/share/singular/LIB/fpadim.lib +2429 -0
  323. sage_wheels/share/singular/LIB/fpalgebras.lib +1666 -0
  324. sage_wheels/share/singular/LIB/fpaprops.lib +1462 -0
  325. sage_wheels/share/singular/LIB/freegb.lib +3853 -0
  326. sage_wheels/share/singular/LIB/general.lib +1350 -0
  327. sage_wheels/share/singular/LIB/gfan.lib +1768 -0
  328. sage_wheels/share/singular/LIB/gitfan.lib +3130 -0
  329. sage_wheels/share/singular/LIB/gkdim.lib +99 -0
  330. sage_wheels/share/singular/LIB/gmspoly.lib +589 -0
  331. sage_wheels/share/singular/LIB/gmssing.lib +1739 -0
  332. sage_wheels/share/singular/LIB/goettsche.lib +909 -0
  333. sage_wheels/share/singular/LIB/graal.lib +1366 -0
  334. sage_wheels/share/singular/LIB/gradedModules.lib +2541 -0
  335. sage_wheels/share/singular/LIB/graphics.lib +360 -0
  336. sage_wheels/share/singular/LIB/grobcov.lib +7706 -0
  337. sage_wheels/share/singular/LIB/groups.lib +1123 -0
  338. sage_wheels/share/singular/LIB/grwalk.lib +507 -0
  339. sage_wheels/share/singular/LIB/hdepth.lib +194 -0
  340. sage_wheels/share/singular/LIB/help.cnf +57 -0
  341. sage_wheels/share/singular/LIB/hess.lib +1946 -0
  342. sage_wheels/share/singular/LIB/hnoether.lib +4292 -0
  343. sage_wheels/share/singular/LIB/hodge.lib +400 -0
  344. sage_wheels/share/singular/LIB/homolog.lib +1965 -0
  345. sage_wheels/share/singular/LIB/hyperel.lib +975 -0
  346. sage_wheels/share/singular/LIB/inout.lib +679 -0
  347. sage_wheels/share/singular/LIB/integralbasis.lib +6224 -0
  348. sage_wheels/share/singular/LIB/interval.lib +1418 -0
  349. sage_wheels/share/singular/LIB/intprog.lib +778 -0
  350. sage_wheels/share/singular/LIB/invar.lib +443 -0
  351. sage_wheels/share/singular/LIB/involut.lib +980 -0
  352. sage_wheels/share/singular/LIB/jacobson.lib +1215 -0
  353. sage_wheels/share/singular/LIB/kskernel.lib +534 -0
  354. sage_wheels/share/singular/LIB/latex.lib +3146 -0
  355. sage_wheels/share/singular/LIB/lejeune.lib +651 -0
  356. sage_wheels/share/singular/LIB/linalg.lib +2040 -0
  357. sage_wheels/share/singular/LIB/locnormal.lib +212 -0
  358. sage_wheels/share/singular/LIB/lrcalc.lib +526 -0
  359. sage_wheels/share/singular/LIB/makedbm.lib +294 -0
  360. sage_wheels/share/singular/LIB/mathml.lib +813 -0
  361. sage_wheels/share/singular/LIB/matrix.lib +1372 -0
  362. sage_wheels/share/singular/LIB/maxlike.lib +1132 -0
  363. sage_wheels/share/singular/LIB/methods.lib +212 -0
  364. sage_wheels/share/singular/LIB/moddiq.lib +322 -0
  365. sage_wheels/share/singular/LIB/modfinduni.lib +181 -0
  366. sage_wheels/share/singular/LIB/modnormal.lib +218 -0
  367. sage_wheels/share/singular/LIB/modprimdec.lib +1278 -0
  368. sage_wheels/share/singular/LIB/modquotient.lib +269 -0
  369. sage_wheels/share/singular/LIB/modstd.lib +1024 -0
  370. sage_wheels/share/singular/LIB/modular.lib +545 -0
  371. sage_wheels/share/singular/LIB/modules.lib +2561 -0
  372. sage_wheels/share/singular/LIB/modwalk.lib +609 -0
  373. sage_wheels/share/singular/LIB/mondromy.lib +1016 -0
  374. sage_wheels/share/singular/LIB/monomialideal.lib +3851 -0
  375. sage_wheels/share/singular/LIB/mprimdec.lib +2353 -0
  376. sage_wheels/share/singular/LIB/mregular.lib +1863 -0
  377. sage_wheels/share/singular/LIB/multigrading.lib +5629 -0
  378. sage_wheels/share/singular/LIB/ncHilb.lib +777 -0
  379. sage_wheels/share/singular/LIB/ncModslimgb.lib +791 -0
  380. sage_wheels/share/singular/LIB/ncalg.lib +16311 -0
  381. sage_wheels/share/singular/LIB/ncall.lib +31 -0
  382. sage_wheels/share/singular/LIB/ncdecomp.lib +468 -0
  383. sage_wheels/share/singular/LIB/ncfactor.lib +13371 -0
  384. sage_wheels/share/singular/LIB/ncfrac.lib +1023 -0
  385. sage_wheels/share/singular/LIB/nchilbert.lib +448 -0
  386. sage_wheels/share/singular/LIB/nchomolog.lib +759 -0
  387. sage_wheels/share/singular/LIB/ncloc.lib +361 -0
  388. sage_wheels/share/singular/LIB/ncpreim.lib +795 -0
  389. sage_wheels/share/singular/LIB/ncrat.lib +2849 -0
  390. sage_wheels/share/singular/LIB/nctools.lib +1887 -0
  391. sage_wheels/share/singular/LIB/nets.lib +1456 -0
  392. sage_wheels/share/singular/LIB/nfmodstd.lib +1000 -0
  393. sage_wheels/share/singular/LIB/nfmodsyz.lib +732 -0
  394. sage_wheels/share/singular/LIB/noether.lib +1106 -0
  395. sage_wheels/share/singular/LIB/normal.lib +8700 -0
  396. sage_wheels/share/singular/LIB/normaliz.lib +2226 -0
  397. sage_wheels/share/singular/LIB/ntsolve.lib +362 -0
  398. sage_wheels/share/singular/LIB/numerAlg.lib +560 -0
  399. sage_wheels/share/singular/LIB/numerDecom.lib +2261 -0
  400. sage_wheels/share/singular/LIB/olga.lib +1933 -0
  401. sage_wheels/share/singular/LIB/orbitparam.lib +351 -0
  402. sage_wheels/share/singular/LIB/parallel.lib +319 -0
  403. sage_wheels/share/singular/LIB/paraplanecurves.lib +3110 -0
  404. sage_wheels/share/singular/LIB/perron.lib +202 -0
  405. sage_wheels/share/singular/LIB/pfd.lib +2223 -0
  406. sage_wheels/share/singular/LIB/phindex.lib +642 -0
  407. sage_wheels/share/singular/LIB/pointid.lib +673 -0
  408. sage_wheels/share/singular/LIB/polybori.lib +1430 -0
  409. sage_wheels/share/singular/LIB/polyclass.lib +525 -0
  410. sage_wheels/share/singular/LIB/polylib.lib +1174 -0
  411. sage_wheels/share/singular/LIB/polymake.lib +1902 -0
  412. sage_wheels/share/singular/LIB/presolve.lib +1533 -0
  413. sage_wheels/share/singular/LIB/primdec.lib +9576 -0
  414. sage_wheels/share/singular/LIB/primdecint.lib +1782 -0
  415. sage_wheels/share/singular/LIB/primitiv.lib +401 -0
  416. sage_wheels/share/singular/LIB/puiseuxexpansions.lib +1631 -0
  417. sage_wheels/share/singular/LIB/purityfiltration.lib +960 -0
  418. sage_wheels/share/singular/LIB/qhmoduli.lib +1561 -0
  419. sage_wheels/share/singular/LIB/qmatrix.lib +293 -0
  420. sage_wheels/share/singular/LIB/random.lib +455 -0
  421. sage_wheels/share/singular/LIB/ratgb.lib +489 -0
  422. sage_wheels/share/singular/LIB/realclassify.lib +5759 -0
  423. sage_wheels/share/singular/LIB/realizationMatroids.lib +772 -0
  424. sage_wheels/share/singular/LIB/realrad.lib +1197 -0
  425. sage_wheels/share/singular/LIB/recover.lib +2628 -0
  426. sage_wheels/share/singular/LIB/redcgs.lib +3984 -0
  427. sage_wheels/share/singular/LIB/reesclos.lib +465 -0
  428. sage_wheels/share/singular/LIB/resbinomial.lib +2802 -0
  429. sage_wheels/share/singular/LIB/resgraph.lib +789 -0
  430. sage_wheels/share/singular/LIB/resjung.lib +820 -0
  431. sage_wheels/share/singular/LIB/resolve.lib +5110 -0
  432. sage_wheels/share/singular/LIB/resources.lib +170 -0
  433. sage_wheels/share/singular/LIB/reszeta.lib +5473 -0
  434. sage_wheels/share/singular/LIB/ring.lib +1328 -0
  435. sage_wheels/share/singular/LIB/ringgb.lib +343 -0
  436. sage_wheels/share/singular/LIB/rinvar.lib +1153 -0
  437. sage_wheels/share/singular/LIB/rootisolation.lib +1481 -0
  438. sage_wheels/share/singular/LIB/rootsmr.lib +709 -0
  439. sage_wheels/share/singular/LIB/rootsur.lib +886 -0
  440. sage_wheels/share/singular/LIB/rstandard.lib +607 -0
  441. sage_wheels/share/singular/LIB/rwalk.lib +336 -0
  442. sage_wheels/share/singular/LIB/sagbi.lib +1353 -0
  443. sage_wheels/share/singular/LIB/sagbiNormaliz.lib +1622 -0
  444. sage_wheels/share/singular/LIB/sagbiNormaliz0.lib +1498 -0
  445. sage_wheels/share/singular/LIB/sagbigrob.lib +449 -0
  446. sage_wheels/share/singular/LIB/schreyer.lib +321 -0
  447. sage_wheels/share/singular/LIB/schubert.lib +2551 -0
  448. sage_wheels/share/singular/LIB/sets.lib +524 -0
  449. sage_wheels/share/singular/LIB/sheafcoh.lib +1663 -0
  450. sage_wheels/share/singular/LIB/signcond.lib +437 -0
  451. sage_wheels/share/singular/LIB/sing.lib +1094 -0
  452. sage_wheels/share/singular/LIB/sing4ti2.lib +419 -0
  453. sage_wheels/share/singular/LIB/solve.lib +2243 -0
  454. sage_wheels/share/singular/LIB/spcurve.lib +1077 -0
  455. sage_wheels/share/singular/LIB/spectrum.lib +62 -0
  456. sage_wheels/share/singular/LIB/sresext.lib +757 -0
  457. sage_wheels/share/singular/LIB/ssi.lib +143 -0
  458. sage_wheels/share/singular/LIB/standard.lib +2769 -0
  459. sage_wheels/share/singular/LIB/stanleyreisner.lib +473 -0
  460. sage_wheels/share/singular/LIB/stdmodule.lib +547 -0
  461. sage_wheels/share/singular/LIB/stratify.lib +1070 -0
  462. sage_wheels/share/singular/LIB/surf.lib +506 -0
  463. sage_wheels/share/singular/LIB/surf_jupyter.lib +223 -0
  464. sage_wheels/share/singular/LIB/surfacesignature.lib +522 -0
  465. sage_wheels/share/singular/LIB/surfex.lib +1462 -0
  466. sage_wheels/share/singular/LIB/swalk.lib +877 -0
  467. sage_wheels/share/singular/LIB/symodstd.lib +1570 -0
  468. sage_wheels/share/singular/LIB/systhreads.lib +74 -0
  469. sage_wheels/share/singular/LIB/tasks.lib +1324 -0
  470. sage_wheels/share/singular/LIB/tateProdCplxNegGrad.lib +2412 -0
  471. sage_wheels/share/singular/LIB/teachstd.lib +858 -0
  472. sage_wheels/share/singular/LIB/template.lib +116 -0
  473. sage_wheels/share/singular/LIB/toric.lib +1119 -0
  474. sage_wheels/share/singular/LIB/transformation.lib +116 -0
  475. sage_wheels/share/singular/LIB/triang.lib +1197 -0
  476. sage_wheels/share/singular/LIB/tropical.lib +8741 -0
  477. sage_wheels/share/singular/LIB/tropicalEllipticCovers.lib +2922 -0
  478. sage_wheels/share/singular/LIB/tropicalNewton.lib +1128 -0
  479. sage_wheels/share/singular/LIB/tst.lib +1108 -0
  480. sage_wheels/share/singular/LIB/weierstr.lib +241 -0
  481. sage_wheels/share/singular/LIB/zeroset.lib +1478 -0
  482. sage_wheels/share/singular/emacs/.emacs-general +184 -0
  483. sage_wheels/share/singular/emacs/.emacs-singular +234 -0
  484. sage_wheels/share/singular/emacs/COPYING +44 -0
  485. sage_wheels/share/singular/emacs/cmd-cmpl.el +241 -0
  486. sage_wheels/share/singular/emacs/ex-cmpl.el +1681 -0
  487. sage_wheels/share/singular/emacs/hlp-cmpl.el +4318 -0
  488. sage_wheels/share/singular/emacs/lib-cmpl.el +179 -0
  489. sage_wheels/share/singular/emacs/singular.el +4273 -0
  490. sage_wheels/share/singular/emacs/singular.xpm +39 -0
  491. sage_wheels/share/singular/singular.idx +5002 -0
@@ -0,0 +1,2611 @@
1
+ # sage_setup: distribution = sagemath-singular
2
+ # sage.doctest: needs sage.rings.function_field
3
+ r"""
4
+ Function Fields: extension
5
+ """
6
+
7
+ # *****************************************************************************
8
+ # Copyright (C) 2010 William Stein <wstein@gmail.com>
9
+ # 2010 Robert Bradshaw <robertwb@math.washington.edu>
10
+ # 2011-2018 Julian Rüth <julian.rueth@gmail.com>
11
+ # 2011 Maarten Derickx <m.derickx.student@gmail.com>
12
+ # 2011 Syed Ahmad Lavasani
13
+ # 2013-2014 Simon King
14
+ # 2017 Dean Bisogno
15
+ # 2017 Alyson Deines
16
+ # 2017-2019 David Roe
17
+ # 2017-2022 Kwankyu Lee
18
+ # 2018 Marc Mezzarobba
19
+ # 2018 Wilfried Luebbe
20
+ # 2019 Brent Baccala
21
+ # 2022 Frédéric Chapoton
22
+ # 2022 Gonzalo Tornaría
23
+ #
24
+ # Distributed under the terms of the GNU General Public License (GPL)
25
+ # as published by the Free Software Foundation; either version 2 of
26
+ # the License, or (at your option) any later version.
27
+ # http://www.gnu.org/licenses/
28
+ # *****************************************************************************
29
+
30
+ from sage.arith.functions import lcm
31
+ from sage.misc.cachefunc import cached_method
32
+ from sage.misc.lazy_import import LazyImport
33
+ from sage.rings.qqbar_decorators import handle_AA_and_QQbar
34
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
35
+ from sage.rings.integer import Integer
36
+ from sage.categories.homset import Hom
37
+ from sage.categories.function_fields import FunctionFields
38
+ from sage.categories.number_fields import NumberFields
39
+
40
+ from .element import FunctionFieldElement
41
+ from .element_polymod import FunctionFieldElement_polymod
42
+ from .function_field import FunctionField
43
+ from .function_field_rational import RationalFunctionField
44
+
45
+
46
+ class FunctionField_polymod(FunctionField):
47
+ """
48
+ Function fields defined by a univariate polynomial, as an extension of the
49
+ base field.
50
+
51
+ INPUT:
52
+
53
+ - ``polynomial`` -- univariate polynomial over a function field
54
+
55
+ - ``names`` -- tuple of length 1 or string; variable names
56
+
57
+ - ``category`` -- category (default: category of function fields)
58
+
59
+ EXAMPLES:
60
+
61
+ We make a function field defined by a degree 5 polynomial over the
62
+ rational function field over the rational numbers::
63
+
64
+ sage: K.<x> = FunctionField(QQ)
65
+ sage: R.<y> = K[]
66
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
67
+ Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
68
+
69
+ We next make a function field over the above nontrivial function
70
+ field L::
71
+
72
+ sage: S.<z> = L[]
73
+ sage: M.<z> = L.extension(z^2 + y*z + y); M
74
+ Function field in z defined by z^2 + y*z + y
75
+ sage: 1/z
76
+ ((-x/(x^4 + 1))*y^4 + 2*x^2/(x^4 + 1))*z - 1
77
+ sage: z * (1/z)
78
+ 1
79
+
80
+ We drill down the tower of function fields::
81
+
82
+ sage: M.base_field()
83
+ Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
84
+ sage: M.base_field().base_field()
85
+ Rational function field in x over Rational Field
86
+ sage: M.base_field().base_field().constant_field()
87
+ Rational Field
88
+ sage: M.constant_base_field()
89
+ Rational Field
90
+
91
+ .. WARNING::
92
+
93
+ It is not checked if the polynomial used to define the function field is irreducible
94
+ Hence it is not guaranteed that this object really is a field!
95
+ This is illustrated below.
96
+
97
+ ::
98
+
99
+ sage: K.<x> = FunctionField(QQ)
100
+ sage: R.<y> = K[]
101
+ sage: L.<y> = K.extension(x^2 - y^2)
102
+ sage: (y - x)*(y + x)
103
+ 0
104
+ sage: 1/(y - x)
105
+ 1
106
+ sage: y - x == 0; y + x == 0
107
+ False
108
+ False
109
+ """
110
+ Element = FunctionFieldElement_polymod
111
+
112
+ def __init__(self, polynomial, names, category=None):
113
+ """
114
+ Create a function field defined as an extension of another function
115
+ field by adjoining a root of a univariate polynomial.
116
+
117
+ EXAMPLES:
118
+
119
+ We create an extension of a function field::
120
+
121
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
122
+ sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L
123
+ Function field in y defined by y^5 + x*y - x^3 - 3*x
124
+ sage: TestSuite(L).run(max_runs=512) # long time (15s)
125
+
126
+ We can set the variable name, which doesn't have to be y::
127
+
128
+ sage: L.<w> = K.extension(y^5 - x^3 - 3*x + x*y); L
129
+ Function field in w defined by w^5 + x*w - x^3 - 3*x
130
+
131
+ TESTS:
132
+
133
+ Test that :issue:`17033` is fixed::
134
+
135
+ sage: K.<t> = FunctionField(QQ)
136
+ sage: R.<x> = QQ[]
137
+ sage: M.<z> = K.extension(x^7 - x - t)
138
+ sage: M(x)
139
+ z
140
+ sage: M('z')
141
+ z
142
+ sage: M('x')
143
+ Traceback (most recent call last):
144
+ ...
145
+ TypeError: unable to evaluate 'x' in Fraction Field of Univariate
146
+ Polynomial Ring in t over Rational Field
147
+ """
148
+ from sage.rings.polynomial.polynomial_element import Polynomial
149
+ if polynomial.parent().ngens() > 1 or not isinstance(polynomial, Polynomial):
150
+ raise TypeError("polynomial must be univariate a polynomial")
151
+ if names is None:
152
+ names = (polynomial.variable_name(), )
153
+ elif names != polynomial.variable_name():
154
+ polynomial = polynomial.change_variable_name(names)
155
+ if polynomial.degree() <= 0:
156
+ raise ValueError("polynomial must have positive degree")
157
+ base_field = polynomial.base_ring()
158
+ if not isinstance(base_field, FunctionField):
159
+ raise TypeError("polynomial must be over a FunctionField")
160
+
161
+ self._base_field = base_field
162
+ self._polynomial = polynomial
163
+
164
+ FunctionField.__init__(self, base_field, names=names,
165
+ category=FunctionFields().or_subcategory(category))
166
+
167
+ from .place_polymod import FunctionFieldPlace_polymod
168
+ self._place_class = FunctionFieldPlace_polymod
169
+
170
+ self._hash = hash(polynomial)
171
+ self._ring = self._polynomial.parent()
172
+
173
+ self._populate_coercion_lists_(coerce_list=[base_field, self._ring])
174
+ self._gen = self(self._ring.gen())
175
+
176
+ def __hash__(self):
177
+ """
178
+ Return hash of the function field.
179
+
180
+ The hash value is equal to the hash of the defining polynomial.
181
+
182
+ EXAMPLES::
183
+
184
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
185
+ sage: L = K.extension(y^5 - x^3 - 3*x + x*y)
186
+ sage: hash(L) == hash(L.polynomial())
187
+ True
188
+ """
189
+ return self._hash
190
+
191
+ def _element_constructor_(self, x):
192
+ r"""
193
+ Make ``x`` into an element of the function field, possibly not canonically.
194
+
195
+ INPUT:
196
+
197
+ - ``x`` -- element
198
+
199
+ TESTS::
200
+
201
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
202
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
203
+ sage: L._element_constructor_(L.polynomial_ring().gen())
204
+ y
205
+ """
206
+ if isinstance(x, FunctionFieldElement):
207
+ return self.element_class(self, self._ring(x.element()))
208
+ return self.element_class(self, self._ring(x))
209
+
210
+ def gen(self, n=0):
211
+ """
212
+ Return the `n`-th generator of the function field. By default, `n` is 0; any other
213
+ value of `n` leads to an error. The generator is the class of `y`, if we view
214
+ the function field as being presented as `K[y]/(f(y))`.
215
+
216
+ EXAMPLES::
217
+
218
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
219
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
220
+ sage: L.gen()
221
+ y
222
+ sage: L.gen(1)
223
+ Traceback (most recent call last):
224
+ ...
225
+ IndexError: there is only one generator
226
+ """
227
+ if n != 0:
228
+ raise IndexError("there is only one generator")
229
+ return self._gen
230
+
231
+ def ngens(self):
232
+ """
233
+ Return the number of generators of the function field over its base
234
+ field. This is by definition 1.
235
+
236
+ EXAMPLES::
237
+
238
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
239
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
240
+ sage: L.ngens()
241
+ 1
242
+ """
243
+ return 1
244
+
245
+ def _to_base_field(self, f):
246
+ r"""
247
+ Return ``f`` as an element of the :meth:`base_field`.
248
+
249
+ INPUT:
250
+
251
+ - ``f`` -- element of the function field which lies in the base field
252
+
253
+ EXAMPLES::
254
+
255
+ sage: K.<x> = FunctionField(QQ)
256
+ sage: R.<y> = K[]
257
+ sage: L.<y> = K.extension(y^2 - x)
258
+ sage: L._to_base_field(L(x))
259
+ x
260
+ sage: L._to_base_field(y)
261
+ Traceback (most recent call last):
262
+ ...
263
+ ValueError: y is not an element of the base field
264
+
265
+ TESTS:
266
+
267
+ Verify that :issue:`21872` has been resolved::
268
+
269
+ sage: R.<z> = L[]
270
+ sage: M.<z> = L.extension(z^2 - y)
271
+
272
+ sage: M(1) in QQ
273
+ True
274
+ sage: M(y) in L
275
+ True
276
+ sage: M(x) in K
277
+ True
278
+ sage: z in K
279
+ False
280
+ """
281
+ K = self.base_field()
282
+ if f.element().is_constant():
283
+ return K(f.element())
284
+ raise ValueError("%r is not an element of the base field" % (f,))
285
+
286
+ def _to_constant_base_field(self, f):
287
+ """
288
+ Return ``f`` as an element of the :meth:`constant_base_field`.
289
+
290
+ INPUT:
291
+
292
+ - ``f`` -- element of the rational function field which is a
293
+ constant
294
+
295
+ EXAMPLES::
296
+
297
+ sage: K.<x> = FunctionField(QQ)
298
+ sage: R.<y> = K[]
299
+ sage: L.<y> = K.extension(y^2 - x)
300
+ sage: L._to_constant_base_field(L(1))
301
+ 1
302
+ sage: L._to_constant_base_field(y)
303
+ Traceback (most recent call last):
304
+ ...
305
+ ValueError: y is not an element of the base field
306
+
307
+ TESTS:
308
+
309
+ Verify that :issue:`21872` has been resolved::
310
+
311
+ sage: L(1) in QQ
312
+ True
313
+ sage: y in QQ
314
+ False
315
+ """
316
+ return self.base_field()._to_constant_base_field(self._to_base_field(f))
317
+
318
+ def monic_integral_model(self, names=None):
319
+ """
320
+ Return a function field isomorphic to this field but which is an
321
+ extension of a rational function field with defining polynomial that is
322
+ monic and integral over the constant base field.
323
+
324
+ INPUT:
325
+
326
+ - ``names`` -- string or tuple of up to two strings (default:
327
+ ``None``); the name of the generator of the field, and the name of
328
+ the generator of the underlying rational function field (if a tuple).
329
+ If not given, then the names are chosen automatically.
330
+
331
+ OUTPUT:
332
+
333
+ A triple ``(F,f,t)`` where ``F`` is a function field, ``f`` is an
334
+ isomorphism from ``F`` to this field, and ``t`` is the inverse of
335
+ ``f``.
336
+
337
+ EXAMPLES::
338
+
339
+ sage: K.<x> = FunctionField(QQ)
340
+ sage: R.<y> = K[]
341
+ sage: L.<y> = K.extension(x^2*y^5 - 1/x); L
342
+ Function field in y defined by x^2*y^5 - 1/x
343
+ sage: A, from_A, to_A = L.monic_integral_model('z')
344
+ sage: A
345
+ Function field in z defined by z^5 - x^12
346
+ sage: from_A
347
+ Function Field morphism:
348
+ From: Function field in z defined by z^5 - x^12
349
+ To: Function field in y defined by x^2*y^5 - 1/x
350
+ Defn: z |--> x^3*y
351
+ x |--> x
352
+ sage: to_A
353
+ Function Field morphism:
354
+ From: Function field in y defined by x^2*y^5 - 1/x
355
+ To: Function field in z defined by z^5 - x^12
356
+ Defn: y |--> 1/x^3*z
357
+ x |--> x
358
+ sage: to_A(y)
359
+ 1/x^3*z
360
+ sage: from_A(to_A(y))
361
+ y
362
+ sage: from_A(to_A(1/y))
363
+ x^3*y^4
364
+ sage: from_A(to_A(1/y)) == 1/y
365
+ True
366
+
367
+ This also works for towers of function fields::
368
+
369
+ sage: R.<z> = L[]
370
+ sage: M.<z> = L.extension(z^2*y - 1/x)
371
+ sage: M.monic_integral_model()
372
+ (Function field in z_ defined by z_^10 - x^18,
373
+ Function Field morphism:
374
+ From: Function field in z_ defined by z_^10 - x^18
375
+ To: Function field in z defined by y*z^2 - 1/x
376
+ Defn: z_ |--> x^2*z
377
+ x |--> x, Function Field morphism:
378
+ From: Function field in z defined by y*z^2 - 1/x
379
+ To: Function field in z_ defined by z_^10 - x^18
380
+ Defn: z |--> 1/x^2*z_
381
+ y |--> 1/x^15*z_^8
382
+ x |--> x)
383
+
384
+ TESTS:
385
+
386
+ If the field is already a monic integral extension, then it is returned
387
+ unchanged::
388
+
389
+ sage: K.<x> = FunctionField(QQ)
390
+ sage: R.<y> = K[]
391
+ sage: L.<y> = K.extension(y^2 - x)
392
+ sage: L.monic_integral_model()
393
+ (Function field in y defined by y^2 - x,
394
+ Function Field endomorphism of Function field in y defined by y^2 - x
395
+ Defn: y |--> y
396
+ x |--> x, Function Field endomorphism of Function field in y defined by y^2 - x
397
+ Defn: y |--> y
398
+ x |--> x)
399
+
400
+ unless ``names`` does not match with the current names::
401
+
402
+ sage: L.monic_integral_model(names=('yy','xx'))
403
+ (Function field in yy defined by yy^2 - xx,
404
+ Function Field morphism:
405
+ From: Function field in yy defined by yy^2 - xx
406
+ To: Function field in y defined by y^2 - x
407
+ Defn: yy |--> y
408
+ xx |--> x, Function Field morphism:
409
+ From: Function field in y defined by y^2 - x
410
+ To: Function field in yy defined by yy^2 - xx
411
+ Defn: y |--> yy
412
+ x |--> xx)
413
+ """
414
+ if names:
415
+ if not isinstance(names, tuple):
416
+ names = (names,)
417
+ if len(names) > 2:
418
+ raise ValueError("names must contain at most 2 entries")
419
+
420
+ if self.base_field() is not self.rational_function_field():
421
+ L, from_L, to_L = self.simple_model()
422
+ ret, ret_to_L, L_to_ret = L.monic_integral_model(names)
423
+ from_ret = ret.hom([from_L(ret_to_L(ret.gen())),
424
+ from_L(ret_to_L(ret.base_field().gen()))])
425
+ to_ret = self.hom([L_to_ret(to_L(k.gen())) for k in self._intermediate_fields(self.rational_function_field())])
426
+ return ret, from_ret, to_ret
427
+ else:
428
+ if self.polynomial().is_monic() and all(c.denominator().is_one() for c in self.polynomial()):
429
+ # self is already monic and integral
430
+ if names is None or names == ():
431
+ names = (self.variable_name(),)
432
+ return self.change_variable_name(names)
433
+ else:
434
+ if not names:
435
+ names = (self.variable_name() + "_",)
436
+ if len(names) == 1:
437
+ names = (names[0], self.rational_function_field().variable_name())
438
+
439
+ g, d = self._make_monic_integral(self.polynomial())
440
+ K, from_K, to_K = self.base_field().change_variable_name(names[1])
441
+ g = g.map_coefficients(to_K)
442
+ ret = K.extension(g, names=names[0])
443
+ from_ret = ret.hom([self.gen() * d, self.base_field().gen()])
444
+ to_ret = self.hom([ret.gen() / d, ret.base_field().gen()])
445
+ return ret, from_ret, to_ret
446
+
447
+ def _make_monic_integral(self, f):
448
+ """
449
+ Return a monic integral polynomial `g` and an element `d` of the base
450
+ field such that `g(y*d)=0` where `y` is a root of `f`.
451
+
452
+ INPUT:
453
+
454
+ - ``f`` -- polynomial
455
+
456
+ EXAMPLES::
457
+
458
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
459
+ sage: L.<y> = K.extension(x^2*y^5 - 1/x)
460
+ sage: g, d = L._make_monic_integral(L.polynomial()); g,d
461
+ (y^5 - x^12, x^3)
462
+ sage: (y*d).is_integral()
463
+ True
464
+ sage: g.is_monic()
465
+ True
466
+ sage: g(y*d)
467
+ 0
468
+ """
469
+ R = f.base_ring()
470
+ if not isinstance(R, RationalFunctionField):
471
+ raise NotImplementedError
472
+
473
+ # make f monic
474
+ n = f.degree()
475
+ c = f.leading_coefficient()
476
+ if c != 1:
477
+ f = f / c
478
+
479
+ # find lcm of denominators
480
+ # would be good to replace this by minimal...
481
+ d = lcm([b.denominator() for b in f.list() if b])
482
+ if d != 1:
483
+ x = f.parent().gen()
484
+ g = (d**n) * f(x/d)
485
+ else:
486
+ g = f
487
+ return g, d
488
+
489
+ def constant_field(self):
490
+ """
491
+ Return the algebraic closure of the constant field of the function field.
492
+
493
+ EXAMPLES::
494
+
495
+ sage: K.<x> = FunctionField(GF(5)); _.<Y> = K[] # needs sage.rings.finite_rings
496
+ sage: L.<y> = K.extension(Y^5 - x) # needs sage.rings.finite_rings
497
+ sage: L.constant_field() # needs sage.rings.finite_rings
498
+ Traceback (most recent call last):
499
+ ...
500
+ NotImplementedError
501
+ """
502
+ raise NotImplementedError
503
+
504
+ def constant_base_field(self):
505
+ """
506
+ Return the base constant field of the function field.
507
+
508
+ EXAMPLES::
509
+
510
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
511
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
512
+ Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
513
+ sage: L.constant_base_field()
514
+ Rational Field
515
+ sage: S.<z> = L[]
516
+ sage: M.<z> = L.extension(z^2 - y)
517
+ sage: M.constant_base_field()
518
+ Rational Field
519
+ """
520
+ return self.base_field().constant_base_field()
521
+
522
+ @cached_method(key=lambda self, base: self.base_field() if base is None else base)
523
+ def degree(self, base=None):
524
+ """
525
+ Return the degree of the function field over the function field ``base``.
526
+
527
+ INPUT:
528
+
529
+ - ``base`` -- a function field (default: ``None``), a function field
530
+ from which this field has been constructed as a finite extension
531
+
532
+ EXAMPLES::
533
+
534
+ sage: K.<x> = FunctionField(QQ)
535
+ sage: R.<y> = K[]
536
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
537
+ Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
538
+ sage: L.degree()
539
+ 5
540
+ sage: L.degree(L)
541
+ 1
542
+
543
+ sage: R.<z> = L[]
544
+ sage: M.<z> = L.extension(z^2 - y)
545
+ sage: M.degree(L)
546
+ 2
547
+ sage: M.degree(K)
548
+ 10
549
+
550
+ TESTS::
551
+
552
+ sage: L.degree(M)
553
+ Traceback (most recent call last):
554
+ ...
555
+ ValueError: base must be the rational function field itself
556
+ """
557
+ if base is None:
558
+ base = self.base_field()
559
+ if base is self:
560
+ from sage.rings.integer_ring import ZZ
561
+ return ZZ(1)
562
+ return self._polynomial.degree() * self.base_field().degree(base)
563
+
564
+ def _repr_(self):
565
+ """
566
+ Return the string representation of the function field.
567
+
568
+ EXAMPLES::
569
+
570
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
571
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
572
+ sage: L._repr_()
573
+ 'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x'
574
+ """
575
+ return f"Function field in {self.variable_name()} defined by {self._polynomial}"
576
+
577
+ def _latex_(self):
578
+ r"""
579
+ Return the LaTeX representation of the function field.
580
+
581
+ EXAMPLES::
582
+
583
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
584
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
585
+ sage: latex(L)
586
+ \text{Function field in } y \text{ defined by } y^{5} - 2 x y + \frac{-x^{4} - 1}{x}
587
+ """
588
+ return (fr"\text{{Function field in }} {self.variable_name()} "
589
+ fr"\text{{ defined by }} {self._polynomial._latex_()}")
590
+
591
+ def base_field(self):
592
+ """
593
+ Return the base field of the function field. This function field is
594
+ presented as `L = K[y]/(f(y))`, and the base field is by definition the
595
+ field `K`.
596
+
597
+ EXAMPLES::
598
+
599
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
600
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
601
+ sage: L.base_field()
602
+ Rational function field in x over Rational Field
603
+ """
604
+ return self._base_field
605
+
606
+ def random_element(self, *args, **kwds):
607
+ """
608
+ Create a random element of the function field. Parameters are passed
609
+ onto the random_element method of the base_field.
610
+
611
+ EXAMPLES::
612
+
613
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
614
+ sage: L.<y> = K.extension(y^2 - (x^2 + x))
615
+ sage: L.random_element() # random
616
+ ((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*y^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*y
617
+ + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95)
618
+ """
619
+ return self(self._ring.random_element(degree=self.degree(), *args, **kwds))
620
+
621
+ def polynomial(self):
622
+ """
623
+ Return the univariate polynomial that defines the function field, that
624
+ is, the polynomial `f(y)` so that the function field is of the form
625
+ `K[y]/(f(y))`.
626
+
627
+ EXAMPLES::
628
+
629
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
630
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
631
+ sage: L.polynomial()
632
+ y^5 - 2*x*y + (-x^4 - 1)/x
633
+ """
634
+ return self._polynomial
635
+
636
+ def is_separable(self, base=None):
637
+ r"""
638
+ Return whether this is a separable extension of ``base``.
639
+
640
+ INPUT:
641
+
642
+ - ``base`` -- a function field from which this field has been created
643
+ as an extension or ``None`` (default: ``None``); if ``None``, then
644
+ return whether this is a separable extension over its base field.
645
+
646
+ EXAMPLES::
647
+
648
+ sage: # needs sage.rings.finite_rings
649
+ sage: K.<x> = FunctionField(GF(2))
650
+ sage: R.<y> = K[]
651
+ sage: L.<y> = K.extension(y^2 - x)
652
+ sage: L.is_separable()
653
+ False
654
+ sage: R.<z> = L[]
655
+ sage: M.<z> = L.extension(z^3 - y)
656
+ sage: M.is_separable()
657
+ True
658
+ sage: M.is_separable(K)
659
+ False
660
+
661
+ sage: # needs sage.rings.finite_rings
662
+ sage: K.<x> = FunctionField(GF(5))
663
+ sage: R.<y> = K[]
664
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
665
+ sage: L.is_separable()
666
+ True
667
+
668
+ sage: # needs sage.rings.finite_rings
669
+ sage: K.<x> = FunctionField(GF(5))
670
+ sage: R.<y> = K[]
671
+ sage: L.<y> = K.extension(y^5 - 1)
672
+ sage: L.is_separable()
673
+ False
674
+ """
675
+ if base is None:
676
+ base = self.base_field()
677
+ for k in self._intermediate_fields(base)[:-1]:
678
+ f = k.polynomial()
679
+ g = f.derivative()
680
+ if f.gcd(g).degree() != 0:
681
+ return False
682
+ return True
683
+
684
+ def polynomial_ring(self):
685
+ """
686
+ Return the polynomial ring used to represent elements of the
687
+ function field. If we view the function field as being presented
688
+ as `K[y]/(f(y))`, then this function returns the ring `K[y]`.
689
+
690
+ EXAMPLES::
691
+
692
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
693
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
694
+ sage: L.polynomial_ring()
695
+ Univariate Polynomial Ring in y over Rational function field in x over Rational Field
696
+ """
697
+ return self._ring
698
+
699
+ @cached_method(key=lambda self, base, basis, map: (self.base_field() if base is None else base, basis, map))
700
+ def free_module(self, base=None, basis=None, map=True):
701
+ """
702
+ Return a vector space and isomorphisms from the field to and from the
703
+ vector space.
704
+
705
+ This function allows us to identify the elements of this field with
706
+ elements of a vector space over the base field, which is useful for
707
+ representation and arithmetic with orders, ideals, etc.
708
+
709
+ INPUT:
710
+
711
+ - ``base`` -- a function field (default: ``None``), the returned vector
712
+ space is over this subfield `R`, which defaults to the base field of this
713
+ function field.
714
+
715
+ - ``basis`` -- a basis for this field over the base
716
+
717
+ - ``maps`` -- boolean (default: ``True``); whether to return
718
+ `R`-linear maps to and from `V`
719
+
720
+ OUTPUT:
721
+
722
+ - a vector space over the base function field
723
+
724
+ - an isomorphism from the vector space to the field (if requested)
725
+
726
+ - an isomorphism from the field to the vector space (if requested)
727
+
728
+ EXAMPLES:
729
+
730
+ We define a function field::
731
+
732
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
733
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
734
+ Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
735
+
736
+ We get the vector spaces, and maps back and forth::
737
+
738
+ sage: # needs sage.modules
739
+ sage: V, from_V, to_V = L.free_module()
740
+ sage: V
741
+ Vector space of dimension 5 over Rational function field in x over Rational Field
742
+ sage: from_V
743
+ Isomorphism:
744
+ From: Vector space of dimension 5 over Rational function field in x over Rational Field
745
+ To: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
746
+ sage: to_V
747
+ Isomorphism:
748
+ From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
749
+ To: Vector space of dimension 5 over Rational function field in x over Rational Field
750
+
751
+ We convert an element of the vector space back to the function field::
752
+
753
+ sage: from_V(V.1) # needs sage.modules
754
+ y
755
+
756
+ We define an interesting element of the function field::
757
+
758
+ sage: a = 1/L.0; a # needs sage.modules
759
+ (x/(x^4 + 1))*y^4 - 2*x^2/(x^4 + 1)
760
+
761
+ We convert it to the vector space, and get a vector over the base field::
762
+
763
+ sage: to_V(a) # needs sage.modules
764
+ (-2*x^2/(x^4 + 1), 0, 0, 0, x/(x^4 + 1))
765
+
766
+ We convert to and back, and get the same element::
767
+
768
+ sage: from_V(to_V(a)) == a # needs sage.modules
769
+ True
770
+
771
+ In the other direction::
772
+
773
+ sage: v = x*V.0 + (1/x)*V.1 # needs sage.modules
774
+ sage: to_V(from_V(v)) == v # needs sage.modules
775
+ True
776
+
777
+ And we show how it works over an extension of an extension field::
778
+
779
+ sage: R2.<z> = L[]; M.<z> = L.extension(z^2 - y)
780
+ sage: M.free_module() # needs sage.modules
781
+ (Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x,
782
+ Isomorphism:
783
+ From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
784
+ To: Function field in z defined by z^2 - y,
785
+ Isomorphism:
786
+ From: Function field in z defined by z^2 - y
787
+ To: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x)
788
+
789
+ We can also get the vector space of ``M`` over ``K``::
790
+
791
+ sage: M.free_module(K) # needs sage.modules
792
+ (Vector space of dimension 10 over Rational function field in x over Rational Field,
793
+ Isomorphism:
794
+ From: Vector space of dimension 10 over Rational function field in x over Rational Field
795
+ To: Function field in z defined by z^2 - y,
796
+ Isomorphism:
797
+ From: Function field in z defined by z^2 - y
798
+ To: Vector space of dimension 10 over Rational function field in x over Rational Field)
799
+ """
800
+ if basis is not None:
801
+ raise NotImplementedError
802
+ from .maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace
803
+ if base is None:
804
+ base = self.base_field()
805
+ degree = self.degree(base)
806
+ V = base**degree
807
+ if not map:
808
+ return V
809
+ from_V = MapVectorSpaceToFunctionField(V, self)
810
+ to_V = MapFunctionFieldToVectorSpace(self, V)
811
+ return (V, from_V, to_V)
812
+
813
+ def maximal_order(self):
814
+ """
815
+ Return the maximal order of the function field.
816
+
817
+ EXAMPLES::
818
+
819
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
820
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
821
+ sage: L.maximal_order()
822
+ Maximal order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
823
+ """
824
+ from .order_polymod import FunctionFieldMaximalOrder_polymod
825
+ return FunctionFieldMaximalOrder_polymod(self)
826
+
827
+ def maximal_order_infinite(self):
828
+ """
829
+ Return the maximal infinite order of the function field.
830
+
831
+ EXAMPLES::
832
+
833
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
834
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
835
+ sage: L.maximal_order_infinite()
836
+ Maximal infinite order of Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
837
+
838
+ sage: K.<x> = FunctionField(GF(2)); _.<t> = K[] # needs sage.rings.finite_rings
839
+ sage: F.<y> = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # needs sage.rings.finite_rings
840
+ sage: F.maximal_order_infinite() # needs sage.rings.finite_rings
841
+ Maximal infinite order of Function field in y defined by y^3 + x^6 + x^4 + x^2
842
+
843
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[] # needs sage.rings.finite_rings
844
+ sage: L.<y> = K.extension(Y^2 + Y + x + 1/x) # needs sage.rings.finite_rings
845
+ sage: L.maximal_order_infinite() # needs sage.rings.finite_rings
846
+ Maximal infinite order of Function field in y defined by y^2 + y + (x^2 + 1)/x
847
+ """
848
+ from .order_polymod import FunctionFieldMaximalOrderInfinite_polymod
849
+ return FunctionFieldMaximalOrderInfinite_polymod(self)
850
+
851
+ def different(self):
852
+ """
853
+ Return the different of the function field.
854
+
855
+ EXAMPLES::
856
+
857
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[] # needs sage.rings.finite_rings
858
+ sage: F.<y> = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # needs sage.rings.finite_rings
859
+ sage: F.different() # needs sage.rings.finite_rings
860
+ 2*Place (x, (1/(x^3 + x^2 + x))*y^2)
861
+ + 2*Place (x^2 + x + 1, (1/(x^3 + x^2 + x))*y^2)
862
+ """
863
+ O = self.maximal_order()
864
+ Oinf = self.maximal_order_infinite()
865
+ return O.different().divisor() + Oinf.different().divisor()
866
+
867
+ def equation_order(self):
868
+ """
869
+ Return the equation order of the function field.
870
+
871
+ If we view the function field as being presented as `K[y]/(f(y))`, then
872
+ the order generated by the class of `y` is returned. If `f`
873
+ is not monic, then :meth:`_make_monic_integral` is called, and instead
874
+ we get the order generated by some integral multiple of a root of `f`.
875
+
876
+ EXAMPLES::
877
+
878
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
879
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
880
+ sage: O = L.equation_order()
881
+ sage: O.basis()
882
+ (1, x*y, x^2*y^2, x^3*y^3, x^4*y^4)
883
+
884
+ We try an example, in which the defining polynomial is not
885
+ monic and is not integral::
886
+
887
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
888
+ sage: L.<y> = K.extension(x^2*y^5 - 1/x); L
889
+ Function field in y defined by x^2*y^5 - 1/x
890
+ sage: O = L.equation_order()
891
+ sage: O.basis()
892
+ (1, x^3*y, x^6*y^2, x^9*y^3, x^12*y^4)
893
+ """
894
+ d = self._make_monic_integral(self.polynomial())[1]
895
+ return self.order(d*self.gen(), check=False)
896
+
897
+ def hom(self, im_gens, base_morphism=None):
898
+ """
899
+ Create a homomorphism from the function field to another function field.
900
+
901
+ INPUT:
902
+
903
+ - ``im_gens`` -- list of images of the generators of the function field
904
+ and of successive base rings
905
+
906
+ - ``base_morphism`` -- homomorphism of the base ring, after the
907
+ ``im_gens`` are used. Thus if ``im_gens`` has length 2, then
908
+ ``base_morphism`` should be a morphism from the base ring of the base
909
+ ring of the function field.
910
+
911
+ EXAMPLES:
912
+
913
+ We create a rational function field, and a quadratic extension of it::
914
+
915
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
916
+ sage: L.<y> = K.extension(y^2 - x^3 - 1)
917
+
918
+ We make the field automorphism that sends y to -y::
919
+
920
+ sage: f = L.hom(-y); f
921
+ Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1
922
+ Defn: y |--> -y
923
+
924
+ Evaluation works::
925
+
926
+ sage: f(y*x - 1/x)
927
+ -x*y - 1/x
928
+
929
+ We try to define an invalid morphism::
930
+
931
+ sage: f = L.hom(y + 1)
932
+ Traceback (most recent call last):
933
+ ...
934
+ ValueError: invalid morphism
935
+
936
+ We make a morphism of the base rational function field::
937
+
938
+ sage: phi = K.hom(x + 1); phi
939
+ Function Field endomorphism of Rational function field in x over Rational Field
940
+ Defn: x |--> x + 1
941
+ sage: phi(x^3 - 3)
942
+ x^3 + 3*x^2 + 3*x - 2
943
+ sage: (x+1)^3 - 3
944
+ x^3 + 3*x^2 + 3*x - 2
945
+
946
+ We make a morphism by specifying where the generators and the
947
+ base generators go::
948
+
949
+ sage: L.hom([-y, x])
950
+ Function Field endomorphism of Function field in y defined by y^2 - x^3 - 1
951
+ Defn: y |--> -y
952
+ x |--> x
953
+
954
+ You can also specify a morphism on the base::
955
+
956
+ sage: R1.<q> = K[]
957
+ sage: L1.<q> = K.extension(q^2 - (x+1)^3 - 1)
958
+ sage: L.hom(q, base_morphism=phi)
959
+ Function Field morphism:
960
+ From: Function field in y defined by y^2 - x^3 - 1
961
+ To: Function field in q defined by q^2 - x^3 - 3*x^2 - 3*x - 2
962
+ Defn: y |--> q
963
+ x |--> x + 1
964
+
965
+ We make another extension of a rational function field::
966
+
967
+ sage: K2.<t> = FunctionField(QQ); R2.<w> = K2[]
968
+ sage: L2.<w> = K2.extension((4*w)^2 - (t+1)^3 - 1)
969
+
970
+ We define a morphism, by giving the images of generators::
971
+
972
+ sage: f = L.hom([4*w, t + 1]); f
973
+ Function Field morphism:
974
+ From: Function field in y defined by y^2 - x^3 - 1
975
+ To: Function field in w defined by 16*w^2 - t^3 - 3*t^2 - 3*t - 2
976
+ Defn: y |--> 4*w
977
+ x |--> t + 1
978
+
979
+ Evaluation works, as expected::
980
+
981
+ sage: f(y+x)
982
+ 4*w + t + 1
983
+ sage: f(x*y + x/(x^2+1))
984
+ (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2)
985
+
986
+ We make another extension of a rational function field::
987
+
988
+ sage: K3.<yy> = FunctionField(QQ); R3.<xx> = K3[]
989
+ sage: L3.<xx> = K3.extension(yy^2 - xx^3 - 1)
990
+
991
+ This is the function field L with the generators exchanged. We define a morphism to L::
992
+
993
+ sage: g = L3.hom([x,y]); g
994
+ Function Field morphism:
995
+ From: Function field in xx defined by -xx^3 + yy^2 - 1
996
+ To: Function field in y defined by y^2 - x^3 - 1
997
+ Defn: xx |--> x
998
+ yy |--> y
999
+ """
1000
+ if not isinstance(im_gens, (list, tuple)):
1001
+ im_gens = [im_gens]
1002
+ if len(im_gens) == 0:
1003
+ raise ValueError("no images specified")
1004
+
1005
+ if len(im_gens) > 1:
1006
+ base_morphism = self.base_field().hom(im_gens[1:], base_morphism)
1007
+
1008
+ # the codomain of this morphism is the field containing all the im_gens
1009
+ codomain = im_gens[0].parent()
1010
+ if base_morphism is not None:
1011
+ from sage.categories.pushout import pushout
1012
+ codomain = pushout(codomain, base_morphism.codomain())
1013
+
1014
+ from .maps import FunctionFieldMorphism_polymod
1015
+ return FunctionFieldMorphism_polymod(self.Hom(codomain), im_gens[0], base_morphism)
1016
+
1017
+ @cached_method
1018
+ def genus(self):
1019
+ """
1020
+ Return the genus of the function field.
1021
+
1022
+ For now, the genus is computed using Singular.
1023
+
1024
+ EXAMPLES::
1025
+
1026
+ sage: K.<x> = FunctionField(QQ); R.<y> = K[]
1027
+ sage: L.<y> = K.extension(y^3 - (x^3 + 2*x*y + 1/x))
1028
+ sage: L.genus()
1029
+ 3
1030
+ """
1031
+ # Unfortunately Singular can not compute the genus with the
1032
+ # polynomial_ring()._singular_ object because genus method only accepts
1033
+ # a ring of transcendental degree 2 over a prime field not a ring of
1034
+ # transcendental degree 1 over a rational function field of one variable
1035
+
1036
+ if (isinstance(self._base_field, RationalFunctionField) and
1037
+ self._base_field.constant_field().is_prime_field()):
1038
+ from sage.interfaces.singular import singular
1039
+
1040
+ # making the auxiliary ring which only has polynomials
1041
+ # with integral coefficients.
1042
+ tmpAuxRing = PolynomialRing(self._base_field.constant_field(),
1043
+ str(self._base_field.gen()) + ',' + str(self._ring.gen()))
1044
+ intMinPoly, d = self._make_monic_integral(self._polynomial)
1045
+ curveIdeal = tmpAuxRing.ideal(intMinPoly)
1046
+
1047
+ singular.lib('normal.lib') # loading genus method in Singular
1048
+ return int(curveIdeal._singular_().genus())
1049
+
1050
+ else:
1051
+ raise NotImplementedError("computation of genus over non-prime "
1052
+ "constant fields not implemented yet")
1053
+
1054
+ def _simple_model(self, name='v'):
1055
+ r"""
1056
+ Return a finite extension `N/K(x)` isomorphic to the tower of
1057
+ extensions `M/L/K(x)` with `K` perfect.
1058
+
1059
+ Helper method for :meth:`simple_model`.
1060
+
1061
+ INPUT:
1062
+
1063
+ - ``name`` -- string; the name of the generator of `N`
1064
+
1065
+ ALGORITHM:
1066
+
1067
+ Since `K` is perfect, the extension `M/K(x)` is simple, i.e., generated
1068
+ by a single element [BM1940]_. Therefore, there are only finitely many
1069
+ intermediate fields (Exercise 3.6.7 in [Bo2009]_).
1070
+ Let `a` be a generator of `M/L` and let `b` be a generator of `L/K(x)`.
1071
+ For some `i` the field `N_i=K(x)(a+x^ib)` is isomorphic to `M` and so
1072
+ it is enough to test for all terms of the form `a+x^ib` whether they
1073
+ generate a field of the right degree.
1074
+ Indeed, suppose for contradiction that for all `i` we had `N_i\neq M`.
1075
+ Then `N_i=N_j` for some `i,j`. Thus `(a+x^ib)-(a+x^jb)=b(x^i-x^j)\in
1076
+ N_j` and so `b\in N_j`. Similarly,
1077
+ `a+x^ib-x^{i-j}(a+x^jb)=a(1+x^{i-j})\in N_j` and so `a\in N_j`.
1078
+ Therefore, `N_j=M`.
1079
+
1080
+ TESTS::
1081
+
1082
+ sage: K.<x> = FunctionField(QQ)
1083
+ sage: R.<y> = K[]
1084
+ sage: L.<y> = K.extension(y^2 - x)
1085
+ sage: R.<z> = L[]
1086
+ sage: M.<z> = L.extension(z^2 - y)
1087
+ sage: M._simple_model()
1088
+ (Function field in v defined by v^4 - x,
1089
+ Function Field morphism:
1090
+ From: Function field in v defined by v^4 - x
1091
+ To: Function field in z defined by z^2 - y
1092
+ Defn: v |--> z,
1093
+ Function Field morphism:
1094
+ From: Function field in z defined by z^2 - y
1095
+ To: Function field in v defined by v^4 - x
1096
+ Defn: z |--> v
1097
+ y |--> v^2)
1098
+
1099
+ Check that this also works for inseparable extensions::
1100
+
1101
+ sage: # needs sage.rings.finite_rings
1102
+ sage: K.<x> = FunctionField(GF(2))
1103
+ sage: R.<y> = K[]
1104
+ sage: L.<y> = K.extension(y^2 - x)
1105
+ sage: R.<z> = L[]
1106
+ sage: M.<z> = L.extension(z^2 - y)
1107
+ sage: M._simple_model()
1108
+ (Function field in v defined by v^4 + x,
1109
+ Function Field morphism:
1110
+ From: Function field in v defined by v^4 + x
1111
+ To: Function field in z defined by z^2 + y
1112
+ Defn: v |--> z,
1113
+ Function Field morphism:
1114
+ From: Function field in z defined by z^2 + y
1115
+ To: Function field in v defined by v^4 + x
1116
+ Defn: z |--> v
1117
+ y |--> v^2)
1118
+
1119
+ An example where the generator of the last extension does not generate
1120
+ the extension of the rational function field::
1121
+
1122
+ sage: # needs sage.rings.finite_rings
1123
+ sage: K.<x> = FunctionField(GF(2))
1124
+ sage: R.<y> = K[]
1125
+ sage: L.<y> = K.extension(y^2 - x)
1126
+ sage: R.<z> = L[]
1127
+ sage: M.<z> = L.extension(z^3 - 1)
1128
+ sage: M._simple_model()
1129
+ (Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1,
1130
+ Function Field morphism:
1131
+ From: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1
1132
+ To: Function field in z defined by z^3 + 1
1133
+ Defn: v |--> z + y,
1134
+ Function Field morphism:
1135
+ From: Function field in z defined by z^3 + 1
1136
+ To: Function field in v defined by v^6 + x*v^4 + x^2*v^2 + x^3 + 1
1137
+ Defn: z |--> v^4 + x^2
1138
+ y |--> v^4 + v + x^2)
1139
+ """
1140
+ M = self
1141
+ L = M.base_field()
1142
+ K = L.base_field()
1143
+
1144
+ assert (isinstance(K, RationalFunctionField))
1145
+ assert (K is not L)
1146
+ assert (L is not M)
1147
+
1148
+ if not K.constant_field().is_perfect():
1149
+ raise NotImplementedError("simple_model() only implemented over perfect constant fields")
1150
+
1151
+ x = K.gen()
1152
+ b = L.gen()
1153
+ a = M.gen()
1154
+
1155
+ # using a+x^i*b tends to lead to huge powers of x in the minimal
1156
+ # polynomial of the resulting field; it is better to try terms of
1157
+ # the form a+i*b first (but in characteristic p>0 there are only
1158
+ # finitely many of these)
1159
+ # We systematically try elements of the form a+b*factor*x^exponent
1160
+ factor = self.constant_base_field().zero()
1161
+ exponent = 0
1162
+ while True:
1163
+ v = M(a+b*factor*x**exponent)
1164
+ minpoly = v.matrix(K).minpoly()
1165
+ if minpoly.degree() == M.degree()*L.degree():
1166
+ break
1167
+ factor += 1
1168
+ if factor == 0:
1169
+ factor = self.constant_base_field().one()
1170
+ exponent += 1
1171
+
1172
+ N = K.extension(minpoly, names=(name,))
1173
+
1174
+ # the morphism N -> M, v |-> v
1175
+ N_to_M = N.hom(v)
1176
+
1177
+ # the morphism M -> N, b |-> M_b, a |-> M_a
1178
+ V, V_to_M, M_to_V = M.free_module(K)
1179
+ V, V_to_N, N_to_V = N.free_module(K)
1180
+ from sage.matrix.matrix_space import MatrixSpace
1181
+ MS = MatrixSpace(V.base_field(), V.dimension())
1182
+ # the power basis of v over K
1183
+ B = [M_to_V(v**i) for i in range(V.dimension())]
1184
+ B = MS(B)
1185
+ M_b = V_to_N(B.solve_left(M_to_V(b)))
1186
+ M_a = V_to_N(B.solve_left(M_to_V(a)))
1187
+ M_to_N = M.hom([M_a, M_b])
1188
+
1189
+ return N, N_to_M, M_to_N
1190
+
1191
+ @cached_method
1192
+ def simple_model(self, name=None):
1193
+ """
1194
+ Return a function field isomorphic to this field which is a simple
1195
+ extension of a rational function field.
1196
+
1197
+ INPUT:
1198
+
1199
+ - ``name`` -- string (default: ``None``); the name of generator of
1200
+ the simple extension. If ``None``, then the name of the generator
1201
+ will be the same as the name of the generator of this function field.
1202
+
1203
+ OUTPUT:
1204
+
1205
+ A triple ``(F,f,t)`` where ``F`` is a field isomorphic to this field,
1206
+ ``f`` is an isomorphism from ``F`` to this function field and ``t`` is
1207
+ the inverse of ``f``.
1208
+
1209
+ EXAMPLES:
1210
+
1211
+ A tower of four function fields::
1212
+
1213
+ sage: K.<x> = FunctionField(QQ); R.<z> = K[]
1214
+ sage: L.<z> = K.extension(z^2 - x); R.<u> = L[]
1215
+ sage: M.<u> = L.extension(u^2 - z); R.<v> = M[]
1216
+ sage: N.<v> = M.extension(v^2 - u)
1217
+
1218
+ The fields N and M as simple extensions of K::
1219
+
1220
+ sage: N.simple_model()
1221
+ (Function field in v defined by v^8 - x,
1222
+ Function Field morphism:
1223
+ From: Function field in v defined by v^8 - x
1224
+ To: Function field in v defined by v^2 - u
1225
+ Defn: v |--> v,
1226
+ Function Field morphism:
1227
+ From: Function field in v defined by v^2 - u
1228
+ To: Function field in v defined by v^8 - x
1229
+ Defn: v |--> v
1230
+ u |--> v^2
1231
+ z |--> v^4
1232
+ x |--> x)
1233
+ sage: M.simple_model()
1234
+ (Function field in u defined by u^4 - x,
1235
+ Function Field morphism:
1236
+ From: Function field in u defined by u^4 - x
1237
+ To: Function field in u defined by u^2 - z
1238
+ Defn: u |--> u,
1239
+ Function Field morphism:
1240
+ From: Function field in u defined by u^2 - z
1241
+ To: Function field in u defined by u^4 - x
1242
+ Defn: u |--> u
1243
+ z |--> u^2
1244
+ x |--> x)
1245
+
1246
+ An optional parameter ``name`` can be used to set the name of the
1247
+ generator of the simple extension::
1248
+
1249
+ sage: M.simple_model(name='t')
1250
+ (Function field in t defined by t^4 - x, Function Field morphism:
1251
+ From: Function field in t defined by t^4 - x
1252
+ To: Function field in u defined by u^2 - z
1253
+ Defn: t |--> u, Function Field morphism:
1254
+ From: Function field in u defined by u^2 - z
1255
+ To: Function field in t defined by t^4 - x
1256
+ Defn: u |--> t
1257
+ z |--> t^2
1258
+ x |--> x)
1259
+
1260
+ An example with higher degrees::
1261
+
1262
+ sage: # needs sage.rings.finite_rings
1263
+ sage: K.<x> = FunctionField(GF(3)); R.<y> = K[]
1264
+ sage: L.<y> = K.extension(y^5 - x); R.<z> = L[]
1265
+ sage: M.<z> = L.extension(z^3 - x)
1266
+ sage: M.simple_model()
1267
+ (Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3,
1268
+ Function Field morphism:
1269
+ From: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3
1270
+ To: Function field in z defined by z^3 + 2*x
1271
+ Defn: z |--> z + y,
1272
+ Function Field morphism:
1273
+ From: Function field in z defined by z^3 + 2*x
1274
+ To: Function field in z defined by z^15 + x*z^12 + x^2*z^9 + 2*x^3*z^6 + 2*x^4*z^3 + 2*x^5 + 2*x^3
1275
+ Defn: z |--> 2/x*z^6 + 2*z^3 + z + 2*x
1276
+ y |--> 1/x*z^6 + z^3 + x
1277
+ x |--> x)
1278
+
1279
+ This also works for inseparable extensions::
1280
+
1281
+ sage: # needs sage.rings.finite_rings
1282
+ sage: K.<x> = FunctionField(GF(2)); R.<y> = K[]
1283
+ sage: L.<y> = K.extension(y^2 - x); R.<z> = L[]
1284
+ sage: M.<z> = L.extension(z^2 - y)
1285
+ sage: M.simple_model()
1286
+ (Function field in z defined by z^4 + x,
1287
+ Function Field morphism:
1288
+ From: Function field in z defined by z^4 + x
1289
+ To: Function field in z defined by z^2 + y
1290
+ Defn: z |--> z,
1291
+ Function Field morphism:
1292
+ From: Function field in z defined by z^2 + y
1293
+ To: Function field in z defined by z^4 + x
1294
+ Defn: z |--> z
1295
+ y |--> z^2
1296
+ x |--> x)
1297
+ """
1298
+ if name is None:
1299
+ name = self.variable_name()
1300
+
1301
+ if isinstance(self.base_field(), RationalFunctionField):
1302
+ # the extension is simple already
1303
+ if name == self.variable_name():
1304
+ id = Hom(self, self).identity()
1305
+ return self, id, id
1306
+ else:
1307
+ ret = self.base_field().extension(self.polynomial(), names=(name,))
1308
+ f = ret.hom(self.gen())
1309
+ t = self.hom(ret.gen())
1310
+ return ret, f, t
1311
+ else:
1312
+ # recursively collapse the tower of fields
1313
+ base = self.base_field()
1314
+ base_, from_base_, to_base_ = base.simple_model()
1315
+ self_ = base_.extension(self.polynomial().map_coefficients(to_base_), names=(name,))
1316
+ gens_in_base_ = [to_base_(k.gen())
1317
+ for k in base._intermediate_fields(base.rational_function_field())]
1318
+ to_self_ = self.hom([self_.gen()] + gens_in_base_)
1319
+ from_self_ = self_.hom([self.gen(), from_base_(base_.gen())])
1320
+
1321
+ # now collapse self_/base_/K(x)
1322
+ ret, ret_to_self_, self__to_ret = self_._simple_model(name)
1323
+ ret_to_self = ret.hom(from_self_(ret_to_self_(ret.gen())))
1324
+ gens_in_ret = [self__to_ret(to_self_(k.gen()))
1325
+ for k in self._intermediate_fields(self.rational_function_field())]
1326
+ self_to_ret = self.hom(gens_in_ret)
1327
+ return ret, ret_to_self, self_to_ret
1328
+
1329
+ @cached_method
1330
+ def primitive_element(self):
1331
+ r"""
1332
+ Return a primitive element over the underlying rational function field.
1333
+
1334
+ If this is a finite extension of a rational function field `K(x)` with
1335
+ `K` perfect, then this is a simple extension of `K(x)`, i.e., there is
1336
+ a primitive element `y` which generates this field over `K(x)`. This
1337
+ method returns such an element `y`.
1338
+
1339
+ EXAMPLES::
1340
+
1341
+ sage: K.<x> = FunctionField(QQ)
1342
+ sage: R.<y> = K[]
1343
+ sage: L.<y> = K.extension(y^2 - x)
1344
+ sage: R.<z> = L[]
1345
+ sage: M.<z> = L.extension(z^2 - y)
1346
+ sage: R.<z> = L[]
1347
+ sage: N.<u> = L.extension(z^2 - x - 1)
1348
+ sage: N.primitive_element()
1349
+ u + y
1350
+ sage: M.primitive_element()
1351
+ z
1352
+ sage: L.primitive_element()
1353
+ y
1354
+
1355
+ This also works for inseparable extensions::
1356
+
1357
+ sage: # needs sage.rings.finite_rings
1358
+ sage: K.<x> = FunctionField(GF(2))
1359
+ sage: R.<Y> = K[]
1360
+ sage: L.<y> = K.extension(Y^2 - x)
1361
+ sage: R.<Z> = L[]
1362
+ sage: M.<z> = L.extension(Z^2 - y)
1363
+ sage: M.primitive_element()
1364
+ z
1365
+ """
1366
+ N, f, t = self.simple_model()
1367
+ return f(N.gen())
1368
+
1369
+ @cached_method
1370
+ def separable_model(self, names=None):
1371
+ r"""
1372
+ Return a function field isomorphic to this field which is a separable
1373
+ extension of a rational function field.
1374
+
1375
+ INPUT:
1376
+
1377
+ - ``names`` -- tuple of two strings or ``None`` (default: ``None``);
1378
+ the second entry will be used as the variable name of the rational
1379
+ function field, the first entry will be used as the variable name of
1380
+ its separable extension. If ``None``, then the variable names will be
1381
+ chosen automatically.
1382
+
1383
+ OUTPUT:
1384
+
1385
+ A triple ``(F,f,t)`` where ``F`` is a function field, ``f`` is an
1386
+ isomorphism from ``F`` to this function field, and ``t`` is the inverse
1387
+ of ``f``.
1388
+
1389
+ ALGORITHM:
1390
+
1391
+ Suppose that the constant base field is perfect. If this is a monic
1392
+ integral inseparable extension of a rational function field, then the
1393
+ defining polynomial is separable if we swap the variables (Proposition
1394
+ 4.8 in Chapter VIII of [Lan2002]_.)
1395
+ The algorithm reduces to this case with :meth:`monic_integral_model`.
1396
+
1397
+ EXAMPLES::
1398
+
1399
+ sage: # needs sage.rings.finite_rings
1400
+ sage: K.<x> = FunctionField(GF(2))
1401
+ sage: R.<y> = K[]
1402
+ sage: L.<y> = K.extension(y^2 - x^3)
1403
+ sage: L.separable_model(('t','w'))
1404
+ (Function field in t defined by t^3 + w^2,
1405
+ Function Field morphism:
1406
+ From: Function field in t defined by t^3 + w^2
1407
+ To: Function field in y defined by y^2 + x^3
1408
+ Defn: t |--> x
1409
+ w |--> y,
1410
+ Function Field morphism:
1411
+ From: Function field in y defined by y^2 + x^3
1412
+ To: Function field in t defined by t^3 + w^2
1413
+ Defn: y |--> w
1414
+ x |--> t)
1415
+
1416
+ This also works for non-integral polynomials::
1417
+
1418
+ sage: # needs sage.rings.finite_rings
1419
+ sage: K.<x> = FunctionField(GF(2))
1420
+ sage: R.<y> = K[]
1421
+ sage: L.<y> = K.extension(y^2/x - x^2)
1422
+ sage: L.separable_model()
1423
+ (Function field in y_ defined by y_^3 + x_^2,
1424
+ Function Field morphism:
1425
+ From: Function field in y_ defined by y_^3 + x_^2
1426
+ To: Function field in y defined by 1/x*y^2 + x^2
1427
+ Defn: y_ |--> x
1428
+ x_ |--> y,
1429
+ Function Field morphism:
1430
+ From: Function field in y defined by 1/x*y^2 + x^2
1431
+ To: Function field in y_ defined by y_^3 + x_^2
1432
+ Defn: y |--> x_
1433
+ x |--> y_)
1434
+
1435
+ If the base field is not perfect this is only implemented in trivial cases::
1436
+
1437
+ sage: # needs sage.rings.finite_rings
1438
+ sage: k.<t> = FunctionField(GF(2))
1439
+ sage: k.is_perfect()
1440
+ False
1441
+ sage: K.<x> = FunctionField(k)
1442
+ sage: R.<y> = K[]
1443
+ sage: L.<y> = K.extension(y^3 - t)
1444
+ sage: L.separable_model()
1445
+ (Function field in y defined by y^3 + t,
1446
+ Function Field endomorphism of Function field in y defined by y^3 + t
1447
+ Defn: y |--> y
1448
+ x |--> x,
1449
+ Function Field endomorphism of Function field in y defined by y^3 + t
1450
+ Defn: y |--> y
1451
+ x |--> x)
1452
+
1453
+ Some other cases for which a separable model could be constructed are
1454
+ not supported yet::
1455
+
1456
+ sage: R.<y> = K[] # needs sage.rings.finite_rings
1457
+ sage: L.<y> = K.extension(y^2 - t) # needs sage.rings.finite_rings
1458
+ sage: L.separable_model() # needs sage.rings.finite_rings
1459
+ Traceback (most recent call last):
1460
+ ...
1461
+ NotImplementedError: constructing a separable model is only implemented
1462
+ for function fields over a perfect constant base field
1463
+
1464
+ TESTS:
1465
+
1466
+ Check that this also works in characteristic zero::
1467
+
1468
+ sage: K.<x> = FunctionField(QQ)
1469
+ sage: R.<y> = K[]
1470
+ sage: L.<y> = K.extension(y^2 - x^3)
1471
+ sage: L.separable_model()
1472
+ (Function field in y defined by y^2 - x^3,
1473
+ Function Field endomorphism of Function field in y defined by y^2 - x^3
1474
+ Defn: y |--> y
1475
+ x |--> x,
1476
+ Function Field endomorphism of Function field in y defined by y^2 - x^3
1477
+ Defn: y |--> y
1478
+ x |--> x)
1479
+
1480
+ Check that this works for towers of inseparable extensions::
1481
+
1482
+ sage: # needs sage.rings.finite_rings
1483
+ sage: K.<x> = FunctionField(GF(2))
1484
+ sage: R.<y> = K[]
1485
+ sage: L.<y> = K.extension(y^2 - x)
1486
+ sage: R.<z> = L[]
1487
+ sage: M.<z> = L.extension(z^2 - y)
1488
+ sage: M.separable_model()
1489
+ (Function field in z_ defined by z_ + x_^4,
1490
+ Function Field morphism:
1491
+ From: Function field in z_ defined by z_ + x_^4
1492
+ To: Function field in z defined by z^2 + y
1493
+ Defn: z_ |--> x
1494
+ x_ |--> z,
1495
+ Function Field morphism:
1496
+ From: Function field in z defined by z^2 + y
1497
+ To: Function field in z_ defined by z_ + x_^4
1498
+ Defn: z |--> x_
1499
+ y |--> x_^2
1500
+ x |--> x_^4)
1501
+
1502
+ Check that this also works if only the first extension is inseparable::
1503
+
1504
+ sage: # needs sage.rings.finite_rings
1505
+ sage: K.<x> = FunctionField(GF(2))
1506
+ sage: R.<y> = K[]
1507
+ sage: L.<y> = K.extension(y^2 - x)
1508
+ sage: R.<z> = L[]
1509
+ sage: M.<z> = L.extension(z^3 - y)
1510
+ sage: M.separable_model()
1511
+ (Function field in z_ defined by z_ + x_^6,
1512
+ Function Field morphism:
1513
+ From: Function field in z_ defined by z_ + x_^6
1514
+ To: Function field in z defined by z^3 + y
1515
+ Defn: z_ |--> x
1516
+ x_ |--> z,
1517
+ Function Field morphism:
1518
+ From: Function field in z defined by z^3 + y
1519
+ To: Function field in z_ defined by z_ + x_^6
1520
+ Defn: z |--> x_
1521
+ y |--> x_^3
1522
+ x |--> x_^6)
1523
+ """
1524
+ if names is None:
1525
+ pass
1526
+ elif not isinstance(names, tuple):
1527
+ raise TypeError("names must be a tuple consisting of two strings")
1528
+ elif len(names) != 2:
1529
+ raise ValueError("must provide exactly two variable names")
1530
+
1531
+ if self.base_ring() is not self.rational_function_field():
1532
+ L, from_L, to_L = self.simple_model()
1533
+ K, from_K, to_K = L.separable_model(names=names)
1534
+ f = K.hom([from_L(from_K(K.gen())), from_L(from_K(K.base_field().gen()))])
1535
+ t = self.hom([to_K(to_L(k.gen())) for k in self._intermediate_fields(self.rational_function_field())])
1536
+ return K, f, t
1537
+
1538
+ if self.polynomial().gcd(self.polynomial().derivative()).is_one():
1539
+ # the model is already separable
1540
+ if names is None:
1541
+ names = self.variable_name(), self.base_field().variable_name()
1542
+ return self.change_variable_name(names)
1543
+
1544
+ if not self.constant_base_field().is_perfect():
1545
+ raise NotImplementedError("constructing a separable model is only implemented for function fields over a perfect constant base field")
1546
+
1547
+ if names is None:
1548
+ names = (self.variable_name()+"_", self.rational_function_field().variable_name()+"_")
1549
+
1550
+ L, from_L, to_L = self.monic_integral_model()
1551
+
1552
+ if L.polynomial().gcd(L.polynomial().derivative()).is_one():
1553
+ # L is separable
1554
+ ret, ret_to_L, L_to_ret = L.change_variable_name(names)
1555
+ f = ret.hom([from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))])
1556
+ t = self.hom([L_to_ret(to_L(self.gen())), L_to_ret(to_L(self.base_field().gen()))])
1557
+ return ret, f, t
1558
+ else:
1559
+ # otherwise, the polynomial of L must be separable in the other variable
1560
+ from .constructor import FunctionField
1561
+ K = FunctionField(self.constant_base_field(), names=(names[1],))
1562
+ # construct a field isomorphic to L on top of K
1563
+
1564
+ # turn the minpoly of K into a bivariate polynomial
1565
+ if names[0] == names[1]:
1566
+ raise ValueError("names of generators must be distinct")
1567
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1568
+ R = PolynomialRing(self.constant_base_field(), names=names)
1569
+ S = R.remove_var(names[1])
1570
+ f = R(L.polynomial().change_variable_name(names[1]).map_coefficients(
1571
+ lambda c: c.numerator().change_variable_name(names[0]), S))
1572
+ f = f.polynomial(R.gen(0)).change_ring(K)
1573
+ f /= f.leading_coefficient()
1574
+ # f must be separable in the other variable (otherwise it would factor)
1575
+ assert f.gcd(f.derivative()).is_one()
1576
+
1577
+ ret = K.extension(f, names=(names[0],))
1578
+ # isomorphisms between L and ret are given by swapping generators
1579
+ ret_to_L = ret.hom([L(L.base_field().gen()), L.gen()])
1580
+ L_to_ret = L.hom([ret(K.gen()), ret.gen()])
1581
+ # compose with from_L and to_L to get the desired isomorphisms between self and ret
1582
+ f = ret.hom([from_L(ret_to_L(ret.gen())), from_L(ret_to_L(ret.base_field().gen()))])
1583
+ t = self.hom([L_to_ret(to_L(self.gen())), L_to_ret(to_L(self.base_field().gen()))])
1584
+ return ret, f, t
1585
+
1586
+ def change_variable_name(self, name):
1587
+ r"""
1588
+ Return a field isomorphic to this field with variable(s) ``name``.
1589
+
1590
+ INPUT:
1591
+
1592
+ - ``name`` -- string or tuple consisting of a strings; the names of
1593
+ the new variables starting with a generator of this field and going
1594
+ down to the rational function field
1595
+
1596
+ OUTPUT:
1597
+
1598
+ A triple ``F,f,t`` where ``F`` is a function field, ``f`` is an
1599
+ isomorphism from ``F`` to this field, and ``t`` is the inverse of
1600
+ ``f``.
1601
+
1602
+ EXAMPLES::
1603
+
1604
+ sage: K.<x> = FunctionField(QQ)
1605
+ sage: R.<y> = K[]
1606
+ sage: L.<y> = K.extension(y^2 - x)
1607
+ sage: R.<z> = L[]
1608
+ sage: M.<z> = L.extension(z^2 - y)
1609
+
1610
+ sage: M.change_variable_name('zz')
1611
+ (Function field in zz defined by zz^2 - y,
1612
+ Function Field morphism:
1613
+ From: Function field in zz defined by zz^2 - y
1614
+ To: Function field in z defined by z^2 - y
1615
+ Defn: zz |--> z
1616
+ y |--> y
1617
+ x |--> x,
1618
+ Function Field morphism:
1619
+ From: Function field in z defined by z^2 - y
1620
+ To: Function field in zz defined by zz^2 - y
1621
+ Defn: z |--> zz
1622
+ y |--> y
1623
+ x |--> x)
1624
+ sage: M.change_variable_name(('zz','yy'))
1625
+ (Function field in zz defined by zz^2 - yy,
1626
+ Function Field morphism:
1627
+ From: Function field in zz defined by zz^2 - yy
1628
+ To: Function field in z defined by z^2 - y
1629
+ Defn: zz |--> z
1630
+ yy |--> y
1631
+ x |--> x,
1632
+ Function Field morphism:
1633
+ From: Function field in z defined by z^2 - y
1634
+ To: Function field in zz defined by zz^2 - yy
1635
+ Defn: z |--> zz
1636
+ y |--> yy
1637
+ x |--> x)
1638
+ sage: M.change_variable_name(('zz','yy','xx'))
1639
+ (Function field in zz defined by zz^2 - yy,
1640
+ Function Field morphism:
1641
+ From: Function field in zz defined by zz^2 - yy
1642
+ To: Function field in z defined by z^2 - y
1643
+ Defn: zz |--> z
1644
+ yy |--> y
1645
+ xx |--> x,
1646
+ Function Field morphism:
1647
+ From: Function field in z defined by z^2 - y
1648
+ To: Function field in zz defined by zz^2 - yy
1649
+ Defn: z |--> zz
1650
+ y |--> yy
1651
+ x |--> xx)
1652
+ """
1653
+ if not isinstance(name, tuple):
1654
+ name = (name,)
1655
+ if len(name) == 0:
1656
+ raise ValueError("name must contain at least one string")
1657
+ elif len(name) == 1:
1658
+ base = self.base_field()
1659
+ from_base = to_base = Hom(base, base).identity()
1660
+ else:
1661
+ base, from_base, to_base = self.base_field().change_variable_name(name[1:])
1662
+
1663
+ ret = base.extension(self.polynomial().map_coefficients(to_base), names=(name[0],))
1664
+ f = ret.hom([k.gen() for k in self._intermediate_fields(self.rational_function_field())])
1665
+ t = self.hom([k.gen() for k in ret._intermediate_fields(ret.rational_function_field())])
1666
+ return ret, f, t
1667
+
1668
+
1669
+ class FunctionField_simple(FunctionField_polymod):
1670
+ """
1671
+ Function fields defined by irreducible and separable polynomials
1672
+ over rational function fields.
1673
+ """
1674
+ @cached_method
1675
+ def _inversion_isomorphism(self):
1676
+ r"""
1677
+ Return an inverted function field isomorphic to ``self`` and isomorphisms
1678
+ between them.
1679
+
1680
+ An *inverted* function field `M` is an extension of the base rational
1681
+ function field `k(x)` of ``self``, and isomorphic to ``self`` by an
1682
+ isomorphism sending `x` to `1/x`, which we call an *inversion*
1683
+ isomorphism. Also the defining polynomial of the function field `M` is
1684
+ required to be monic and integral.
1685
+
1686
+ The inversion isomorphism is for internal use to reposition infinite
1687
+ places to finite places.
1688
+
1689
+ EXAMPLES::
1690
+
1691
+ sage: K.<x> = FunctionField(GF(2)); _.<t> = K[] # needs sage.rings.finite_rings
1692
+ sage: F.<y> = K.extension(t^3 - x^2*(x^2 + x + 1)^2) # needs sage.rings.finite_rings
1693
+ sage: F._inversion_isomorphism() # needs sage.rings.finite_rings
1694
+ (Function field in s defined by s^3 + x^16 + x^14 + x^12, Composite map:
1695
+ From: Function field in s defined by s^3 + x^16 + x^14 + x^12
1696
+ To: Function field in y defined by y^3 + x^6 + x^4 + x^2
1697
+ Defn: Function Field morphism:
1698
+ From: Function field in s defined by s^3 + x^16 + x^14 + x^12
1699
+ To: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6
1700
+ Defn: s |--> x^6*T
1701
+ x |--> x
1702
+ then
1703
+ Function Field morphism:
1704
+ From: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6
1705
+ To: Function field in y defined by y^3 + x^6 + x^4 + x^2
1706
+ Defn: T |--> y
1707
+ x |--> 1/x,
1708
+ Composite map:
1709
+ From: Function field in y defined by y^3 + x^6 + x^4 + x^2
1710
+ To: Function field in s defined by s^3 + x^16 + x^14 + x^12
1711
+ Defn: Function Field morphism:
1712
+ From: Function field in y defined by y^3 + x^6 + x^4 + x^2
1713
+ To: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6
1714
+ Defn: y |--> T
1715
+ x |--> 1/x
1716
+ then
1717
+ Function Field morphism:
1718
+ From: Function field in T defined by T^3 + (x^4 + x^2 + 1)/x^6
1719
+ To: Function field in s defined by s^3 + x^16 + x^14 + x^12
1720
+ Defn: T |--> 1/x^6*s
1721
+ x |--> x)
1722
+ """
1723
+ K = self.base_field()
1724
+ R = PolynomialRing(K, 'T')
1725
+ x = K.gen()
1726
+ xinv = 1/x
1727
+
1728
+ h = K.hom(xinv)
1729
+ F_poly = R([h(c) for c in self.polynomial().list()])
1730
+ F = K.extension(F_poly)
1731
+
1732
+ self2F = self.hom([F.gen(), xinv])
1733
+ F2self = F.hom([self.gen(), xinv])
1734
+
1735
+ M, M2F, F2M = F.monic_integral_model('s')
1736
+
1737
+ return M, F2self*M2F, F2M*self2F
1738
+
1739
+ def places_above(self, p):
1740
+ """
1741
+ Return places lying above ``p``.
1742
+
1743
+ INPUT:
1744
+
1745
+ - ``p`` -- place of the base rational function field
1746
+
1747
+ EXAMPLES::
1748
+
1749
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[] # needs sage.rings.finite_rings
1750
+ sage: F.<y> = K.extension(Y^3 - x^2*(x^2 + x + 1)^2) # needs sage.rings.finite_rings
1751
+ sage: all(q.place_below() == p # needs sage.rings.finite_rings
1752
+ ....: for p in K.places() for q in F.places_above(p))
1753
+ True
1754
+
1755
+ sage: K.<x> = FunctionField(QQ); _.<Y> = K[]
1756
+ sage: F.<y> = K.extension(Y^3 - x^2*(x^2 + x + 1)^2)
1757
+ sage: O = K.maximal_order()
1758
+ sage: pls = [O.ideal(x - c).place() for c in [-2, -1, 0, 1, 2]]
1759
+ sage: all(q.place_below() == p
1760
+ ....: for p in pls for q in F.places_above(p))
1761
+ True
1762
+
1763
+ sage: # needs sage.rings.number_field sage.symbolic
1764
+ sage: K.<x> = FunctionField(QQbar); _.<Y> = K[]
1765
+ sage: F.<y> = K.extension(Y^3 - x^2*(x^2 + x + 1)^2)
1766
+ sage: O = K.maximal_order()
1767
+ sage: pls = [O.ideal(x - QQbar(sqrt(c))).place()
1768
+ ....: for c in [-2, -1, 0, 1, 2]]
1769
+ sage: all(q.place_below() == p # long time (4s)
1770
+ ....: for p in pls for q in F.places_above(p))
1771
+ True
1772
+ """
1773
+ R = self.base_field()
1774
+
1775
+ if p not in R.place_set():
1776
+ raise TypeError("not a place of the base rational function field")
1777
+
1778
+ if p.is_infinite_place():
1779
+ dec = self.maximal_order_infinite().decomposition()
1780
+ else:
1781
+ dec = self.maximal_order().decomposition(p.prime_ideal())
1782
+
1783
+ return tuple([q.place() for q, deg, exp in dec])
1784
+
1785
+ def constant_field(self):
1786
+ """
1787
+ Return the algebraic closure of the base constant field in the function
1788
+ field.
1789
+
1790
+ EXAMPLES::
1791
+
1792
+ sage: K.<x> = FunctionField(GF(3)); _.<y> = K[] # needs sage.rings.finite_rings
1793
+ sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) # needs sage.rings.finite_rings
1794
+ sage: L.constant_field() # needs sage.rings.finite_rings
1795
+ Finite Field of size 3
1796
+ """
1797
+ return self.exact_constant_field()[0]
1798
+
1799
+ def exact_constant_field(self, name='t'):
1800
+ """
1801
+ Return the exact constant field and its embedding into the function field.
1802
+
1803
+ INPUT:
1804
+
1805
+ - ``name`` -- name (default: `t`) of the generator of the exact constant field
1806
+
1807
+ EXAMPLES::
1808
+
1809
+ sage: # needs sage.rings.finite_rings
1810
+ sage: K.<x> = FunctionField(GF(3)); _.<Y> = K[]
1811
+ sage: f = Y^2 - x*Y + x^2 + 1 # irreducible but not absolutely irreducible
1812
+ sage: L.<y> = K.extension(f)
1813
+ sage: L.genus()
1814
+ 0
1815
+ sage: L.exact_constant_field()
1816
+ (Finite Field in t of size 3^2, Ring morphism:
1817
+ From: Finite Field in t of size 3^2
1818
+ To: Function field in y defined by y^2 + 2*x*y + x^2 + 1
1819
+ Defn: t |--> y + x)
1820
+ sage: (y+x).divisor()
1821
+ 0
1822
+ """
1823
+ # A basis of the full constant field is obtained from
1824
+ # computing a Riemann-Roch basis of zero divisor.
1825
+ basis = self.divisor_group().zero().basis_function_space()
1826
+
1827
+ dim = len(basis)
1828
+
1829
+ for e in basis:
1830
+ _min_poly = e.minimal_polynomial(name)
1831
+ if _min_poly.degree() == dim:
1832
+ break
1833
+ k = self.constant_base_field()
1834
+ R = k[name]
1835
+ min_poly = R([k(c) for c in _min_poly.list()])
1836
+
1837
+ k_ext = k.extension(min_poly, name)
1838
+
1839
+ if k_ext.is_prime_field():
1840
+ # The cover of the quotient ring k_ext is the integer ring
1841
+ # whose generator is 1. This is different from the generator
1842
+ # of k_ext.
1843
+ embedding = k_ext.hom([self(1)], self)
1844
+ else:
1845
+ embedding = k_ext.hom([e], self)
1846
+
1847
+ return k_ext, embedding
1848
+
1849
+ def genus(self):
1850
+ """
1851
+ Return the genus of the function field.
1852
+
1853
+ EXAMPLES::
1854
+
1855
+ sage: # needs sage.rings.finite_rings
1856
+ sage: F.<a> = GF(16)
1857
+ sage: K.<x> = FunctionField(F); K
1858
+ Rational function field in x over Finite Field in a of size 2^4
1859
+ sage: R.<t> = PolynomialRing(K)
1860
+ sage: L.<y> = K.extension(t^4 + t - x^5)
1861
+ sage: L.genus()
1862
+ 6
1863
+
1864
+ sage: # needs sage.rings.number_field
1865
+ sage: R.<T> = QQ[]
1866
+ sage: N.<a> = NumberField(T^2 + 1)
1867
+ sage: K.<x> = FunctionField(N); K
1868
+ Rational function field in x over Number Field in a with defining polynomial T^2 + 1
1869
+ sage: K.genus()
1870
+ 0
1871
+ sage: S.<t> = PolynomialRing(K)
1872
+ sage: L.<y> = K.extension(t^2 - x^3 + x)
1873
+ sage: L.genus()
1874
+ 1
1875
+
1876
+ The genus is computed by the Hurwitz genus formula.
1877
+ """
1878
+ k, _ = self.exact_constant_field()
1879
+ if k in NumberFields():
1880
+ k_degree = k.relative_degree()
1881
+ else:
1882
+ k_degree = k.degree()
1883
+ different_degree = self.different().degree() # must be even
1884
+ return Integer(different_degree // 2 - self.degree() / k_degree) + 1
1885
+
1886
+ def residue_field(self, place, name=None):
1887
+ """
1888
+ Return the residue field associated with the place along with the maps
1889
+ from and to the residue field.
1890
+
1891
+ INPUT:
1892
+
1893
+ - ``place`` -- place of the function field
1894
+
1895
+ - ``name`` -- string; name of the generator of the residue field
1896
+
1897
+ The domain of the map to the residue field is the discrete valuation
1898
+ ring associated with the place.
1899
+
1900
+ The discrete valuation ring is defined as the ring of all elements of
1901
+ the function field with nonnegative valuation at the place. The maximal
1902
+ ideal is the set of elements of positive valuation. The residue field
1903
+ is then the quotient of the discrete valuation ring by its maximal
1904
+ ideal.
1905
+
1906
+ If an element not in the valuation ring is applied to the map, an
1907
+ exception :exc:`TypeError` is raised.
1908
+
1909
+ EXAMPLES::
1910
+
1911
+ sage: # needs sage.rings.finite_rings
1912
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
1913
+ sage: L.<y> = K.extension(Y^2 + Y + x + 1/x)
1914
+ sage: p = L.places_finite()[0]
1915
+ sage: R, fr_R, to_R = L.residue_field(p)
1916
+ sage: R
1917
+ Finite Field of size 2
1918
+ sage: f = 1 + y
1919
+ sage: f.valuation(p)
1920
+ -1
1921
+ sage: to_R(f)
1922
+ Traceback (most recent call last):
1923
+ ...
1924
+ TypeError: ...
1925
+ sage: (1+1/f).valuation(p)
1926
+ 0
1927
+ sage: to_R(1 + 1/f)
1928
+ 1
1929
+ sage: [fr_R(e) for e in R]
1930
+ [0, 1]
1931
+ """
1932
+ return place.residue_field(name=name)
1933
+
1934
+ def places_infinite(self, degree=1):
1935
+ """
1936
+ Return a list of the infinite places with ``degree``.
1937
+
1938
+ INPUT:
1939
+
1940
+ - ``degree`` -- positive integer (default: `1`)
1941
+
1942
+ EXAMPLES::
1943
+
1944
+ sage: # needs sage.rings.finite_rings
1945
+ sage: F.<a> = GF(2)
1946
+ sage: K.<x> = FunctionField(F)
1947
+ sage: R.<t> = PolynomialRing(K)
1948
+ sage: L.<y> = K.extension(t^4 + t - x^5)
1949
+ sage: L.places_infinite(1)
1950
+ [Place (1/x, 1/x^4*y^3)]
1951
+ """
1952
+ return list(self._places_infinite(degree))
1953
+
1954
+ def _places_infinite(self, degree):
1955
+ """
1956
+ Return a generator of *infinite* places with ``degree``.
1957
+
1958
+ INPUT:
1959
+
1960
+ - ``degree`` -- positive integer
1961
+
1962
+ EXAMPLES::
1963
+
1964
+ sage: # needs sage.rings.finite_rings
1965
+ sage: F.<a> = GF(2)
1966
+ sage: K.<x> = FunctionField(F)
1967
+ sage: R.<t> = PolynomialRing(K)
1968
+ sage: L.<y> = K.extension(t^4 + t - x^5)
1969
+ sage: L._places_infinite(1)
1970
+ <generator object ...>
1971
+ """
1972
+ Oinf = self.maximal_order_infinite()
1973
+ for prime, _, _ in Oinf.decomposition():
1974
+ place = prime.place()
1975
+ if place.degree() == degree:
1976
+ yield place
1977
+
1978
+
1979
+ class FunctionField_char_zero(FunctionField_simple):
1980
+ """
1981
+ Function fields of characteristic zero.
1982
+
1983
+ EXAMPLES::
1984
+
1985
+ sage: K.<x> = FunctionField(QQ); _.<Y> = K[]
1986
+ sage: L.<y> = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2))
1987
+ sage: L
1988
+ Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2)
1989
+ sage: L.characteristic()
1990
+ 0
1991
+ """
1992
+ @cached_method
1993
+ def higher_derivation(self):
1994
+ """
1995
+ Return the higher derivation (also called the Hasse-Schmidt derivation)
1996
+ for the function field.
1997
+
1998
+ The higher derivation of the function field is uniquely determined with
1999
+ respect to the separating element `x` of the base rational function
2000
+ field `k(x)`.
2001
+
2002
+ EXAMPLES::
2003
+
2004
+ sage: K.<x> = FunctionField(QQ); _.<Y> = K[]
2005
+ sage: L.<y> = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2))
2006
+ sage: L.higher_derivation() # needs sage.modules
2007
+ Higher derivation map:
2008
+ From: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2)
2009
+ To: Function field in y defined by y^3 + (-x^3 + 1)/(x^3 - 2)
2010
+ """
2011
+ from .derivations_polymod import FunctionFieldHigherDerivation_char_zero
2012
+ return FunctionFieldHigherDerivation_char_zero(self)
2013
+
2014
+
2015
+ class FunctionField_global(FunctionField_simple):
2016
+ """
2017
+ Global function fields.
2018
+
2019
+ INPUT:
2020
+
2021
+ - ``polynomial`` -- monic irreducible and separable polynomial
2022
+
2023
+ - ``names`` -- name of the generator of the function field
2024
+
2025
+ EXAMPLES::
2026
+
2027
+ sage: K.<x> = FunctionField(GF(5)); _.<Y> = K[] # needs sage.rings.finite_rings
2028
+ sage: L.<y> = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # needs sage.rings.finite_rings
2029
+ sage: L # needs sage.rings.finite_rings
2030
+ Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3)
2031
+
2032
+ The defining equation needs not be monic::
2033
+
2034
+ sage: K.<x> = FunctionField(GF(4)); _.<Y> = K[] # needs sage.rings.finite_rings
2035
+ sage: L.<y> = K.extension((1 - x)*Y^7 - x^3) # needs sage.rings.finite_rings
2036
+ sage: L.gaps() # long time (6s) # needs sage.rings.finite_rings
2037
+ [1, 2, 3]
2038
+
2039
+ or may define a trivial extension::
2040
+
2041
+ sage: K.<x> = FunctionField(GF(5)); _.<Y> = K[] # needs sage.rings.finite_rings
2042
+ sage: L.<y> = K.extension(Y-1) # needs sage.rings.finite_rings
2043
+ sage: L.genus() # needs sage.rings.finite_rings
2044
+ 0
2045
+ """
2046
+ _differentials_space = LazyImport('sage.rings.function_field.differential', 'DifferentialsSpace_global')
2047
+
2048
+ def __init__(self, polynomial, names):
2049
+ """
2050
+ Initialize.
2051
+
2052
+ TESTS::
2053
+
2054
+ sage: K.<x> = FunctionField(GF(5)); _.<Y> = K[] # needs sage.rings.finite_rings
2055
+ sage: L.<y> = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # needs sage.rings.finite_rings
2056
+ sage: TestSuite(L).run() # long time (7s) # needs sage.rings.finite_rings
2057
+ """
2058
+ FunctionField_polymod.__init__(self, polynomial, names)
2059
+
2060
+ def maximal_order(self):
2061
+ """
2062
+ Return the maximal order of the function field.
2063
+
2064
+ EXAMPLES::
2065
+
2066
+ sage: # needs sage.rings.finite_rings
2067
+ sage: K.<x> = FunctionField(GF(2))
2068
+ sage: R.<t> = PolynomialRing(K)
2069
+ sage: F.<y> = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18)
2070
+ sage: O = F.maximal_order()
2071
+ sage: O.basis()
2072
+ (1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y)
2073
+ """
2074
+ from .order_polymod import FunctionFieldMaximalOrder_global
2075
+ return FunctionFieldMaximalOrder_global(self)
2076
+
2077
+ @cached_method
2078
+ def higher_derivation(self):
2079
+ """
2080
+ Return the higher derivation (also called the Hasse-Schmidt derivation)
2081
+ for the function field.
2082
+
2083
+ The higher derivation of the function field is uniquely determined with
2084
+ respect to the separating element `x` of the base rational function
2085
+ field `k(x)`.
2086
+
2087
+ EXAMPLES::
2088
+
2089
+ sage: K.<x> = FunctionField(GF(5)); _.<Y> = K[] # needs sage.rings.finite_rings
2090
+ sage: L.<y> = K.extension(Y^3 - (x^3 - 1)/(x^3 - 2)) # needs sage.rings.finite_rings
2091
+ sage: L.higher_derivation() # needs sage.modules sage.rings.finite_rings
2092
+ Higher derivation map:
2093
+ From: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3)
2094
+ To: Function field in y defined by y^3 + (4*x^3 + 1)/(x^3 + 3)
2095
+ """
2096
+ from .derivations_polymod import FunctionFieldHigherDerivation_global
2097
+ return FunctionFieldHigherDerivation_global(self)
2098
+
2099
+ def get_place(self, degree):
2100
+ """
2101
+ Return a place of ``degree``.
2102
+
2103
+ INPUT:
2104
+
2105
+ - ``degree`` -- positive integer
2106
+
2107
+ OUTPUT: a place of ``degree`` if any exists; otherwise ``None``
2108
+
2109
+ EXAMPLES::
2110
+
2111
+ sage: # needs sage.rings.finite_rings
2112
+ sage: F.<a> = GF(2)
2113
+ sage: K.<x> = FunctionField(F)
2114
+ sage: R.<Y> = PolynomialRing(K)
2115
+ sage: L.<y> = K.extension(Y^4 + Y - x^5)
2116
+ sage: L.get_place(1)
2117
+ Place (x, y)
2118
+ sage: L.get_place(2)
2119
+ Place (x, y^2 + y + 1)
2120
+ sage: L.get_place(3)
2121
+ Place (x^3 + x^2 + 1, y + x^2 + x)
2122
+ sage: L.get_place(4)
2123
+ Place (x + 1, x^5 + 1)
2124
+ sage: L.get_place(5)
2125
+ Place (x^5 + x^3 + x^2 + x + 1, y + x^4 + 1)
2126
+ sage: L.get_place(6)
2127
+ Place (x^3 + x^2 + 1, y^2 + y + x^2)
2128
+ sage: L.get_place(7)
2129
+ Place (x^7 + x + 1, y + x^6 + x^5 + x^4 + x^3 + x)
2130
+ sage: L.get_place(8)
2131
+ """
2132
+ for p in self._places_finite(degree):
2133
+ return p
2134
+
2135
+ for p in self._places_infinite(degree):
2136
+ return p
2137
+
2138
+ return None
2139
+
2140
+ def places(self, degree=1):
2141
+ """
2142
+ Return a list of the places with ``degree``.
2143
+
2144
+ INPUT:
2145
+
2146
+ - ``degree`` -- positive integer (default: `1`)
2147
+
2148
+ EXAMPLES::
2149
+
2150
+ sage: # needs sage.rings.finite_rings
2151
+ sage: F.<a> = GF(2)
2152
+ sage: K.<x> = FunctionField(F)
2153
+ sage: R.<t> = PolynomialRing(K)
2154
+ sage: L.<y> = K.extension(t^4 + t - x^5)
2155
+ sage: L.places(1)
2156
+ [Place (1/x, 1/x^4*y^3), Place (x, y), Place (x, y + 1)]
2157
+ """
2158
+ return self.places_infinite(degree) + self.places_finite(degree)
2159
+
2160
+ def places_finite(self, degree=1):
2161
+ """
2162
+ Return a list of the finite places with ``degree``.
2163
+
2164
+ INPUT:
2165
+
2166
+ - ``degree`` -- positive integer (default: `1`)
2167
+
2168
+ EXAMPLES::
2169
+
2170
+ sage: # needs sage.rings.finite_rings
2171
+ sage: F.<a> = GF(2)
2172
+ sage: K.<x> = FunctionField(F)
2173
+ sage: R.<t> = PolynomialRing(K)
2174
+ sage: L.<y> = K.extension(t^4 + t - x^5)
2175
+ sage: L.places_finite(1)
2176
+ [Place (x, y), Place (x, y + 1)]
2177
+ """
2178
+ return list(self._places_finite(degree))
2179
+
2180
+ def _places_finite(self, degree):
2181
+ """
2182
+ Return a generator of finite places with ``degree``.
2183
+
2184
+ INPUT:
2185
+
2186
+ - ``degree`` -- positive integer
2187
+
2188
+ EXAMPLES::
2189
+
2190
+ sage: # needs sage.rings.finite_rings
2191
+ sage: F.<a> = GF(2)
2192
+ sage: K.<x> = FunctionField(F)
2193
+ sage: R.<t> = PolynomialRing(K)
2194
+ sage: L.<y> = K.extension(t^4 + t - x^5)
2195
+ sage: L._places_finite(1)
2196
+ <generator object ...>
2197
+ """
2198
+ O = self.maximal_order()
2199
+ K = self.base_field()
2200
+
2201
+ degree = Integer(degree)
2202
+
2203
+ for d in degree.divisors():
2204
+ for p in K._places_finite(degree=d):
2205
+ for prime, _, _ in O.decomposition(p.prime_ideal()):
2206
+ place = prime.place()
2207
+ if place.degree() == degree:
2208
+ yield place
2209
+
2210
+ def gaps(self):
2211
+ """
2212
+ Return the gaps of the function field.
2213
+
2214
+ These are the gaps at the ordinary places, that is, places which are
2215
+ not Weierstrass places.
2216
+
2217
+ EXAMPLES::
2218
+
2219
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[] # needs sage.rings.finite_rings
2220
+ sage: L.<y> = K.extension(Y^3 + x^3 * Y + x) # needs sage.rings.finite_rings
2221
+ sage: L.gaps() # needs sage.modules sage.rings.finite_rings
2222
+ [1, 2, 3]
2223
+ """
2224
+ return self._weierstrass_places()[1]
2225
+
2226
+ def weierstrass_places(self):
2227
+ """
2228
+ Return all Weierstrass places of the function field.
2229
+
2230
+ EXAMPLES::
2231
+
2232
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[] # needs sage.rings.finite_rings
2233
+ sage: L.<y> = K.extension(Y^3 + x^3 * Y + x) # needs sage.rings.finite_rings
2234
+ sage: L.weierstrass_places() # needs sage.modules sage.rings.finite_rings
2235
+ [Place (1/x, 1/x^3*y^2 + 1/x),
2236
+ Place (1/x, 1/x^3*y^2 + 1/x^2*y + 1),
2237
+ Place (x, y),
2238
+ Place (x + 1, (x^3 + 1)*y + x + 1),
2239
+ Place (x^3 + x + 1, y + 1),
2240
+ Place (x^3 + x + 1, y + x^2),
2241
+ Place (x^3 + x + 1, y + x^2 + 1),
2242
+ Place (x^3 + x^2 + 1, y + x),
2243
+ Place (x^3 + x^2 + 1, y + x^2 + 1),
2244
+ Place (x^3 + x^2 + 1, y + x^2 + x + 1)]
2245
+ """
2246
+ return self._weierstrass_places()[0].support()
2247
+
2248
+ @cached_method
2249
+ def _weierstrass_places(self):
2250
+ """
2251
+ Return the Weierstrass places together with the gap sequence for
2252
+ ordinary places.
2253
+
2254
+ EXAMPLES::
2255
+
2256
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[] # needs sage.rings.finite_rings
2257
+ sage: L.<y> = K.extension(Y^3 + x^3 * Y + x) # needs sage.rings.finite_rings
2258
+ sage: len(L.weierstrass_places()) # indirect doctest # needs sage.modules sage.rings.finite_rings
2259
+ 10
2260
+
2261
+ This method implements Algorithm 30 in [Hes2002b]_.
2262
+ """
2263
+ from sage.matrix.constructor import matrix
2264
+ from sage.modules.free_module_element import vector
2265
+
2266
+ W = self(self.base_field().gen()).differential().divisor()
2267
+ basis = W._basis()
2268
+
2269
+ if not basis:
2270
+ return [], []
2271
+ d = len(basis)
2272
+
2273
+ der = self.higher_derivation()
2274
+ M = matrix([basis])
2275
+ e = 1
2276
+ gaps = [1]
2277
+ while M.nrows() < d:
2278
+ row = vector([der._derive(basis[i], e) for i in range(d)])
2279
+ if row not in M.row_space():
2280
+ M = matrix(M.rows() + [row])
2281
+ gaps.append(e + 1)
2282
+ e += 1
2283
+
2284
+ # This is faster than M.determinant(). Note that Mx
2285
+ # is a matrix over univariate polynomial ring.
2286
+ Mx = matrix(M.nrows(), [c._x for c in M.list()])
2287
+ detM = self(Mx.determinant() % self._polynomial)
2288
+
2289
+ R = detM.divisor() + sum(gaps)*W # ramification divisor
2290
+
2291
+ return R, gaps
2292
+
2293
+ @cached_method
2294
+ def L_polynomial(self, name='t'):
2295
+ """
2296
+ Return the L-polynomial of the function field.
2297
+
2298
+ INPUT:
2299
+
2300
+ - ``name`` -- (default: ``t``) name of the variable of the polynomial
2301
+
2302
+ EXAMPLES::
2303
+
2304
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[] # needs sage.rings.finite_rings
2305
+ sage: F.<y> = K.extension(Y^2 + Y + x + 1/x) # needs sage.rings.finite_rings
2306
+ sage: F.L_polynomial() # needs sage.rings.finite_rings
2307
+ 2*t^2 + t + 1
2308
+ """
2309
+ from sage.rings.integer_ring import ZZ
2310
+ q = self.constant_field().order()
2311
+ g = self.genus()
2312
+
2313
+ B = [len(self.places(i+1)) for i in range(g)]
2314
+ N = [sum(d * B[d-1] for d in ZZ(i+1).divisors()) for i in range(g)]
2315
+ S = [N[i] - q**(i+1) - 1 for i in range(g)]
2316
+
2317
+ a = [1]
2318
+ for i in range(1, g+1):
2319
+ a.append(sum(S[j] * a[i-j-1] for j in range(i)) / i)
2320
+ for j in range(1, g+1):
2321
+ a.append(q**j * a[g-j])
2322
+
2323
+ return ZZ[name](a)
2324
+
2325
+ def number_of_rational_places(self, r=1):
2326
+ """
2327
+ Return the number of rational places of the function field whose
2328
+ constant field extended by degree ``r``.
2329
+
2330
+ INPUT:
2331
+
2332
+ - ``r`` -- positive integer (default: `1`)
2333
+
2334
+ EXAMPLES::
2335
+
2336
+ sage: # needs sage.rings.finite_rings
2337
+ sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
2338
+ sage: F.<y> = K.extension(Y^2 + Y + x + 1/x)
2339
+ sage: F.number_of_rational_places()
2340
+ 4
2341
+ sage: [F.number_of_rational_places(r) for r in [1..10]]
2342
+ [4, 8, 4, 16, 44, 56, 116, 288, 508, 968]
2343
+ """
2344
+ from sage.rings.integer_ring import IntegerRing
2345
+
2346
+ q = self.constant_field().order()
2347
+ L = self.L_polynomial()
2348
+ Lp = L.derivative()
2349
+
2350
+ R = IntegerRing()[[L.parent().gen()]] # power series ring
2351
+
2352
+ f = R(Lp / L, prec=r)
2353
+ n = f[r-1] + q**r + 1
2354
+
2355
+ return n
2356
+
2357
+
2358
+ @handle_AA_and_QQbar
2359
+ def _singular_normal(ideal):
2360
+ r"""
2361
+ Compute the normalization of the affine algebra defined by ``ideal`` using
2362
+ Singular.
2363
+
2364
+ The affine algebra is the quotient algebra of a multivariate polynomial
2365
+ ring `R` by the ideal. The normalization is by definition the integral
2366
+ closure of the algebra in its total ring of fractions.
2367
+
2368
+ INPUT:
2369
+
2370
+ - ``ideal`` -- a radical ideal in a multivariate polynomial ring
2371
+
2372
+ OUTPUT:
2373
+
2374
+ a list of lists, one list for each ideal in the equidimensional
2375
+ decomposition of the ``ideal``, each list giving a set of generators of the
2376
+ normalization of each ideal as an R-module by dividing all elements of the
2377
+ list by the final element. Thus the list ``[x, y]`` means that `\{x/y, 1\}`
2378
+ is the set of generators of the normalization of `R/(x,y)`.
2379
+
2380
+ ALGORITHM:
2381
+
2382
+ Singular's implementation of the normalization algorithm described in G.-M.
2383
+ Greuel, S. Laplagne, F. Seelisch: Normalization of Rings (2009).
2384
+
2385
+ EXAMPLES::
2386
+
2387
+ sage: from sage.rings.function_field.function_field_polymod import _singular_normal
2388
+ sage: R.<x,y> = QQ[]
2389
+
2390
+ sage: f = (x^2 - y^3) * x
2391
+ sage: _singular_normal(ideal(f))
2392
+ [[x, y], [1]]
2393
+
2394
+ sage: f = y^2 - x
2395
+ sage: _singular_normal(ideal(f))
2396
+ [[1]]
2397
+ """
2398
+ from sage.libs.singular.function import (singular_function,
2399
+ lib as singular_lib,
2400
+ get_printlevel, set_printlevel)
2401
+ singular_lib('normal.lib')
2402
+ normal = singular_function('normal')
2403
+
2404
+ # verbose unless printlevel is -1.
2405
+ saved_printlevel = get_printlevel()
2406
+ set_printlevel(-1)
2407
+ nor = normal(ideal)
2408
+ set_printlevel(saved_printlevel)
2409
+
2410
+ return nor[1]
2411
+
2412
+
2413
+ class FunctionField_integral(FunctionField_simple):
2414
+ """
2415
+ Integral function fields.
2416
+
2417
+ A function field is integral if it is defined by an irreducible separable
2418
+ polynomial, which is integral over the maximal order of the base rational
2419
+ function field.
2420
+ """
2421
+ def _maximal_order_basis(self):
2422
+ """
2423
+ Return a basis of the maximal order of the function field.
2424
+
2425
+ EXAMPLES::
2426
+
2427
+ sage: # needs sage.rings.finite_rings
2428
+ sage: K.<x> = FunctionField(GF(2))
2429
+ sage: R.<t> = PolynomialRing(K)
2430
+ sage: F.<y> = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18)
2431
+ sage: F._maximal_order_basis()
2432
+ [1, 1/x^4*y, 1/x^11*y^2 + 1/x^2, 1/x^15*y^3 + 1/x^6*y]
2433
+
2434
+ The basis of the maximal order *always* starts with 1. This is assumed
2435
+ in some algorithms.
2436
+ """
2437
+ from sage.matrix.constructor import matrix
2438
+ from .hermite_form_polynomial import reversed_hermite_form
2439
+
2440
+ k = self.constant_base_field()
2441
+ K = self.base_field() # rational function field
2442
+ n = self.degree()
2443
+
2444
+ # Construct the defining polynomial of the function field as a
2445
+ # two-variate polynomial g in the ring k[y,x] where k is the constant
2446
+ # base field.
2447
+ S, (y, x) = PolynomialRing(k, names='y,x', order='lex').objgens()
2448
+ v = self.polynomial().list()
2449
+ g = sum([v[i].numerator().subs(x) * y**i for i in range(len(v))])
2450
+
2451
+ if self.is_global():
2452
+ from sage.libs.singular.function import singular_function, lib
2453
+ from sage.env import SAGE_EXTCODE
2454
+ lib(SAGE_EXTCODE + '/singular/function_field/core.lib')
2455
+ normalize = singular_function('core_normalize')
2456
+
2457
+ # Singular "normalP" algorithm assumes affine domain over
2458
+ # a prime field. So we construct gflat lifting g as in
2459
+ # k_prime[yy,xx,zz]/(k_poly) where k = k_prime[zz]/(k_poly)
2460
+ R = PolynomialRing(k.prime_subfield(), names='yy,xx,zz')
2461
+ gflat = R.zero()
2462
+ for m in g.monomials():
2463
+ c = g.monomial_coefficient(m).polynomial('zz')
2464
+ gflat += R(c) * R(m) # R(m) is a monomial in yy and xx
2465
+
2466
+ k_poly = R(k.polynomial('zz'))
2467
+
2468
+ # invoke Singular
2469
+ pols_in_R = normalize(R.ideal([k_poly, gflat]))
2470
+
2471
+ # reconstruct polynomials in S
2472
+ h = R.hom([y, x, k.gen()], S)
2473
+ pols_in_S = [h(f) for f in pols_in_R]
2474
+ else:
2475
+ # Call Singular. Singular's "normal" function returns a basis
2476
+ # of the integral closure of k(x,y)/(g) as a k[x,y]-module.
2477
+ pols_in_S = _singular_normal(S.ideal(g))[0]
2478
+
2479
+ # reconstruct the polynomials in the function field
2480
+ x = K.gen()
2481
+ y = self.gen()
2482
+ pols = []
2483
+ for f in pols_in_S:
2484
+ p = f.polynomial(S.gen(0))
2485
+ s = 0
2486
+ for i in range(p.degree()+1):
2487
+ s += p[i].subs(x) * y**i
2488
+ pols.append(s)
2489
+
2490
+ # Now if pols = [g1,g2,...gn,g0], then the g1/g0,g2/g0,...,gn/g0,
2491
+ # and g0/g0=1 are the module generators of the integral closure
2492
+ # of the equation order Sb = k[xb,yb] in its fraction field,
2493
+ # that is, the function field. The integral closure of k[x]
2494
+ # is then obtained by multiplying these generators with powers of y
2495
+ # as the equation order itself is an integral extension of k[x].
2496
+ d = ~ pols[-1]
2497
+ _basis = []
2498
+ for f in pols:
2499
+ b = d * f
2500
+ for i in range(n):
2501
+ _basis.append(b)
2502
+ b *= y
2503
+
2504
+ # Finally we reduce _basis to get a basis over k[x]. This is done of
2505
+ # course by Hermite normal form computation. Here we apply a trick to
2506
+ # get a basis that starts with 1 and is ordered in increasing
2507
+ # y-degrees. The trick is to use the reversed Hermite normal form.
2508
+ # Note that it is important that the overall denominator l lies in k[x].
2509
+ V, fr_V, to_V = self.free_module()
2510
+ basis_V = [to_V(bvec) for bvec in _basis]
2511
+ l = lcm([vvec.denominator() for vvec in basis_V])
2512
+
2513
+ _mat = matrix([[coeff.numerator() for coeff in l*v] for v in basis_V])
2514
+ reversed_hermite_form(_mat)
2515
+
2516
+ basis = [fr_V(v) / l for v in _mat if not v.is_zero()]
2517
+ return basis
2518
+
2519
+ @cached_method
2520
+ def equation_order(self):
2521
+ """
2522
+ Return the equation order of the function field.
2523
+
2524
+ EXAMPLES::
2525
+
2526
+ sage: K.<x> = FunctionField(GF(2)); R.<t> = PolynomialRing(K) # needs sage.rings.finite_rings
2527
+ sage: F.<y> = K.extension(t^3 - x^2*(x^2+x+1)^2) # needs sage.rings.finite_rings
2528
+ sage: F.equation_order() # needs sage.rings.finite_rings
2529
+ Order in Function field in y defined by y^3 + x^6 + x^4 + x^2
2530
+
2531
+ sage: K.<x> = FunctionField(QQ); R.<t> = PolynomialRing(K)
2532
+ sage: F.<y> = K.extension(t^3 - x^2*(x^2+x+1)^2)
2533
+ sage: F.equation_order()
2534
+ Order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2
2535
+ """
2536
+ from .order_basis import FunctionFieldOrder_basis
2537
+ a = self.gen()
2538
+ basis = [a**i for i in range(self.degree())]
2539
+ return FunctionFieldOrder_basis(tuple(basis))
2540
+
2541
+ @cached_method
2542
+ def primitive_integal_element_infinite(self):
2543
+ """
2544
+ Return a primitive integral element over the base maximal infinite order.
2545
+
2546
+ This element is integral over the maximal infinite order of the base
2547
+ rational function field and the function field is a simple extension by
2548
+ this element over the base order.
2549
+
2550
+ EXAMPLES::
2551
+
2552
+ sage: # needs sage.rings.finite_rings
2553
+ sage: K.<x> = FunctionField(GF(2)); R.<t> = PolynomialRing(K)
2554
+ sage: F.<y> = K.extension(t^3 - x^2*(x^2+x+1)^2)
2555
+ sage: b = F.primitive_integal_element_infinite(); b
2556
+ 1/x^2*y
2557
+ sage: b.minimal_polynomial('t')
2558
+ t^3 + (x^4 + x^2 + 1)/x^4
2559
+ """
2560
+ f = self.polynomial()
2561
+ n = f.degree()
2562
+ y = self.gen()
2563
+ x = self.base_field().gen()
2564
+
2565
+ cf = max([(f[i].numerator().degree()/(n-i)).ceil() for i in range(n)
2566
+ if f[i] != 0])
2567
+ return y*x**(-cf)
2568
+
2569
+ @cached_method
2570
+ def equation_order_infinite(self):
2571
+ """
2572
+ Return the infinite equation order of the function field.
2573
+
2574
+ This is by definition `o[b]` where `b` is the primitive integral
2575
+ element from :meth:`primitive_integal_element_infinite()` and `o` is
2576
+ the maximal infinite order of the base rational function field.
2577
+
2578
+ EXAMPLES::
2579
+
2580
+ sage: K.<x> = FunctionField(GF(2)); R.<t> = PolynomialRing(K) # needs sage.rings.finite_rings
2581
+ sage: F.<y> = K.extension(t^3 - x^2*(x^2+x+1)^2) # needs sage.rings.finite_rings
2582
+ sage: F.equation_order_infinite() # needs sage.rings.finite_rings
2583
+ Infinite order in Function field in y defined by y^3 + x^6 + x^4 + x^2
2584
+
2585
+ sage: K.<x> = FunctionField(QQ); R.<t> = PolynomialRing(K)
2586
+ sage: F.<y> = K.extension(t^3 - x^2*(x^2+x+1)^2)
2587
+ sage: F.equation_order_infinite()
2588
+ Infinite order in Function field in y defined by y^3 - x^6 - 2*x^5 - 3*x^4 - 2*x^3 - x^2
2589
+ """
2590
+ from .order_basis import FunctionFieldOrderInfinite_basis
2591
+ b = self.primitive_integal_element_infinite()
2592
+ basis = [b**i for i in range(self.degree())]
2593
+ return FunctionFieldOrderInfinite_basis(tuple(basis))
2594
+
2595
+
2596
+ class FunctionField_char_zero_integral(FunctionField_char_zero, FunctionField_integral):
2597
+ """
2598
+ Function fields of characteristic zero, defined by an irreducible and
2599
+ separable polynomial, integral over the maximal order of the base rational
2600
+ function field with a finite constant field.
2601
+ """
2602
+ pass
2603
+
2604
+
2605
+ class FunctionField_global_integral(FunctionField_global, FunctionField_integral):
2606
+ """
2607
+ Global function fields, defined by an irreducible and separable polynomial,
2608
+ integral over the maximal order of the base rational function field with a
2609
+ finite constant field.
2610
+ """
2611
+ pass