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,3110 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+ version="version paraplanecurves.lib 4.4.0.0 Nov_2023 "; // $Id: b589715939cb7e23849243fe086de95d939e3b98 $
3
+ category="Algebraic Geometry";
4
+ info="
5
+ LIBRARY: paraplanecurves.lib Rational parametrization of rational plane curves
6
+
7
+ AUTHORS: J. Boehm, boehm at mathematik.uni-kl.de @*
8
+ W. Decker, decker at mathematik.uni-kl.de @*
9
+ S. Laplagne, slaplagn at dm.uba.ar @*
10
+ F. Seelisch, seelisch at mathematik.uni-kl.de
11
+
12
+ OVERVIEW:
13
+
14
+ Suppose C = {f(x,y,z)=0} is a rational plane curve, where f is homogeneous
15
+ of degree n with coefficients in Q and absolutely irreducible (these
16
+ conditions are checked automatically.) @*
17
+ After a first step, realized by a projective automorphism in the procedure
18
+ adjointIdeal, C satisfies: @*
19
+ - C does not have singularities at infinity z=0. @*
20
+ - C does not contain the point (0:1:0) (that is, the dehomogenization of f
21
+ with respect to z is monic as a polynomial in y). @*
22
+ Considering C in the chart z<>0, the algorithm regards x as transcendental
23
+ and y as algebraic and computes an integral basis in C(x)[y] of the integral
24
+ closure of C[x] in C(x,y) using the normalization algorithm from
25
+ @ref{normal_lib}: see @ref{integralbasis_lib}. In a future edition of the
26
+ library, also van Hoeij's algorithm for computing the integral basis will
27
+ be available. @*
28
+ From the integral basis, the adjoint ideal is obtained by linear algebra.
29
+ Alternatively, the algorithm starts with a local analysis of the singular
30
+ locus of C. Then, for each primary component of the singular locus which
31
+ does not correspond to ordinary multiple points or cusps, the integral
32
+ basis algorithm is applied separately. The ordinary multiple points and
33
+ cusps, in turn, are addressed by a straightforward direct algorithm. The
34
+ adjoint ideal is obtained by intersecting all ideals obtained locally.
35
+ The local variant of the algorithm is used by default. @*
36
+ The linear system corresponding to the adjoint ideal maps the curve
37
+ birationally to a rational normal curve in P^(n-2). @*
38
+ Iterating the anticanonical map, the algorithm projects the rational normal
39
+ curve to PP1 for n odd resp. to a conic C2 in PP2 for n even. @*
40
+ In case n is even, the algorithm tests whether there is a rational point on
41
+ C2 and if so gives a parametrization of C2 which is defined over Q. Otherwise,
42
+ the parametrization given is defined over a quadratic field extension of Q. @*
43
+ By inverting the birational map of C to PP1 resp. to C2, a parametrization
44
+ of C is obtained (defined over Q or the quadratic field extension).
45
+
46
+ REFERENCES:
47
+
48
+ Janko Boehm: Parametrisierung rationaler Kurven, Diploma Thesis,
49
+ http://www.math.uni-sb.de/ag/schreyer/jb/diplom%20janko%20boehm.pdf
50
+
51
+ Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister:
52
+ Local to global algorithms for the Gorenstein adjoint ideal of a curve,
53
+ Algorithmic and Experimental Methods in Algebra, Geometry, and Number Theory, Springer 2018
54
+
55
+ Theo de Jong: An algorithm for computing the integral closure,
56
+ Journal of Symbolic Computation 26 (3) (1998), p. 273-277
57
+
58
+ Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings,
59
+ Journal of Symbolic Computation 9 (2010), p. 887-901
60
+
61
+ Mark van Hoeij: An Algorithm for Computing an Integral Basis in an Algebraic
62
+ Function Field, Journal of Symbolic Computation 18 (1994), p. 353-363,
63
+ http://www.math.fsu.edu/~hoeij/papers/comments/jsc1994.html
64
+
65
+
66
+ KEYWORDS:
67
+ Curves; Parametrization; Rational curves; Adjoint ideal; Geometric genus
68
+
69
+
70
+ PROCEDURES:
71
+
72
+ adjointIdeal(poly, [...]); Adjoint ideal of a plane curve
73
+ invertBirMap(ideal,ideal); Invert a birational map of algebraic
74
+ varieties
75
+ paraPlaneCurve(poly, [...]); Compute a rational parametrization of a
76
+ rational plane curve
77
+ rncAntiCanonicalMap(ideal); Anticanonical map of a rational normal curve
78
+ rationalPointConic(poly); Finds a point on the conic. This point has
79
+ either coefficients in Q or in a quadratic
80
+ extension field of Q
81
+ mapToRatNormCurve(poly,ideal); Map a plane rational curve to a rational
82
+ normal curve (RNC)
83
+ rncItProjOdd(ideal); Map a RNC via successive anticanonical maps
84
+ to PP1
85
+ rncItProjEven(ideal); Map a RNC via successive anticanonical maps
86
+ to a conic in PP2
87
+ paraConic(poly); Compute a rational parametrization of a conic
88
+ testParametrization(poly,ring); Checks whether a given curve is parametrized
89
+ by a given rational map (defined in the
90
+ given ring)
91
+ testPointConic(poly,ring); Checks whether a given point (defined in the
92
+ given ring) lies on the given conic.
93
+ ";
94
+
95
+ LIB "elim.lib";
96
+ LIB "general.lib";
97
+ LIB "primdec.lib";
98
+ LIB "absfact.lib";
99
+ LIB "matrix.lib";
100
+ LIB "random.lib";
101
+ LIB "homolog.lib";
102
+ LIB "integralbasis.lib";
103
+ LIB "normal.lib";
104
+
105
+
106
+ ///////////////////////////////////////////////////////////////////////////////
107
+ proc invertBirMap(ideal phi, ideal I)
108
+ "USAGE: invertBirMap(phi, I); phi ideal, I ideal
109
+ ASSUME: The ideal phi in the basering R represents a birational map of the
110
+ variety given by the ideal I in R to its image in projective space
111
+ P = PP^(size(phi)-1).
112
+ NOTE: The procedure might fail or give a wrong output if phi does
113
+ not define a birational map.
114
+ RETURN: ring, the coordinate ring of P, with an ideal named J and an ideal
115
+ named psi.@*
116
+ The ideal J defines the image of phi.@*
117
+ The ideal psi gives the inverse of phi.@*
118
+ Note that the entries of psi should be considered as representatives
119
+ of classes in the quotient ring R/J.@*
120
+ THEORY: We compute the ideal I(G) in R**S of the graph G of phi.@*
121
+ The ideal J is given by the intersection of I(G) with S.@*
122
+ The map psi is given by a relation mod J of those relations
123
+ in I(G) which are linear in the variables of R.@*
124
+ KEYWORDS: birational map, image, inverse.
125
+ EXAMPLE: example invertBirMap; shows an example
126
+ "
127
+ {
128
+ def Roriginal = basering;
129
+ int n = nvars(Roriginal);
130
+ int m = size(phi);
131
+ /*phi: P^(n-1) --> P^(m-1)*/
132
+ list rl = ring_list(Roriginal);
133
+ int k;
134
+ for(k = 1; k <= n; k++)
135
+ {
136
+ rl[2][k] = "x("+string(k)+")";
137
+ }
138
+ for(k = 1; k <= m; k++)
139
+ {
140
+ rl[2][k+n] = "y("+string(k)+")";
141
+ }
142
+ rl[3]= list(list("dp",1:(n+m)),list("C",0));
143
+ /*Use Hilbert driven Buchberger*/
144
+ def Rbig0 = ring(rl);
145
+ setring Rbig0;
146
+ ideal I = fetch(Roriginal,I);
147
+ ideal phi = fetch(Roriginal,phi);
148
+ ideal mi = maxideal(1);
149
+ ideal xv = mi[1..n];
150
+ ideal yv = mi[n+1..n+m];
151
+ matrix HM[2][m] = concat(transpose(yv),transpose(phi));
152
+ ideal graph = sat(I+minor(HM,2),phi);
153
+ graph = sat(graph,xv);
154
+ bigintvec Hgraph = hilb(graph,1);
155
+ setring Roriginal;
156
+ rl[3]= list(list("dp",1:n),list("dp",1:m),list("C",0));
157
+ def Rbig = ring(rl);
158
+ setring Rbig;
159
+ ideal graph = imap(Rbig0,graph);
160
+ graph = std(graph,Hgraph);
161
+ ideal xv = imap(Rbig0,xv);
162
+ /*The ideal J defines the image of phi*/
163
+ ideal J = graph;
164
+ for(k = 1; k <= n; k++)
165
+ {
166
+ J = subst(J,xv[k],0);
167
+ }
168
+ J = compress(J);
169
+ /*now we start inverting phi to psi*/
170
+ matrix relpsi = diff(xv,graph);
171
+ for(k = 1; k <= n; k++)
172
+ {
173
+ relpsi = subst(relpsi,xv[k],0);
174
+ }
175
+ relpsi = compress(relpsi);
176
+ list rl = ring_list(Rbig);
177
+ list rl2 = rl[2];
178
+ rl[2] = list(rl2[n+1..n+m]);
179
+ rl[3]= list(list("dp",1:m),list("C",0));
180
+ def Rtarget = ring(rl);
181
+ setring Rtarget;
182
+ ideal J = imap(Rbig,J);
183
+ qring RtargetmodJ = std(J);
184
+ matrix relpsi = imap(Rbig,relpsi);
185
+ relpsi = syz(transpose(relpsi));
186
+ ideal psi = submat(relpsi,1..nrows(relpsi),1);
187
+ setring Rtarget;
188
+ ideal psi = imap(RtargetmodJ,psi);
189
+ export(J,psi);
190
+ int p = printlevel - voice + 3;
191
+ dbprint(p,"// 'invertBirMap' created a ring together with two ideals J and psi.");
192
+ dbprint(p,"// Supposing you typed, say, def RPn = invertBirMap(phi,I);");
193
+ dbprint(p,"// you may access the ideals by typing");
194
+ dbprint(p,"// setring RPn; J; psi;");
195
+ return(Rtarget);
196
+ }
197
+
198
+ example
199
+ { "EXAMPLE:"; echo=2;
200
+ ring R = 0,(x,y,z),dp;
201
+ poly f = y^8-x^3*(z+x)^5;
202
+ ideal adj = adjointIdeal(f);
203
+ def Rn = invertBirMap(adj,ideal(f));
204
+ setring(Rn);
205
+ J;
206
+ psi;
207
+ }
208
+
209
+ ///////////////////////////////////////////////////////////////////////////////
210
+ static proc checkAssumptions(poly f)
211
+ "USAGE: checkAssumptions(f); f poly
212
+ RETURN: 1 if assumptions are satisfied, 0 otherwise.@*
213
+ Assumptions checked are: basering is polynomial ring in 3 variables
214
+ with coefficients in Q, f is homogeneous and absolutely irreducible
215
+ "
216
+ {
217
+ def Roriginal = basering;
218
+ list rl = ringlist(Roriginal);
219
+ rl[3] = list(list("dp",1:3),list("C",0));
220
+ if(size(rl[1])>1){ERROR("ground field is not Q");}
221
+ if(rl[1]!=0){ERROR("ground field is not Q");}
222
+ if(nvars(Roriginal)!=3)
223
+ { ERROR("not a projective plane curve: wrong number of variables"); }
224
+ if(homog(f)==0)
225
+ { ERROR("not a projective plane curve: polynomial is not homogeneous"); }
226
+ def RP2 = ring(rl);
227
+ setring RP2;
228
+ poly f = fetch(Roriginal,f);
229
+ if(isIrreducible(f)==0){ERROR("curve is not absolutely irreducible");}
230
+ setring Roriginal;
231
+ }
232
+
233
+ ///////////////////////////////////////////////////////////////////////////////
234
+ proc paraPlaneCurve(poly f, list #)
235
+ "USAGE: paraPlaneCurve(f [, s]); f poly , s optional string@*
236
+ optional string s can be: @*
237
+ 'normal': compute integral basis via normalization. @*
238
+ 'local': make local analysis of singularities first and apply
239
+ normalization separately. @*
240
+ The default is 2. @*
241
+ ASSUME: The basering must be a polynomial ring in three variables, say x,y,z,
242
+ with coefficients in Q. @*
243
+ The polynomial f must be homogeneous and absolutely irreducible. @*
244
+ The curve C = {f = 0} must be rational, i.e., have geometric genus 0
245
+ (see @ref{genus}). @*
246
+ These conditions will be checked automatically.
247
+ RETURN: ring with an ideal PARA which contains a rational parametrization of
248
+ the rational plane curve given by f; the ground field of the returned
249
+ polynomial ring is either Q or some algebraic extension Q(a); PARA
250
+ consists of three generators that parametrize the three coordinates
251
+ of the rational curve
252
+ THEORY: After a first step, realized by a projective automorphism in the
253
+ procedure adjointIdeal, C satisfies: @*
254
+ - C does not have singularities at infinity z=0. @*
255
+ - C does not contain the point (0:1:0) (that is, the dehomogenization of f
256
+ with respect to z is monic as a polynomial in y). @*
257
+ Considering C in the chart z<>0, the algorithm regards x as transcendental
258
+ and y as algebraic and computes an integral basis in C(x)[y] of the integral
259
+ closure of C[x] in C(x,y) using the normalization algorithm from @ref{normal_lib}:
260
+ see @ref{integralbasis_lib}. In a future edition of the library, also van Hoeij's
261
+ algorithm for computing the integral basis will be available. @*
262
+ From the integral basis, the adjoint ideal is obtained by linear algebra.
263
+ Alternatively, the algorithm starts with a local analysis of the singular
264
+ locus of C. Then, for each primary component of the singular locus which
265
+ does not correspond to ordinary multiple points or cusps, the integral
266
+ basis algorithm is applied separately. The ordinary multiple points and
267
+ cusps, in turn, are addressed by a straightforward direct algorithm. The
268
+ adjoint ideal is obtained by intersecting all ideals obtained locally.
269
+ The local variant of the algorithm is used by default. @*
270
+ The linear system corresponding to the adjoint ideal maps the curve
271
+ birationally to a rational normal curve in P^(n-2). @*
272
+ Iterating the anticanonical map, the algorithm projects the rational normal
273
+ curve to PP1 for n odd resp. to a conic C2 in PP2 for n even. @*
274
+ In case n is even, the algorithm tests whether there is a rational point on C2
275
+ and if so gives a parametrization of C2 which is defined over Q. Otherwise the
276
+ parametrization is defined over a quadratic field extension of Q. @*
277
+ By inverting the birational map of C to PP1 resp. to C2, a parametrization of
278
+ C is obtained (defined over Q or the quadratic field extension).
279
+ KEYWORDS: rational curves, rational parametrization of rational curves.
280
+ EXAMPLE: example paraPlaneCurve; shows an example
281
+ "
282
+ {
283
+ int choice = 2;
284
+ if (size(#) != 0)
285
+ {
286
+ if (typeof(#[1]) == "string")
287
+ {
288
+ string s = string(#[1]);
289
+ if (s == "normal") { choice = 1; }
290
+ else
291
+ {
292
+ if (s == "local") { choice = 2; }
293
+ else { ERROR("expected optional argument to be either"
294
+ + " 'local' or 'normal'"); }
295
+ }
296
+ }
297
+ else { ERROR("expected optional argument to be a string"); }
298
+ }
299
+ def Roriginal = basering;
300
+ /*checking assumptions and handling the conic case*/
301
+ checkAssumptions(f);
302
+ list rl = ring_list(Roriginal);
303
+ rl[2] = list("x","y","z");
304
+ rl[3] = list(list("dp",1:3),list("C",0));
305
+ def RP2 = ring(rl);
306
+ setring RP2;
307
+ poly f = fetch(Roriginal,f);
308
+ int d = deg(f);
309
+ if(d==2)
310
+ {
311
+ def RP1 = paraConic(f); // (ring, PARACONIC)
312
+ setring RP1;
313
+ ideal PARA = PARACONIC;
314
+ export(PARA);
315
+ int p = printlevel - voice + 3;
316
+ dbprint(p,"// 'paraPlaneCurve' created a ring together with an ideal PARA.
317
+ // Supposing you typed, say, def RP1 = paraPlaneCurve(f);
318
+ // you may access the ideal by typing
319
+ // setring RP1; PARA;");
320
+ return(RP1);
321
+ }
322
+ int k;
323
+ /*the adjoint ideal*/
324
+ ideal AI = adjointIdeal(f,list(choice,"rattestyes/firstchecksdone"));
325
+ /*rattestyes -> causes error message if curve is not rational*/
326
+ /*firstchecksdone -> prevents that check of assumptions will be done again*/
327
+ /*mapping the curve to a rational normal curve V(RNC) in Proj(Rrnc) via AI*/
328
+ def Rrnc = mapToRatNormCurve(f, AI); // ring containing ideal RNC
329
+ setring Rrnc;
330
+ int m = d-1; // the size of AI
331
+ /*the odd dimensional case*/
332
+ if((d mod 2) == 1)
333
+ {
334
+ /*mapping the rational normal curve to P^1 creating PHI*/
335
+ ideal PHI = rncItProjOdd(RNC);
336
+ /*composing the maps AI and PHI*/
337
+ def Rbig = Rrnc + RP2;
338
+ setring Rbig;
339
+ ideal AI = imap(RP2,AI);
340
+ ideal PROJ = imap(Rrnc,PHI);
341
+ for(k = 1; k <= m; k++)
342
+ {
343
+ PROJ = subst(PROJ,var(k),AI[k]);
344
+ }
345
+ setring RP2;
346
+ ideal If = ideal(fetch(Roriginal,f));
347
+ ideal PROJ = imap(Rbig,PROJ);
348
+ /*inverting the composed map to psi*/
349
+ def rp1 = invertBirMap(PROJ,If); // ring containing ideal psi
350
+ setring rp1;
351
+ list rl1 = ring_list(rp1);
352
+ rl1[2] = list("s","t");
353
+ def RP1 = ring(rl1);
354
+ setring RP1;
355
+ ideal PARA = fetch(rp1,psi);
356
+ export(PARA);
357
+ int p = printlevel - voice + 3;
358
+ dbprint(p,"// 'paraPlaneCurve' created a ring together with an ideal PARA.
359
+ // Supposing you typed, say, def RP1 = paraPlaneCurve(f);
360
+ // you may access the ideal by typing
361
+ // setring RP1; PARA;");
362
+ return(RP1);
363
+ }
364
+ /*the even dimensional case*/
365
+ /*mapping the rational normal curve to a CONIC in P^2* creating PHI*/
366
+ def RP2conic = rncItProjEven(RNC); // exports PHI, returns ring
367
+ // containing CONIC
368
+ setring RP2conic;
369
+ /*mapping the conic to P^1 via pencil defined by Ipoint*/
370
+ def RP2conicNew = projConic(CONIC); // ring containing ideal Ipoint
371
+ // possibly defined over algebraic number field
372
+ // variables u,v,w
373
+ /*composing the maps AI and PHI and Ipoint in two steps*/
374
+ def Rbig = RP2conicNew + Rrnc;
375
+ setring Rbig;
376
+ ideal PHI = imap(Rrnc,PHI);
377
+ ideal PROJ = imap(RP2conicNew,Ipoint);
378
+ for(k = 1; k <= 3; k++)
379
+ {
380
+ PROJ = subst(PROJ,var(k),PHI[k]);
381
+ }
382
+ ideal AI = fetch(RP2,AI);
383
+ for(k = 1; k <= m; k++)
384
+ {
385
+ PROJ = subst(PROJ,var(k+3),AI[k]);
386
+ }
387
+ setring RP2conicNew;
388
+ ideal If = ideal(fetch(Roriginal,f));
389
+ ideal PROJ = imap(Rbig,PROJ);
390
+ /*inverting the composed map to psi*/
391
+ def rp1 = invertBirMap(PROJ,If); // (ring, (J,psi))
392
+ setring rp1;
393
+ list rl1 = ring_list(rp1);
394
+ rl1[2] = list("s","t");
395
+ def RP1 = ring(rl1);
396
+ setring RP1;
397
+ ideal PARA = fetch(rp1,psi);
398
+ export(PARA);
399
+ int p = printlevel - voice + 3;
400
+ dbprint(p,"// 'paraPlaneCurve' created a ring together with an ideal PARA.
401
+ // Supposing you typed, say, def RP1 = paraPlaneCurve(f);
402
+ // you may access the ideal by typing
403
+ // setring RP1; PARA;");
404
+ return(RP1);
405
+ }
406
+
407
+ example
408
+ { "EXAMPLE:"; echo=2;
409
+ ring R = 0,(x,y,z),dp;
410
+ poly f1 = 1/2*x^5+x^2*y*z^2+x^3*y*z+1/2*x*y^2*z^2-2*x*y^3*z+y^5;
411
+ def Rp1 = paraPlaneCurve(f1);
412
+ setring Rp1;
413
+ PARA;
414
+ setring R;
415
+ poly f2 = x6+3x4y2+3x2y4+y6-4x4z2-34x3yz2-7x2y2z2+12xy3z2+6y4z2;
416
+ f2 = f2+36x2z4+36xyz4+9y2z4;
417
+ def Rp2 = paraPlaneCurve(f2);
418
+ setring Rp2;
419
+ PARA;
420
+ }
421
+
422
+ ///////////////////////////////////////////////////////////////////////////////
423
+ // compute the weighted degree of p;
424
+ // this code is an exact copy of the proc in paraplanecurves.lib
425
+ // (since we do not want to make it non-static)
426
+ static proc w_deg(poly p, intvec v)
427
+ {
428
+ if(p==0){return(-1);}
429
+ int d=0;
430
+ while(jet(p,d,v)==0){d++;}
431
+ d=(transpose(leadexp(jet(p,d,v)))*v)[1];
432
+ return(d);
433
+ }
434
+
435
+ ///////////////////////////////////////////////////////////////////////////////
436
+ static proc findCoordChange(poly f, ideal JAC)
437
+ "USAGE: findCoordChange(f, JAC); f poly, JAC ideal.
438
+ ASSUME: The polynomial f is homogeneous in three variables, JAC is
439
+ the Jacobi ideal of f.
440
+ RETURN: intvec, say a,b,c. After the coordinate change
441
+ var(3) --> a*var(1)+b*var(2)+c*var(3), the curve {f=0}
442
+ has no singularities at infinity {var(3)=0}.
443
+ "
444
+ {
445
+ int h = 2;
446
+ int a,b,c;
447
+ ideal Jfinfty;
448
+ while(h)
449
+ {
450
+ c = 1;
451
+ while(c<=h)
452
+ {
453
+ b = 0;
454
+ while(b<=(h-c))
455
+ {
456
+ a = h-b-c;
457
+ Jfinfty = JAC,a*var(1)+b*var(2)+c*var(3);
458
+ if(dim(std(Jfinfty)) == 0)
459
+ {
460
+ return(a,b,c);
461
+ }
462
+ b = b+1;
463
+ }
464
+ c = c+1;
465
+ }
466
+ h = h+1;
467
+ }
468
+ }
469
+
470
+ ///////////////////////////////////////////////////////////////////////////////
471
+ proc adjointIdeal(poly f, list #)
472
+ "USAGE: adjointIdeal(f [, choices]); f polynomial in three variables, choices
473
+ optional list consisting of one integer or of one string or of one
474
+ integer followed by one string. @*
475
+ Optional integer can be: @*
476
+ 1: compute integral basis via normalization. @*
477
+ 2: make local analysis of singularities first and apply normalization
478
+ separately. @*
479
+ 3: normalization via ideal quotient. @*
480
+ 4: normalization via local ideal quotient. @*
481
+ The default is 2. @*
482
+ Optional string may contain substrings: @*
483
+ - rattestyes -> causes error message if curve is not rational. @*
484
+ - firstchecksdone -> prevents that check of assumptions will be done
485
+ more than once.
486
+ ASSUME: The basering must be a polynomial ring in three variables, say x,y,z,
487
+ with coefficients in Q. @*
488
+ The polynomial f must be homogeneous and absolutely irreducible.@*
489
+ All these conditions will be checked automatically.@*
490
+ RETURN: ideal, the adjoint ideal of the curve defined by f.
491
+ THEORY: Considering C in the chart z<>0, the algorithm regards x as
492
+ transcendental and y as algebraic and computes an integral basis in C(x)[y] of
493
+ the integral closure of C[x] in C(x,y) using the normalization algorithm
494
+ from @ref{normal_lib}: see @ref{integralbasis_lib}. In a future edition of the library,
495
+ also van Hoeij's algorithm for computing the integral basis will be available.@*
496
+ From the integral basis, the adjoint ideal is obtained by linear algebra.
497
+ Alternatively, the algorithm starts with a local analysis of the singular
498
+ locus of C. Then, for each primary component of the singular locus which
499
+ does not correspond to ordinary multiple points or cusps, the integral
500
+ basis algorithm is applied separately. The ordinary multiple points and
501
+ cusps, in turn, are addressed by a straightforward direct algorithm. The
502
+ adjoint ideal is obtained by intersecting all ideals obtained locally.
503
+ The local variant of the algorithm is used by default. @*
504
+ KEYWORDS: integral basis; normalization.
505
+ EXAMPLE: example adjointIdeal; shows an example
506
+ "
507
+ {
508
+ def save_ring=basering;
509
+ ring r=QQ,(x,y,z),dp;
510
+ poly f=fetch(save_ring,f);
511
+ ideal I=adjointIdeal0(f,#);
512
+ setring save_ring;
513
+ ideal I=fetch(r,I);
514
+ return(I);
515
+ }
516
+ example
517
+ { "EXAMPLE:"; echo=2;
518
+ ring R = 0,(x,y,z),dp;
519
+ poly f = y^8-x^3*(z+x)^5;
520
+ adjointIdeal(f);
521
+ }
522
+
523
+ static proc adjointIdeal0(poly f, list choices)
524
+ {
525
+ list o_choices=choices;
526
+ if(size(o_choices)==0)
527
+ {
528
+ checkAssumptions(f);
529
+ choices = list(2, "rattestno");
530
+ }
531
+ if(size(o_choices)==1)
532
+ {
533
+ if(typeof(choices[1])=="int")
534
+ {
535
+ checkAssumptions(f);
536
+ choices = list(choices[1], "rattestno");
537
+ }
538
+ else
539
+ {
540
+ if(not(find(choices[1], "firstchecksdone")))
541
+ {
542
+ checkAssumptions(f);
543
+ }
544
+ else
545
+ {
546
+ choices = list(2, choices[1]);
547
+ }
548
+ }
549
+ }
550
+ if(size(o_choices) == 2)
551
+ {
552
+ if(not(find(choices[2],"firstchecksdone")))
553
+ {
554
+ checkAssumptions(f);
555
+ }
556
+ }
557
+ ideal JAC = diff(maxideal(1),ideal(f));
558
+ ideal Jfinfty = JAC,var(3);
559
+ /*applying a change of coordinates if (f=0) has singularities at infinity*/
560
+ int bb1;
561
+ if(dim(std(Jfinfty)) >= 1)
562
+ {
563
+ bb1 = 1;
564
+ int a,b,c = findCoordChange(f,JAC);
565
+ f = subst(f,var(3),var(3)-number(a)/c*var(1)-number(b)/c*var(2));
566
+ }
567
+ /*applying a change of coordinates if the point (0:1:0) lies on the curve*/
568
+ matrix co = coeffs(f,var(2));
569
+ int bb2 = ((size(co)-1) != deg(f));
570
+ if(bb2)
571
+ {
572
+ co = coeffs(f,var(1));
573
+ int bb2x = ((size(co)-1) == deg(f));
574
+ if(bb2x)
575
+ {
576
+ map perm = basering, var(2), var(1), var(3);
577
+ f = perm(f);
578
+ }
579
+ else
580
+ {
581
+ number cc=1;
582
+ int tst=0;
583
+ poly ff;
584
+ while (tst==0){
585
+ ff = subst(f,var(1),var(1)+cc*var(2));
586
+ tst=((size(coeffs(ff,var(2)))-1) == deg(ff));
587
+ if (tst==0){cc=cc+1;}
588
+ }
589
+ f = subst(f,var(1),var(1)+cc*var(2));
590
+ }
591
+ }
592
+ co = coeffs(f,var(2));
593
+ f = f/co[size(co),1];
594
+ /*the actual computation*/
595
+ ideal AI = adjointIdealAtWork(f,choices);
596
+ /*reversing the changes of coordinates if needed*/
597
+ if(bb2)
598
+ {
599
+ if(bb2x)
600
+ {
601
+ perm = basering, var(2), var(1), var(3);
602
+ AI = mstd(perm(AI))[2];
603
+ }
604
+ else
605
+ {
606
+ AI = mstd(substitute(AI,var(1),var(1)-cc*var(2)))[2];
607
+ }
608
+
609
+ }
610
+ if(bb1==1)
611
+ {
612
+ AI = mstd(substitute(AI,var(3),var(3)+number(a)/c*var(1)+number(b)/c*var(2)))[2];
613
+ }
614
+ return(AI);
615
+ }
616
+
617
+ example
618
+ { "EXAMPLE:"; echo=2;
619
+ ring R = 0,(x,y,z),dp;
620
+ poly f = y^8-x^3*(z+x)^5;
621
+ adjointIdeal(f);
622
+ }
623
+
624
+ ///////////////////////////////////////////////////////////////////////////////
625
+ static proc adjointIdealAtWork(poly f, list choices)
626
+ "USAGE: adjointIdealAtWork(f, choices); f polynomial in three variables,
627
+ choices list consisting of one integer followed by one string. @*
628
+ integer can be: @*
629
+ 1: compute integral basis via normalization. @*
630
+ 2: make local analysis of singularities first and apply normalization
631
+ separately. @*
632
+ 3: normalization via ideal quotient. @*
633
+ 4: normalization via local ideal quotient. @*
634
+ The default is 2. @*
635
+ string may contain substring: @*
636
+ - rattestyes -> causes error message if curve is not rational. @*
637
+ ASSUME: The basering must be a polynomial ring in three variables, say x,y,z,
638
+ with coefficients in Q. @*
639
+ The polynomial f must be homogeneous and absolutely irreducible. @*
640
+ Its dehomogenization with respect to the third variable must be monic
641
+ as a polynomial in the second variable (that is, C does not contain
642
+ the point (0:1:0)).@*
643
+ The curve C is not allowed to have singularities
644
+ at infinity (z = 0). @*
645
+ RETURN: ideal, the adjoint ideal of the curve defined by f.
646
+ "
647
+ {
648
+ def Roriginal = basering;
649
+ list rl = ring_list(Roriginal);
650
+ rl[3] = list(list("dp",1:nvars(Roriginal)),list("C",0));
651
+ def RP2 = ring(rl);
652
+ setring RP2;
653
+ poly f = imap(Roriginal,f);
654
+ poly dhf = subst(f,var(3),1);
655
+ int n = deg(f);
656
+ if((choices[1]==1) || (choices[1]==3)) // no local analysis of singularities
657
+ {
658
+ ideal AI;
659
+ if (choices[1]==1)
660
+ { AI = adjointIdealIB(f,insert(choices,ideal(0),size(choices))); }
661
+ else
662
+ { AI = adjointIdealIQ(f,insert(choices,ideal(0),size(choices))); }
663
+ AI = homog(std(AI),var(3));
664
+ AI = sat(AI, maxideal(1));
665
+ AI = minbase(AI);
666
+ setring Roriginal;
667
+ return(imap(RP2,AI));
668
+ }
669
+ list LL = geomGenusLA(f); // local analysis of singularities
670
+ int sizeLL2 = size(LL[2]);
671
+ int sizeLL3 = size(LL[3]);
672
+ list LL3 = LL[3];
673
+ ideal LL4 = LL[4];
674
+ if((LL[1]!=0) && (find(choices[2],"rattestyes")))
675
+ { ERROR("not a rational curve"); }
676
+ if((LL[2]==0) && (sizeLL3==0) && (LL4[1]==1)) // smooth case
677
+ {
678
+ setring Roriginal;
679
+ return(ideal(1));
680
+ }
681
+ int j,k;
682
+ list rl = ring_list(RP2);
683
+ rl[2] = list(var(1), var(2));
684
+ rl[3] = list(list("dp",1:2),list("C",0));
685
+ def Rdummy = ring(rl);
686
+ ideal B;
687
+ if(sizeLL3==0){B = 1;} // no ordinary multiple points
688
+ // (except possibly nodes)
689
+ else // there are ordinary multiple points
690
+ // (other than nodes)
691
+ {
692
+ setring Rdummy;
693
+ list OMP = imap(RP2,LL3);
694
+ int ub;
695
+ for(k=1;k<=size(OMP);k++)
696
+ {
697
+ if(OMP[k][1]>ub)
698
+ {
699
+ ub = OMP[k][1];
700
+ }
701
+ }
702
+ int lb = ub;
703
+ for(k=1;k<=size(OMP);k++)
704
+ {
705
+ if(OMP[k][1]<lb)
706
+ {
707
+ lb = OMP[k][1];
708
+ }
709
+ }
710
+ for(k=lb;k<=ub;k++)
711
+ {
712
+ ideal A(k) = 1;
713
+ }
714
+ for(k=1;k<=size(OMP);k++)
715
+ {
716
+ A(OMP[k][1]) = intersect(A(OMP[k][1]), OMP[k][2]);
717
+ }
718
+ int i = ub;
719
+ setring RP2;
720
+ for(k=lb;k<=ub;k++)
721
+ {
722
+ ideal A(k) = homog(std(fetch(Rdummy,A(k))),var(3));
723
+ }
724
+ B = maxideal(n-i);
725
+ ideal A;
726
+ while(i>=lb)
727
+ {
728
+ A = A(i)**(i-1);
729
+ j=1;
730
+ while(j<=ncols(A))
731
+ {
732
+ if(deg(A[j]>(n-2)))
733
+ {
734
+ A = sat(A, maxideal(1));
735
+ break;
736
+ }
737
+ j = j+1;
738
+ }
739
+ B = intersect(B,A);
740
+ i = i-1;
741
+ }
742
+ } //end else
743
+ B = intersect(B,homog(std(LL4),var(3))); // add nodes and cusps
744
+ if(sizeLL2==0) // ordinary multiple points plus cusps only
745
+ {
746
+ ideal AI = sat(B, maxideal(1));
747
+ AI = minbase(AI);
748
+ setring Roriginal;
749
+ return(imap(RP2,AI));
750
+ }
751
+ setring Rdummy;
752
+ poly f = imap(RP2,dhf);
753
+ ideal SL = jacob(f),f;
754
+ SL = sat(SL, fetch(RP2,LL4));
755
+ if(sizeLL3!=0)
756
+ {
757
+ for(k=lb;k<=ub;k++)
758
+ {
759
+ SL = sat(SL, A(k));
760
+ }
761
+ }
762
+ list PD = primdecGTZ(SL); // could be made faster -- see minAssGTZ
763
+ // in deltaLocMod -- only one PD needed
764
+ int pd = size(PD);
765
+ setring RP2;
766
+ list PD = imap(Rdummy,PD);
767
+ ideal AI = 1;
768
+ for(k=1;k<=pd;k++)
769
+ {
770
+ if (choices[1]==2)
771
+ {
772
+ AI = intersect(AI,adjointIdealIB(f,insert(choices,PD[k][1],
773
+ size(choices))));
774
+ }
775
+ else
776
+ {
777
+ AI = intersect(AI,adjointIdealIQ(f,insert(choices,PD[k][1],
778
+ size(choices))));
779
+ }
780
+ }
781
+ AI = homog(std(AI),var(3));
782
+ AI = intersect(AI,B);
783
+ AI = sat(AI, maxideal(1));
784
+ AI = minbase(AI);
785
+ setring Roriginal;
786
+ return(imap(RP2,AI));
787
+ }
788
+
789
+ ///////////////////////////////////////////////////////////////////////////////
790
+ static proc adjointIdealIB(poly f, list choices)
791
+ "USAGE: adjointIdealIB(f, choices); f polynomial in three variables, choices
792
+ list consisting of one integer followed by one string followed by one
793
+ ideal. @*
794
+ integer can be: @*
795
+ 1, 2 : compute integral basis via normalization @*
796
+ The default is 2. @*
797
+ string may contain substring: @*
798
+ - rattestyes -> causes error message if curve is not rational. @*
799
+ ideal serves as input for @ref integralBasis.
800
+ ASSUME: The basering must be a polynomial ring in three variables, say x,y,z,
801
+ with coefficients in Q. @*
802
+ The polynomial f must be homogeneous and absolutely irreducible.@*
803
+ Its dehomogenization with respect to the third variable must be monic
804
+ as a polynomial in the second variable (that is, C does not contain
805
+ the point (0:1:0)).@*
806
+ The curve C is not allowed to have singularities
807
+ at infinity (z = 0). @*
808
+ RETURN: ideal containing the adjoint ideal of the curve defined by f. @*
809
+ "
810
+ {
811
+ poly dhf = subst(f,var(3),1);
812
+ def Roriginal = basering;
813
+ list rl = ring_list(Roriginal);
814
+ rl[2] = list(var(1), var(2));
815
+ rl[3] = list(list("dp",1:2),list("C",0));
816
+ def Rdummy = ring(rl);
817
+ setring Rdummy;
818
+ poly f = imap(Roriginal,dhf);
819
+ poly d2f = diff(f,var(2));
820
+ list DATA = imap(Roriginal,choices);
821
+ /* Creating rings for later use */
822
+ list rl = ring_list(Rdummy);
823
+ rl[2] = list(var(2), var(1));
824
+ rl[3] = list(list("lp",1:2),list("C",0));
825
+ def Rred = ring(rl); // make var(2) > var(1)
826
+ rl = ring_list(Rdummy);
827
+ rl[1] = list(0,list(var(1)),list(list("dp",1)),ideal(0));
828
+ rl[2] = list(var(2));
829
+ rl[3] = list(list("dp",1),list("C",0));
830
+ def QF = ring(rl); // make var(1) transcendental
831
+ list LIntB;
832
+ if(DATA[1] <= 4) // use normalization algorithm
833
+ {
834
+ LIntB = integralBasis(f, 2, list(list("inputC", DATA[3]),"isIrred"));
835
+ }
836
+ else // use van Hoeij's algorithm
837
+ {
838
+ LIntB = integralBasisVH(f,DATA[3],2); // van Hoeij in future version
839
+ // used when DATA[1] = 5
840
+ }
841
+ if(find(DATA[2],"rattestyes") && (size(DATA[3])==0))
842
+ {
843
+ setring Roriginal;
844
+ int gg = geomGenusIB(f,imap(Rdummy, LIntB));
845
+ if(gg!=0){ERROR("not a rational curve");}
846
+ setring Rdummy;
847
+ }
848
+ int i,j,k,l;
849
+ ideal IB = LIntB[1];
850
+ poly d = LIntB[2];
851
+ int sL=size(IB);
852
+ setring Rred;
853
+ ideal IB = imap(Rdummy,IB);
854
+ ideal fred = std(imap(Rdummy,f));
855
+ IB = reduce(IB,fred);
856
+ matrix M = coeffs(IB,var(1));
857
+ setring QF;
858
+ matrix M = imap(Rred,M);
859
+ poly d = imap(Rdummy,d);
860
+ M=1/d*M;
861
+ list LUM = ludecomp(M);
862
+ list LS;
863
+ matrix dummyvector[sL][1];
864
+ matrix Gij[sL][sL];
865
+ matrix Tr[sL][sL];
866
+ setring Rred;
867
+ poly eiej;
868
+ list Iij, empty;
869
+ matrix Gij[sL][sL];
870
+ for(i = 1; i <= sL; i++)
871
+ {
872
+ for(j = i; j <= sL; j++)
873
+ {
874
+ setring Rred;
875
+ Gij = 0;
876
+ eiej = IB[i]*IB[j];
877
+ Iij=empty;
878
+ for(k = 1; k <= sL; k++)
879
+ {
880
+ Iij[k] = reduce(eiej*IB[k],fred);
881
+ }
882
+ Gij = coeffs(ideal(Iij[1..sL]),var(1));
883
+ setring QF;
884
+ Gij = imap (Rred, Gij);
885
+ for(k = 1; k <= sL; k++)
886
+ {
887
+ dummyvector = Gij[1..sL,k];
888
+ LS = lusolve(LUM[1], LUM[2], LUM[3], dummyvector);
889
+ Tr[i,j] = Tr[i,j] + 1/d^3*LS[2][k,1];
890
+ }
891
+ }
892
+ }
893
+ for(i = 1; i <= sL; i++)
894
+ {
895
+ for(j = 1; j < i; j++)
896
+ {
897
+ Tr[i,j] = Tr[j,i];
898
+ }
899
+ }
900
+ LUM = ludecomp(Tr);
901
+ setring Rred;
902
+ poly d2f = imap(Rdummy,d2f);
903
+ IB = d2f*IB;
904
+ IB = reduce(IB,fred);
905
+ setring QF;
906
+ matrix IB = transpose(matrix(imap(Rred,IB)));
907
+ IB = 1/d*IB;
908
+ LS = lusolve(LUM[1], LUM[2], LUM[3], IB);
909
+ ideal LL = ideal(LS[2]);
910
+ setring Roriginal;
911
+ ideal AI = imap(QF,LL);
912
+ return(AI);
913
+ }
914
+
915
+ ///////////////////////////////////////////////////////////////////////////////
916
+ static proc adjointIdealIQ(poly f, list choices)
917
+ {
918
+ poly dhf = subst(f,var(3),1);
919
+ def Roriginal = basering;
920
+ list rl = ring_list(Roriginal);
921
+ rl[2] = list(var(1), var(2));
922
+ rl[3] = list(list("dp",1:2),list("C",0));
923
+ def Rdummy = ring(rl);
924
+ setring Rdummy;
925
+ list DATA = imap(Roriginal,choices);
926
+ poly f = imap(Roriginal,dhf);
927
+ list LIntB;
928
+ if(DATA[1] <= 4) // use normalization algorithm
929
+ {
930
+ LIntB = integralBasis(f, 2, list(list("inputC", DATA[3]),"isIrred"));
931
+ }
932
+ else // use van Hoeij's algorithm
933
+ {
934
+ LIntB = integralBasisVH(f,DATA[3],2); // van Hoeij in future version
935
+ // used when DATA[1] = 5
936
+ }
937
+ if(find(DATA[2],"rattestyes") && (DATA[3]==0))
938
+ {
939
+ setring Roriginal;
940
+ int gg = geomGenusIB(f,imap(Rdummy, LIntB));
941
+ if(gg!=0){ERROR("not a rational curve");}
942
+ setring Rdummy;
943
+ }
944
+ int i,j,k,l;
945
+ ideal IB = LIntB[1];
946
+ poly d = LIntB[2];
947
+ ideal fd = f, d;
948
+ ideal IBf = IB, f;
949
+ ideal AI = quotient(fd, IBf);
950
+ //"#### IB:"; IB;
951
+ //"#### d:", d;
952
+ setring Roriginal;
953
+ ideal AI = imap(Rdummy,AI);
954
+ //"#### AI:"; AI;
955
+ return(AI);
956
+ }
957
+
958
+ ///////////////////////////////////////////////////////////////////////////////
959
+ proc mapToRatNormCurve(poly f, ideal AI)
960
+ "USAGE: mapToRatNormCurve(f, AI); f polynomial, AI ideal
961
+ ASSUME: The polynomial f is homogeneous in three variables and absolutely
962
+ irreducible.
963
+ The plane curve C defined by f is rational.
964
+ The ideal AI is the adjoint ideal of C.
965
+ RETURN: ring with an ideal RNC.
966
+ EXAMPLE: example mapToRatNormCurve; shows an example
967
+ "
968
+ {
969
+ int n = size(AI);
970
+ int k;
971
+ //if(n!=deg(f)-1){ERROR("not a rational curve");}
972
+ def Roriginal = basering;
973
+ ideal IC = f;
974
+ list rl = ring_list(Roriginal);
975
+ /* begin workaround elimination*/
976
+ for(k = 1; k <= 3; k++)
977
+ {
978
+ rl[2][k] = "x("+string(k)+")";
979
+ }
980
+ for(k = 1; k <= n; k++)
981
+ {
982
+ rl[2][k+3] = "y("+string(k)+")";
983
+ }
984
+ rl[3]= list(list("wp",intvec(1:3, (n-1):n)),list("C",0));
985
+ def Relim = ring(rl);
986
+ setring Relim;
987
+ ideal IC = fetch(Roriginal,IC);
988
+ ideal AI = fetch(Roriginal,AI);
989
+ ideal J;
990
+ J = IC;
991
+ for(k=1;k<=n;k++)
992
+ {
993
+ J=J,var(k+3)-AI[k];
994
+ }
995
+ ideal SJ = std(J);
996
+ bigintvec HJ = hilb(SJ,1);
997
+ ideal RNC = eliminate(J,x(1)*x(2)*x(3),HJ);
998
+ list rl = ring_list(Relim);
999
+ list rl2 = rl[2];
1000
+ rl[2] = list(rl2[4..n+3]);
1001
+ rl[3]= list(list("dp",1:n),list("C",0));
1002
+ def Rtarget = ring(rl);
1003
+ setring Rtarget;
1004
+ ideal RNC = imap(Relim,RNC);
1005
+ /* end workaround elimination*/
1006
+ export(RNC);
1007
+ int p = printlevel - voice + 3;
1008
+ dbprint(p,"//'mapToRatNorm' created a ring together with an ideal RNC.");
1009
+ dbprint(p,"// Supposing you typed, say, def RPn = mapToRatNorm(f,AI);");
1010
+ dbprint(p,"// you may access the ideal by typing");
1011
+ dbprint(p,"// setring RPn; RNC;");
1012
+ return(Rtarget);
1013
+ }
1014
+
1015
+ example
1016
+ { "EXAMPLE:"; echo=2;
1017
+ ring R = 0,(x,y,z),dp;
1018
+ poly f = y^8-x^3*(z+x)^5;
1019
+ ideal adj = adjointIdeal(f);
1020
+ def Rn = mapToRatNormCurve(f,adj);
1021
+ setring(Rn);
1022
+ RNC;
1023
+ }
1024
+
1025
+ ///////////////////////////////////////////////////////////////////////////////
1026
+ proc rncAntiCanonicalMap(ideal I)
1027
+ "USAGE: rncAntiCanonicalMap(I); I ideal
1028
+ ASSUME: I is a homogeneous ideal in the basering
1029
+ defining a rational normal curve C in PP^n.
1030
+ NOTE: The procedure will fail or give a wrong output if I is not the
1031
+ ideal of a rational normal curve.
1032
+ RETURN: ideal defining the anticanonical map C --> PP^(n-2). @*
1033
+ Note that the entries of the ideal should be considered as
1034
+ representatives of elements in R/I, where R is the basering.
1035
+ THEORY: The anti-canonical map of a rational normal curve
1036
+ maps C isomorpically to a rational normal curve in PP^(n-2).
1037
+ KEYWORDS: rational normal curve, projection.
1038
+ EXAMPLE: example rncAntiCanonicalMap; shows an example
1039
+ "
1040
+ {
1041
+ def Roriginal = basering;
1042
+ list rl = ring_list(Roriginal);
1043
+ rl[3] = list(list("dp",1:nvars(Roriginal)),list("C",0));
1044
+ def RoriginalDP = ring(rl);
1045
+ setring RoriginalDP;
1046
+ ideal I = imap(Roriginal,I);
1047
+ int cc = nvars(RoriginalDP)-2;
1048
+ module AKD = Ext_R(cc,I);
1049
+ qring qI = std(I);
1050
+ matrix AKD = imap(RoriginalDP,AKD);
1051
+ AKD = syz(transpose(AKD));
1052
+ ideal PR = submat(AKD,1..nrows(AKD),1);
1053
+ setring Roriginal;
1054
+ return(imap(qI,PR));
1055
+ }
1056
+
1057
+ example
1058
+ { "EXAMPLE:"; echo=2;
1059
+ ring R = 0,(x,y,z),dp;
1060
+ poly f = y^8-x^3*(z+x)^5;
1061
+ ideal adj = adjointIdeal(f);
1062
+ def Rn = mapToRatNormCurve(f,adj);
1063
+ setring(Rn);
1064
+ RNC;
1065
+ rncAntiCanonicalMap(RNC);
1066
+ }
1067
+
1068
+
1069
+ ///////////////////////////////////////////////////////////////////////////////
1070
+ proc rncItProjOdd(ideal I)
1071
+ "USAGE: rncItProjOdd(I); I ideal
1072
+ ASSUME: I is a homogeneous ideal in the basering with n+1 variables
1073
+ defining a rational normal curve C in PP^n with n odd.
1074
+ NOTE: The procedure will fail or give a wrong output if I is not the
1075
+ ideal of a rational normal curve. It will test whether n is odd.
1076
+ RETURN: ideal PHI defining an isomorphic projection of C to PP^1.@*
1077
+ Note that the entries of PHI should be considered as
1078
+ representatives of elements in R/I, where R is the basering.
1079
+ THEORY: We iterate the procedure @ref{rncAntiCanonicalMap} to obtain PHI.
1080
+ KEYWORDS: rational normal curve, projection.
1081
+ SEE ALSO: rncItProjEven.
1082
+ EXAMPLE: example rncItProjOdd; shows an example
1083
+ "
1084
+ {
1085
+ int n = nvars(basering);
1086
+ if((n mod 2) == 1){ERROR("Pn has even dimension");}
1087
+ def Roriginal = basering;
1088
+ list rlo = ring_list(Roriginal);
1089
+ rlo[3]= list(list("dp",1:n),list("C",0));
1090
+ int k;
1091
+ for(k = 1; k <= n; k++)
1092
+ {
1093
+ rlo[2][k] = "z("+string(k)+")";
1094
+ }
1095
+ def RoriginalCopy = ring(rlo);
1096
+ for(k = 1; k <= n; k++)
1097
+ {
1098
+ rlo[2][k] = "y("+string(k)+")";
1099
+ }
1100
+ def Rold = ring(rlo);
1101
+ setring RoriginalCopy;
1102
+ ideal PHI = maxideal(1);
1103
+ setring Rold;
1104
+ ideal J = fetch(Roriginal,I);
1105
+ list rl2;
1106
+ def Rnew;
1107
+ def Rbig;
1108
+ def Relim;
1109
+ bigintvec HJJ;
1110
+ while(n>2)
1111
+ {
1112
+ ideal PR = rncAntiCanonicalMap(J);
1113
+ list rl = ring_list(Rold);
1114
+ Rbig = Rold + RoriginalCopy;
1115
+ setring Rbig;
1116
+ ideal PHI = imap(RoriginalCopy,PHI);
1117
+ ideal dummy = imap(Rold,PR);
1118
+ for(k = 1; k <= n; k++)
1119
+ {
1120
+ dummy = subst(dummy,var(k),PHI[k]);
1121
+ }
1122
+ setring RoriginalCopy;
1123
+ PHI = imap(Rbig,dummy);
1124
+ /* begin workaround elimination*/
1125
+ setring Rold;
1126
+ for(k = 1; k <= n; k++)
1127
+ {
1128
+ rl[2][k] = "x("+string(k)+")";
1129
+ }
1130
+ for(k = 1; k <= n-2; k++)
1131
+ {
1132
+ rl[2][k+n] = "y("+string(k)+")";
1133
+ }
1134
+ rl[3]= list(list("dp",1:(2*n-2)),list("C",0));
1135
+ Relim = ring(rl);
1136
+ setring Relim;
1137
+ ideal J = fetch(Rold,J);
1138
+ ideal PR = fetch(Rold,PR);
1139
+ ideal JJ = J;
1140
+ poly pvar=1;
1141
+ for(k = 1; k <= n; k++)
1142
+ {
1143
+ pvar = pvar*var(k);
1144
+ }
1145
+ for(k=1;k<=n-2;k++)
1146
+ {
1147
+ JJ=JJ,var(k+n)-PR[k];
1148
+ }
1149
+ ideal SJJ = std(JJ);
1150
+ HJJ = hilb(SJJ,1);
1151
+ J = eliminate(JJ,pvar,HJJ);
1152
+ list rl = ring_list(Relim);
1153
+ rl2 = rl[2];
1154
+ rl[2] = list(rl2[n+1..2*n-2]);
1155
+ rl[3]= list(list("dp",1:(n-2)),list("C",0));
1156
+ Rnew = ring(rl);
1157
+ setring Rnew;
1158
+ ideal J = imap(Relim,J);
1159
+ /* end workaround elimination*/
1160
+ Rold = Rnew;
1161
+ setring Rold;
1162
+ n = n-2;
1163
+ }
1164
+ setring Roriginal;
1165
+ return(fetch(RoriginalCopy,PHI));
1166
+ }
1167
+
1168
+ example
1169
+ { "EXAMPLE:"; echo=2;
1170
+ ring R = 0,(x,y,z),dp;
1171
+ poly f = -x7-10x5y2-10x4y3-3x3y4+8x2y5+7xy6+11y7+3x6+10x5y +30x4y2
1172
+ +26x3y3-13x2y4-29xy5-33y6-3x5-20x4y-33x3y2-8x2y3+37xy4+33y5
1173
+ +x4+10x3y+13x2y2-15xy3-11y4;
1174
+ f = homog(f,z);
1175
+ ideal adj = adjointIdeal(f);
1176
+ def Rn = mapToRatNormCurve(f,adj);
1177
+ setring(Rn);
1178
+ RNC;
1179
+ rncItProjOdd(RNC);
1180
+ }
1181
+
1182
+
1183
+ ///////////////////////////////////////////////////////////////////////////////
1184
+ proc rncItProjEven(ideal I)
1185
+ "USAGE: rncItProjEven(I); I ideal
1186
+ ASSUME: I is a homogeneous ideal in the basering with n+1 variables
1187
+ defining a rational normal curve C in PP^n with n even.
1188
+ NOTE: The procedure will fail or give a wrong output if I is not the
1189
+ ideal of a rational normal curve. It will test whether n is odd.
1190
+ RETURN: ring with an ideal CONIC defining a conic C2 in PP^2.@*
1191
+ In addition, an ideal PHI in the basering defining an isomorphic
1192
+ projection of C to C2 will be exported.@*
1193
+ Note that the entries of PHI should be considered as
1194
+ representatives of elements in R/I, where R is the basering.
1195
+ THEORY: We iterate the procedure @ref{rncAntiCanonicalMap} to obtain PHI.
1196
+ KEYWORDS: rational normal curve, projection.
1197
+ SEE ALSO: rncItProjOdd.
1198
+ EXAMPLE: example rncItProjEven; shows an example
1199
+ "
1200
+ {
1201
+ int n = nvars(basering);
1202
+ if((n mod 2) == 0){ERROR("Pn has odd dimension");}
1203
+ def Roriginal = basering;
1204
+ list rlo = ring_list(Roriginal);
1205
+ rlo[3]= list(list("dp",1:n),list("C",0));
1206
+ int k;
1207
+ for(k = 1; k <= n; k++)
1208
+ {
1209
+ rlo[2][k] = "z("+string(k)+")";
1210
+ }
1211
+ def RoriginalCopy = ring(rlo);
1212
+ for(k = 1; k <= n; k++)
1213
+ {
1214
+ rlo[2][k] = "y("+string(k)+")";
1215
+ }
1216
+ def Rold = ring(rlo);
1217
+ setring RoriginalCopy;
1218
+ ideal PHI = maxideal(1);
1219
+ setring Rold;
1220
+ ideal J = fetch(Roriginal,I);
1221
+ list rl2;
1222
+ def Rnew;
1223
+ def Rbig;
1224
+ def Relim;
1225
+ bigintvec HJJ;
1226
+ while(n>3)
1227
+ {
1228
+ ideal PR = rncAntiCanonicalMap(J);
1229
+ list rl = ring_list(Rold);
1230
+ Rbig = Rold + RoriginalCopy;
1231
+ setring Rbig;
1232
+ ideal PHI = imap(RoriginalCopy,PHI);
1233
+ ideal dummy = imap(Rold,PR);
1234
+ for(k = 1; k <= n; k++)
1235
+ {
1236
+ dummy = subst(dummy,var(k),PHI[k]);
1237
+ }
1238
+ setring RoriginalCopy;
1239
+ PHI = imap(Rbig,dummy);
1240
+ /* begin workaround elimination*/
1241
+ setring Rold;
1242
+ for(k = 1; k <= n; k++)
1243
+ {
1244
+ rl[2][k] = "x("+string(k)+")";
1245
+ }
1246
+ for(k = 1; k <= n-2; k++)
1247
+ {
1248
+ rl[2][k+n] = "y("+string(k)+")";
1249
+ }
1250
+ rl[3]= list(list("dp",1:(2*n-2)),list("C",0));
1251
+ Relim = ring(rl);
1252
+ setring Relim;
1253
+ ideal J = fetch(Rold,J);
1254
+ ideal PR = fetch(Rold,PR);
1255
+ ideal JJ = J;
1256
+ poly pvar=1;
1257
+ for(k = 1; k <= n; k++)
1258
+ {
1259
+ pvar = pvar*var(k);
1260
+ }
1261
+ for(k=1;k<=n-2;k++)
1262
+ {
1263
+ JJ=JJ,var(k+n)-PR[k];
1264
+ }
1265
+ ideal SJJ = std(JJ);
1266
+ HJJ = hilb(SJJ,1);
1267
+ J = eliminate(JJ,pvar,HJJ);
1268
+ list rl = ring_list(Relim);
1269
+ rl2 = rl[2];
1270
+ rl[2] = list(rl2[n+1..2*n-2]);
1271
+ rl[3]= list(list("dp",1:(n-2)),list("C",0));
1272
+ Rnew = ring(rl);
1273
+ setring Rnew;
1274
+ ideal J = imap(Relim,J);
1275
+ /* end workaround elimination*/
1276
+ Rold = Rnew;
1277
+ setring Rold;
1278
+ n = n-2;
1279
+ }
1280
+ poly CONIC = J[1];
1281
+ export(CONIC);
1282
+ setring Roriginal;
1283
+ ideal PHI = fetch(RoriginalCopy,PHI);
1284
+ export(PHI);
1285
+ return(Rold);
1286
+ }
1287
+
1288
+ example
1289
+ { "EXAMPLE:"; echo=2;
1290
+ ring R = 0,(x,y,z),dp;
1291
+ poly f = y^8-x^3*(z+x)^5;
1292
+ ideal adj = adjointIdeal(f);
1293
+ def Rn = mapToRatNormCurve(f,adj);
1294
+ setring(Rn);
1295
+ RNC;
1296
+ def Rc = rncItProjEven(RNC);
1297
+ PHI;
1298
+ setring Rc;
1299
+ CONIC;
1300
+ }
1301
+
1302
+ ///////////////////////////////////////////////////////////////////////////////
1303
+ static proc geomGenusIB(poly f, list #)
1304
+ "USAGE: geomGenusIB(f [, L]); f poly, L optional list representing the
1305
+ integral basis as returned by @ref integralBasisJ.
1306
+ ASSUME: The basering must be a polynomial ring in three variables, say x,y,z,
1307
+ with coefficients in Q. @*
1308
+ The polynomial f must be homogeneous and absolutely irreducible.@*
1309
+ Its dehomogenization with respect to the third variable must be monic
1310
+ as a polynomial in the second variable (that is, the curve C = {f = 0}
1311
+ does not contain the point (0:1:0)).@*
1312
+ The curve C is not allowed to have singularities
1313
+ at infinity (z = 0). @*
1314
+ NOTE: The last two conditions can be met by a suitable change of coordinates in PGL(3)
1315
+ as applied in the procedure @ref adjointIdeal. The other conditions
1316
+ can be tested using @ref checkAssumptions.@*
1317
+ RETURN: int, the geometric genus of C.
1318
+ THEORY: We compute an integral basis of the integral closure of the coordinate
1319
+ ring of C and from that the geometric genus.@*
1320
+ KEYWORDS: geometric genus, plane curves.
1321
+ SEE ALSO: genus.
1322
+ "
1323
+ {
1324
+ int bb = size(#);
1325
+ poly dhf = subst(f,var(3),1);
1326
+ def Roriginal = basering;
1327
+ list rl = ring_list(Roriginal);
1328
+ rl[2] = list(var(1), var(2));
1329
+ rl[3] = list(list("dp",1:2),list("C",0));
1330
+ def Rdummy = ring(rl);
1331
+ setring Rdummy;
1332
+ poly f = imap(Roriginal,dhf);
1333
+ list LIntB;
1334
+ if(bb == 0)
1335
+ {
1336
+ LIntB = integralBasis(f,2,"isIrred");
1337
+ }
1338
+ else
1339
+ {
1340
+ LIntB = imap(Roriginal,#);
1341
+ }
1342
+ ideal IB = LIntB[1];
1343
+ poly d = LIntB[2];
1344
+ int ud = deg(d);
1345
+ int sL = size(IB);
1346
+ int k;
1347
+ int gg = (sL-1)*(sL-2) div 2-sL*ud;
1348
+ for(k = 1; k <= sL; k++)
1349
+ {
1350
+ gg = gg + deg(gcd(d,IB[k]));
1351
+ }
1352
+ setring Roriginal;
1353
+ return(gg);
1354
+ }
1355
+
1356
+
1357
+ ///////////////////////////////////////////////////////////////////////////////
1358
+ static proc geomGenusLA(poly F)
1359
+ "USAGE: geomGenusLA(F); F polynomial
1360
+ ASSUME: The basering must be a polynomial ring in three variables. @*
1361
+ The polynomial F must be homogeneous.@*
1362
+ RETURN: list L:
1363
+ @texinfo
1364
+ @table @asis
1365
+ @item @code{L[1]}; int:
1366
+ the geometric genus p_g = p_a - delta of the projective
1367
+ curve C defined by F, where p_a is the arithmetic genus.
1368
+ @item @code{L[2]}; int:
1369
+ is positive if C has singularities other
1370
+ than ordinary multiple points.@*
1371
+ @item @code{L[3]}; list:
1372
+ consists of one list for each primary component
1373
+ of the singular locus of C which corresponds to a set of conjugated
1374
+ ordinary multiple points. Each list consists of an int, the
1375
+ multiplicity of the points, and an ideal, the primary component.
1376
+ @end table
1377
+ @end texinfo
1378
+ NOTE: delta is the sum of all local delta-invariants of the singularities,
1379
+ i.e. dim(R'/R), R' the normalization of the local ring R of the
1380
+ singularity. @*
1381
+ SEE ALSO: genus
1382
+ "
1383
+ {
1384
+ int w = printlevel-voice+2; // w=printlevel (default: w=0)
1385
+ int d = deg(F);
1386
+ def R = basering;
1387
+ ring S = create_ring(ring_list(R)[1], "(x,y,t)", "dp", "no_minpoly");
1388
+ ring C = create_ring(ring_list(R)[1], "(x,y)", "ds", "no_minpoly");
1389
+ int genus=(d-1)*(d-2) div 2;
1390
+ if(w>=1){"the arithmetic genus of the plane curve:";genus;pause();}
1391
+
1392
+ int delt,deltaloc,deltainf,tau,tauinf,cusps,iloc,iglob,l,nsing,
1393
+ tauloc,tausing,k,rat,nbranchinf,nbranch,nodes,cuspsinf,nodesinf;
1394
+ list inv;
1395
+ ring newR = create_ring(ring_list(R)[1], "(x,y)", "dp", "no_minpoly");
1396
+ //the singularities at the affine part
1397
+ map sigma=R,var(1),var(2),1;
1398
+ ideal I=sigma(F);
1399
+
1400
+ list OMPButNodes;
1401
+ int sizeOMPButNodes;
1402
+ int NotOnlyOMPPlusCusps;
1403
+
1404
+ ideal I1=jacob(I);
1405
+ matrix Hess[2][2]=jacob(I1);
1406
+ ideal ID=I+I1+ideal(det(Hess));//singular locus of I+I1
1407
+ ideal radID=std(radical(ID));//the non-nodal locus
1408
+ if(w>=1){"the non-nodal locus:";"";radID;pause();"";}
1409
+ if(deg(radID[1])==0)
1410
+ {
1411
+ ideal IDsing=1;
1412
+ }
1413
+ else
1414
+ {
1415
+ ideal IDsing=minor(jacob(ID),2)+radID;//singular locus of ID
1416
+ }
1417
+
1418
+ iglob=vdim(std(IDsing));
1419
+
1420
+ ideal radIDsing = 1;
1421
+
1422
+ if(iglob!=0)//computation of the radical of IDsing
1423
+ {
1424
+ radIDsing=reduce(IDsing,radID);
1425
+ if(size(radIDsing)==0)
1426
+ {
1427
+ radIDsing=radID;
1428
+ attrib(radIDsing,"isSB",1);
1429
+ }
1430
+ else
1431
+ {
1432
+ radIDsing=std(radical(IDsing));
1433
+ }
1434
+ iglob=vdim(radIDsing);
1435
+ if((w>=1)&&(iglob))
1436
+ {"the non-nodal-cuspidal locus:";radIDsing;pause();"";}
1437
+ }
1438
+ cusps=vdim(radID)-iglob;
1439
+
1440
+ ideal NodesPlusCusps = radical(sat(I+I1, radIDsing));
1441
+
1442
+ nsing=nsing+cusps;
1443
+
1444
+ if(iglob==0)
1445
+ {
1446
+ if(w>=1){" there are only cusps and nodes";"";}
1447
+ tau=vdim(std(I+jacob(I)));
1448
+ tauinf=tauinf+tau;
1449
+ nodes=tau-2*cusps;
1450
+ delt=nodes+cusps;
1451
+ nbranch=2*tau-3*cusps;
1452
+ nsing=nsing+nodes;
1453
+ }
1454
+ else
1455
+ {
1456
+ if(w>=1){"the non-nodal-cuspidal singularities";"";}
1457
+ setring C;
1458
+ ideal I1=imap(newR,radIDsing);
1459
+ iloc=vdim(std(I1));
1460
+ if(iglob==iloc)
1461
+ {
1462
+ if(w>=1){"only cusps and nodes outside (0,0,1)";}
1463
+ setring newR;
1464
+ tau=vdim(std(I+jacob(I)));
1465
+ tauinf=tauinf+tau;
1466
+ inv=deltaLocMod(I[1],maxideal(1));
1467
+ delt=inv[1];
1468
+ tauloc=inv[2];
1469
+ nodes=tau-tauloc-2*cusps;
1470
+ nsing=nsing+nodes;
1471
+ if(inv[2]!=0)
1472
+ {
1473
+ nsing=nsing+1;
1474
+ }
1475
+ nbranch=inv[3]+ 2*nodes+cusps;
1476
+ delt=delt+nodes+cusps;
1477
+ if((w>=1)&&(inv[2]==0)){"smooth at (0,0,1)";}
1478
+ if(inv[4]!=0)
1479
+ {
1480
+ OMPButNodes = insert(OMPButNodes,list(inv[4],maxideal(1)),
1481
+ sizeOMPButNodes);
1482
+ sizeOMPButNodes = size(OMPButNodes); // new
1483
+ }
1484
+ else
1485
+ {
1486
+ NotOnlyOMPPlusCusps = NotOnlyOMPPlusCusps + 1;
1487
+ }
1488
+ }
1489
+ else
1490
+ {
1491
+ setring newR;
1492
+ list pr=minAssGTZ(radIDsing);
1493
+ if(w>=1){pr;}
1494
+
1495
+ for(k=1;k<=size(pr);k++)
1496
+ {
1497
+ if(w>=1){nsing=nsing+vdim(std(pr[k]));}
1498
+ inv=deltaLocMod(I[1],pr[k]);
1499
+ delt=delt+inv[1];
1500
+ tausing=tausing+inv[2];
1501
+ nbranch=nbranch+inv[3];
1502
+ if(inv[4]!=0)
1503
+ {
1504
+ OMPButNodes = insert(OMPButNodes,list(inv[4],pr[k]),
1505
+ sizeOMPButNodes);
1506
+ sizeOMPButNodes = size(OMPButNodes);
1507
+ }
1508
+ else
1509
+ {
1510
+ NotOnlyOMPPlusCusps = NotOnlyOMPPlusCusps + 1;
1511
+ }
1512
+ }
1513
+ tau=vdim(std(I+jacob(I)));
1514
+ tauinf=tauinf+tau;
1515
+ nodes=tau-tausing-2*cusps;
1516
+ nsing=nsing+nodes;
1517
+ delt=delt+nodes+cusps;
1518
+ nbranch=nbranch+2*nodes+cusps;
1519
+ }
1520
+ }
1521
+ genus=genus-delt-deltainf;
1522
+ if(w>=1)
1523
+ {
1524
+ "The projected plane curve has locally:";"";
1525
+ "singularities:";nsing;
1526
+ "branches:";nbranch+nbranchinf;
1527
+ "nodes:"; nodes+nodesinf;
1528
+ "cusps:";cusps+cuspsinf;
1529
+ "Tjurina number:";tauinf;
1530
+ "Milnor number:";2*(delt+deltainf)-nbranch-nbranchinf+nsing;
1531
+ "delta of the projected curve:";delt+deltainf;
1532
+ //"delta of the curve:";p_a-genus;
1533
+ "genus:";genus;
1534
+ "====================================================";
1535
+ "";
1536
+ }
1537
+ setring R;
1538
+ if(sizeOMPButNodes>0)
1539
+ {
1540
+ list OMPButNodes = fetch(newR,OMPButNodes);
1541
+ }
1542
+ return(list(genus,NotOnlyOMPPlusCusps,OMPButNodes,
1543
+ fetch(newR,NodesPlusCusps)));
1544
+ }
1545
+
1546
+
1547
+ ///////////////////////////////////////////////////////////////////////////////
1548
+ static proc deltaLocMod(poly f,ideal singL)
1549
+ "USAGE: deltaLoc(f,J); f poly, J ideal
1550
+ ASSUME: f is reduced bivariate polynomial; basering has exactly two variables;
1551
+ J is irreducible prime component of the singular locus of f (e.g., one
1552
+ entry of the output of @code{minAssGTZ(I);}, I = <f,jacob(f)>).
1553
+ RETURN: list L:
1554
+ @texinfo
1555
+ @table @asis
1556
+ @item @code{L[1]}; int:
1557
+ the sum of (local) delta invariants of f at the (conjugated) singular
1558
+ points given by J.
1559
+ @item @code{L[2]}; int:
1560
+ the sum of (local) Tjurina numbers of f at the (conjugated) singular
1561
+ points given by J.
1562
+ @item @code{L[3]}; int:
1563
+ the sum of (local) number of branches of f at the (conjugated)
1564
+ singular points given by J.
1565
+ @item @code{L[3]}; int:
1566
+ the multiplicity of f at the (conjugated) singular points given by J,
1567
+ if these are ordinary multiple points, and 0 otherwise.
1568
+ @end table
1569
+ @end texinfo
1570
+ NOTE: procedure makes use of @code{execute}; increasing printlevel displays
1571
+ more comments (default: printlevel=0).
1572
+ SEE ALSO: deltaLoc, delta, tjurina
1573
+ KEYWORDS: delta invariant; Tjurina number
1574
+ "
1575
+ {
1576
+ option(redSB);
1577
+ def R=basering;
1578
+ ring S = create_ring(ring_list(R)[1], "(x,y)", "lp", "no_minpoly");
1579
+ map phi=R,x,y;
1580
+ ideal singL=phi(singL);
1581
+ singL=simplify(std(singL),1);
1582
+ attrib(singL,"isSB",1);
1583
+ int d=vdim(singL);
1584
+ poly f=phi(f);
1585
+ int i;
1586
+ int w = printlevel-voice+2; // w=printlevel (default: w=0)
1587
+ if(d==1)
1588
+ {
1589
+ map alpha=S,var(1)-singL[2][2],var(2)-singL[1][2];
1590
+ f=alpha(f);
1591
+ ring C = create_ring(ring_list(S)[1], "("+varstr(S)+")", "ds", "no_minpoly");
1592
+ poly f=imap(S,f);
1593
+ ideal singL=imap(S,singL);
1594
+ if((w>=1)&&(ord(f)>=2))
1595
+ {
1596
+ "local analysis of the singularities";"";
1597
+ basering;
1598
+ singL;
1599
+ f;
1600
+ pause();
1601
+ }
1602
+ }
1603
+ else
1604
+ {
1605
+ poly p;
1606
+ poly c;
1607
+ map psi;
1608
+ number co;
1609
+
1610
+ while((deg(lead(singL[1]))>1)&&(deg(lead(singL[2]))>1))
1611
+ {
1612
+ psi=S,x,y+random(-100,100)*x;
1613
+ singL=psi(singL);
1614
+ singL=std(singL);
1615
+ f=psi(f);
1616
+ }
1617
+
1618
+ if(deg(lead(singL[2]))==1)
1619
+ {
1620
+ p=singL[1];
1621
+ c=singL[2]-lead(singL[2]);
1622
+ co=leadcoef(singL[2]);
1623
+ }
1624
+ if(deg(lead(singL[1]))==1)
1625
+ {
1626
+ psi=S,y,x;
1627
+ f=psi(f);
1628
+ singL=psi(singL);
1629
+ p=singL[2];
1630
+ c=singL[1]-lead(singL[1]);
1631
+ co=leadcoef(singL[1]);
1632
+ }
1633
+
1634
+ ring B = create_ring(ring_list(S)[1], "a", "dp", "no_minpoly");
1635
+ map beta=S,a,a;
1636
+ poly p=beta(p);
1637
+
1638
+ ring C = create_ring("("+charstr(S)+",a)", "("+varstr(S)+")", "ds");
1639
+ number p=number(imap(B,p));
1640
+ minpoly=p;
1641
+
1642
+ map iota=S,a,a;
1643
+ number c=number(iota(c));
1644
+ number co=iota(co);
1645
+
1646
+ map alpha=S,x-c/co,y+a;
1647
+ poly f=alpha(f);
1648
+ f=cleardenom(f);
1649
+ if((w>=1)&&(ord(f)>=2))
1650
+ {
1651
+ "local analysis of the singularities";"";
1652
+ basering;
1653
+ alpha;
1654
+ f;
1655
+ pause();
1656
+ "";
1657
+ }
1658
+ }
1659
+ int intMult = deg(lead(f));
1660
+ poly fdummy = f;
1661
+ poly gdummy = lead(f);
1662
+ int ivr = 1;
1663
+ while(ivr)
1664
+ {
1665
+ fdummy = fdummy - lead(fdummy);
1666
+ if((fdummy ==0) || (deg(lead(fdummy))>intMult)){break;}
1667
+ gdummy = gdummy + lead(fdummy);
1668
+ }
1669
+ poly SQRpart = sqrfree(gdummy, 3);
1670
+ int IntForRet;
1671
+ if(deg(SQRpart)==intMult)
1672
+ {
1673
+ IntForRet = intMult;
1674
+ }
1675
+ option(noredSB);
1676
+ ideal fstd=std(ideal(f)+jacob(f));
1677
+ poly hc=highcorner(fstd);
1678
+ int tau=vdim(fstd);
1679
+ int o=ord(f);
1680
+ int delt,nb;
1681
+
1682
+ if(tau==0) //smooth case
1683
+ {
1684
+ setring R;
1685
+ return(list(0,0,1,0));
1686
+ }
1687
+ if((char(basering)>=181)||(char(basering)==0))
1688
+ {
1689
+ if(o==2) //A_k-singularity
1690
+ {
1691
+ if(w>=1){"A_k-singularity";"";}
1692
+ setring R;
1693
+ delt=(tau+1) div 2;
1694
+ return(list(d*delt,d*tau,d*(2*delt-tau+1),IntForRet));
1695
+ }
1696
+ if((lead(f)==var(1)*var(2)^2)||(lead(f)==var(1)^2*var(2)))
1697
+ {
1698
+ if(w>=1){"D_k- singularity";"";}
1699
+
1700
+ setring R;
1701
+ delt=(tau+2) div 2;
1702
+ return(list(d*delt,d*tau,d*(2*delt-tau+1),IntForRet));
1703
+ }
1704
+
1705
+ int mu=vdim(std(jacob(f)));
1706
+ poly g=f+var(1)^mu+var(2)^mu; //to obtain a convenient Newton-polygon
1707
+
1708
+ list NP=newtonpoly(g);
1709
+ if(w>=1){"Newton-Polygon:";NP;"";}
1710
+ int s=size(NP);
1711
+
1712
+ if(is_NND(f,mu,NP))
1713
+ { // the Newton-polygon is non-degenerate
1714
+ // compute nb, the number of branches
1715
+ for(i=1;i<=s-1;i++)
1716
+ {
1717
+ nb=nb+gcd(NP[i][2]-NP[i+1][2],NP[i][1]-NP[i+1][1]);
1718
+ }
1719
+ if(w>=1){"Newton-Polygon is non-degenerated";"";}
1720
+ return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
1721
+ }
1722
+
1723
+ if(w>=1){"Newton-Polygon is degenerated";"";}
1724
+
1725
+ // the following can certainly be made more efficient when replacing
1726
+ // 'hnexpansion' (used only for computing number of branches) by
1727
+ // successive blowing-up + test if Newton polygon degenerate:
1728
+ if(s>2) // splitting of f
1729
+ {
1730
+ if(w>=1){"Newton polygon can be used for splitting";"";}
1731
+ intvec v=NP[1][2]-NP[2][2],NP[2][1];
1732
+ int de=w_deg(g,v);
1733
+ int st=w_deg(hc,v)+v[1]+v[2];
1734
+ poly f1=var(2)^NP[2][2];
1735
+ poly f2=jet(g,de,v)/var(2)^NP[2][2];
1736
+ poly h=g-f1*f2;
1737
+ de=w_deg(h,v);
1738
+ poly k;
1739
+ ideal wi=var(2)^NP[2][2],f2;
1740
+ matrix li;
1741
+ while(de<st)
1742
+ {
1743
+ k=jet(h,de,v);
1744
+ li=lift(wi,k);
1745
+ f1=f1+li[2,1];
1746
+ f2=f2+li[1,1];
1747
+ h=g-f1*f2;
1748
+ de=w_deg(h,v);
1749
+ }
1750
+ nb=deltaLocMod(f1,maxideal(1))[3]+deltaLocMod(f2,maxideal(1))[3];
1751
+ setring R;
1752
+ return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
1753
+ }
1754
+
1755
+ f=jet(f,deg(hc)+2);
1756
+ if(w>=1){"now we have to use Hamburger-Noether (Puiseux) expansion";}
1757
+ ideal fac=factorize(f,1);
1758
+ if(size(fac)>1)
1759
+ {
1760
+ nb=0;
1761
+ for(i=1;i<=size(fac);i++)
1762
+ {
1763
+ nb=nb+deltaLocMod(fac[i],maxideal(1))[3];
1764
+ }
1765
+ setring R;
1766
+ return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
1767
+ }
1768
+ list HNEXP=hnexpansion(f);
1769
+ if (typeof(HNEXP[1])=="ring") {
1770
+ def altring = basering;
1771
+ def HNEring = HNEXP[1]; setring HNEring;
1772
+ nb=size(hne);
1773
+ setring R;
1774
+ kill HNEring;
1775
+ }
1776
+ else
1777
+ {
1778
+ nb=size(HNEXP);
1779
+ }
1780
+ return(list(d*(mu+nb-1) div 2,d*tau,d*nb,IntForRet));
1781
+ }
1782
+ else //the case of small characteristic
1783
+ {
1784
+ f=jet(f,deg(hc)+2);
1785
+ if(w>=1){"now we have to use Hamburger-Noether (Puiseux) expansion";}
1786
+ delt=delta(f);
1787
+ return(list(d*delt,d*tau,d,IntForRet));
1788
+ }
1789
+ }
1790
+
1791
+ ///////////////////////////////////////////////////////////////////////////////
1792
+ proc paraConic(poly q)
1793
+ "USAGE: paraConic(q); q poly
1794
+ ASSUME: The basering must be a polynomial ring in three variables with
1795
+ coefficients in Q. @*
1796
+ The polynomial q must be homogeneous of degree 2 and absolutely
1797
+ irreducible. @*
1798
+ NOTE: The procedure might fail or give a wrong output if the assumptions
1799
+ do not hold.
1800
+
1801
+ RETURN: ring with an ideal PARACONIC. The ring should be considered as the
1802
+ homogeneous coordinate ring of PP^1, the ideal defines a rational
1803
+ parametrization PP^1 --> C2 = {q=0}.
1804
+
1805
+ THEORY: We compute a point on C2 via @ref{rationalPointConic}. The pencil of
1806
+ lines through this point projects C2 birationally to PP^1. Inverting
1807
+ the projection gives the result.
1808
+ KEYWORDS: conic, parametrization, rational point.
1809
+ SEE ALSO: rationalPointConic.
1810
+ EXAMPLE: example paraConic; shows an example
1811
+ "
1812
+ {
1813
+ def Roriginal = basering;
1814
+ def RP2 = projConic(q); // ring with ideal Ipoint
1815
+ // possibly defined over algebraic number field
1816
+ setring RP2;
1817
+ def rp1 = invertBirMap(Ipoint, ideal(fetch(Roriginal,q)));
1818
+ setring rp1;
1819
+ list rl = ring_list(rp1);
1820
+ rl[2] = list("s","t");
1821
+ def RP1 = ring(rl);
1822
+ setring RP1;
1823
+ ideal PARACONIC = fetch(rp1,psi);
1824
+ export(PARACONIC);
1825
+ int p = printlevel - voice + 3;
1826
+ dbprint(p,"// 'paraConic' created a ring together with an ideal RNC.
1827
+ // Supposing you typed, say, def RP1 = paraConic(q);
1828
+ // you may access the ideal by typing
1829
+ // setring RP1; PARACONIC;");
1830
+ return(RP1);
1831
+ }
1832
+ example
1833
+ { "EXAMPLE:"; echo=2;
1834
+ ring R = 0,(x,y,z),dp;
1835
+ poly f = y^8-x^3*(z+x)^5;
1836
+ ideal adj = adjointIdeal(f);
1837
+ def Rn = invertBirMap(adj,ideal(f));
1838
+ setring(Rn);
1839
+ J;
1840
+ def Rc = rncItProjEven(J);
1841
+ PHI;
1842
+ setring Rc;
1843
+ CONIC;
1844
+ def RPc = paraConic(CONIC);
1845
+ setring RPc;
1846
+ PARACONIC;
1847
+ }
1848
+
1849
+ ///////////////////////////////////////////////////////////////////////////////
1850
+ static proc projConic(poly q)
1851
+ "USAGE: projConic(q); q poly
1852
+ ASSUME: The basering must be a polynomial ring in three variables with
1853
+ coefficients in Q. @*
1854
+ The polynomial q must be homogeneous of degree 2 and absolutely
1855
+ irreducible. @*
1856
+ NOTE: The procedure might fail or give a wrong output if the assumptions
1857
+ do not hold.
1858
+ RETURN: ring with an ideal Ipoint defining a pencil of lines through a point
1859
+ on the conic C2 = {q=0}. This point has either coefficients in Q or
1860
+ in a quadratic extension field of Q.
1861
+ THEORY: We compute the point on C2 via @ref rationalPointConic.
1862
+ KEYWORDS: conic, parametrization, rational point.
1863
+ SEE ALSO: rationalPointConic.
1864
+ "
1865
+ {
1866
+ def Roriginal = basering;
1867
+ list rl = ring_list(Roriginal);
1868
+ rl[3] = list(list("dp",1:3),list("C",0));
1869
+ def RP20 = ring(rl);
1870
+ setring RP20;
1871
+ poly q = imap(Roriginal,q);
1872
+ def RP21 = rationalPointConic(q); // ring with ideal point representing
1873
+ // point on conic
1874
+ // possibly defined over algebraic number
1875
+ // field
1876
+ setring RP21;
1877
+ list rl1 = ring_list(RP21);
1878
+ rl1[2] = list("u","v","w");
1879
+ rl1[3] = list(list("dp",1:3),list("C",0));
1880
+ def RP2 = ring(rl1);
1881
+ setring RP2;
1882
+ ideal point = fetch(RP21,point);
1883
+ matrix bP = syz(point);
1884
+ ideal Ipoint = matrix(maxideal(1))*bP; // defines pencil of lines through
1885
+ // point
1886
+ export(Ipoint);
1887
+ return(RP2);
1888
+ }
1889
+
1890
+
1891
+ ///////////////////////////////////////////////////////////////////////////////
1892
+ static proc isIrreducible(poly f)
1893
+ "USAGE: isIrreducible(f); f poly
1894
+ RETURN: 1 iff the given polynomial f is irreducible; 0 otherwise.
1895
+ THEORY: This test is performed by computing the absolute factorization of f.
1896
+ KEYWORDS: irreducible.
1897
+ "
1898
+ {
1899
+ def r = basering;
1900
+ def s = absFactorize(f);
1901
+ setring s;
1902
+ list L = absolute_factors;
1903
+ int result = 0;
1904
+ if (L[4] == 1){result = 1;}
1905
+ setring r;
1906
+ kill s;
1907
+ return (result);
1908
+ }
1909
+
1910
+
1911
+ ///////////////////////////////////////////////////////////////////////////////
1912
+ static proc isQuadratic(poly p)
1913
+ "USAGE: isQuadratic(p); p poly
1914
+ RETURN: checks whether p is a homogeneous, quadratic polynomial in the
1915
+ first three ring variables, x, y, z say;
1916
+ If so, the method extracs the coefficients a, b, ..., f such that
1917
+ p = a*x2 + b*xy + c * y2 + d * xz + e * yz + f * z2
1918
+ and returns them as a list of seven entries, [1, a, b, c, d, e, f];
1919
+ otherwise, a list with the single entry [0] is returned
1920
+ "
1921
+ {
1922
+ p=system("content",p); // clear denominator, remove content
1923
+ bigint a = bigint(leadcoef(subst(p, var(2), 0, var(3), 0)));
1924
+ bigint c = bigint(leadcoef(subst(p, var(1), 0, var(3), 0)));
1925
+ bigint f = bigint(leadcoef(subst(p, var(1), 0, var(2), 0)));
1926
+ poly h = p - a * var(1)^2 - c * var(2)^2 - f * var(3)^2;
1927
+ bigint b = bigint(leadcoef(subst(h, var(3), 0)));
1928
+ bigint d = bigint(leadcoef(subst(h, var(2), 0)));
1929
+ bigint e = bigint(leadcoef(subst(h, var(1), 0)));
1930
+ list L = 0;
1931
+ if (h - b * var(1) * var(2) - d * var(1) * var(3)
1932
+ - e * var(2) * var(3) != 0) { return (L); }
1933
+ L = 1, a, b, c, d, e, f;
1934
+ return (L);
1935
+ }
1936
+
1937
+
1938
+ ///////////////////////////////////////////////////////////////////////////////
1939
+ static proc largestSquare(bigint n)
1940
+ "USAGE: largestSquare(n); n bigint
1941
+ ASSUME: n <> 0
1942
+ RETURN: returns the largest positive number m (as bigint) such that m^2
1943
+ divides n.
1944
+ THEORY: This computation is done by prime factorization of n.
1945
+ KEYWORDS: prime factorization.
1946
+ "
1947
+ {
1948
+ if (n == 0) { "ERROR: largestSquare(0) had been invoked"; }
1949
+
1950
+ bigint nn = n; if (nn < 0) { nn = -n; }
1951
+ list L = primefactors(nn);
1952
+ if (L[3] != 1)
1953
+ { "WARNING: command 'primefactors(.)' did not find all prime factors"; }
1954
+ int i; bigint m = bigint(1); int e; int j;
1955
+ for (i = 1; i <= size(L[1]); i++)
1956
+ {
1957
+ e = L[2][i] div 2;
1958
+ for (j = 1; j <= e; j++) { m = m * bigint(L[1][i]); }
1959
+ }
1960
+ return (m);
1961
+ }
1962
+
1963
+
1964
+ ///////////////////////////////////////////////////////////////////////////////
1965
+ static proc jIndex(bigint a, bigint b, bigint c)
1966
+ "USAGE: jIndex(a, b, c); a, b, c bigint's
1967
+ RETURN: returns the middle of the three numbers |ab|, |bc|, and |ca|.
1968
+ "
1969
+ {
1970
+ bigint n1 = a*b; if (n1 < 0) { n1 = -n1; }
1971
+ bigint n2 = b*c; if (n2 < 0) { n2 = -n2; }
1972
+ bigint n3 = c*a; if (n3 < 0) { n3 = -n3; }
1973
+ if ((n1 <= n2) && (n2 <= n3)) { return (n2); }
1974
+ if ((n1 >= n2) && (n2 >= n3)) { return (n2); }
1975
+ if ((n2 <= n1) && (n1 <= n3)) { return (n1); }
1976
+ if ((n2 >= n1) && (n1 >= n3)) { return (n1); }
1977
+ return (n3);
1978
+ }
1979
+
1980
+
1981
+ ///////////////////////////////////////////////////////////////////////////////
1982
+ static proc aMod(bigint a, bigint b)
1983
+ "USAGE: aMod(a,b); a, b bigint
1984
+ RETURN: r bigint
1985
+ THEORY: The asymmetric residue r of the division with remainder a mod b.
1986
+ "
1987
+ {
1988
+ bigint c = a mod b;
1989
+ if (c<0)
1990
+ {
1991
+ return(c+b);
1992
+ }
1993
+ return(c);
1994
+ }
1995
+
1996
+ ///////////////////////////////////////////////////////////////////////////////
1997
+ static proc aDiv(bigint a, bigint b)
1998
+ "USAGE: aDiv(a,b); a, b bigint
1999
+ RETURN: q bigint
2000
+ THEORY: Quotient with remainder q = a div b with asymmetric residue.
2001
+ "
2002
+ {
2003
+ bigint q = a div b;
2004
+ if ((a mod b)<0)
2005
+ {
2006
+ return(q-1);
2007
+ }
2008
+ return(q);
2009
+ }
2010
+
2011
+
2012
+
2013
+ ///////////////////////////////////////////////////////////////////////////////
2014
+ static proc polyModP(poly q, bigint p)
2015
+ "USAGE: polyModP(q, p); q poly, p bigint
2016
+ RETURN: takes each coefficient of q modulo p and returns the resulting poly
2017
+ "
2018
+ {
2019
+ poly qq = q; poly res = 0;
2020
+ bigint c;
2021
+ while (qq != 0)
2022
+ {
2023
+ c = bigint(leadcoef(qq)) mod p;
2024
+ res = res + c * leadmonom(qq);
2025
+ qq = qq - lead(qq);
2026
+ }
2027
+ return (res);
2028
+ }
2029
+
2030
+
2031
+ ///////////////////////////////////////////////////////////////////////////////
2032
+ static proc rootModP(bigint r, bigint p)
2033
+ "USAGE: rootModP(r, p); r, p bigint's
2034
+ ASSUME: 0 <= r < p, and p prime;
2035
+ Furthermore it is assumes that there is some x in {0, 1, ..., p-1}
2036
+ such that x^2 = r mod p;
2037
+ RETURN: an x in {0, 1, ..., p-1} such that x^2 = r mod p;
2038
+ THEORY: For p larger than 32003, this computation is done using Cantor-
2039
+ Zassenhaus' algorithm. Otherwise a brute force approach is used.
2040
+ KEYWORDS: Cantor-Zassenhaus algorithm.
2041
+ "
2042
+ {
2043
+ if (r == 0) { return (0); }
2044
+ if (r == 1) { return (1); }
2045
+ if (p <= 32003)
2046
+ {
2047
+ /* For small p, we use a brute force approach: */
2048
+ int i;
2049
+ for (i = 2; i < p; i++)
2050
+ {
2051
+ if (((i*i) mod p) == r) { return (i); }
2052
+ }
2053
+ /* should never be reached: */
2054
+ return (-1);
2055
+ }
2056
+
2057
+ /* For p > 32003, we use Cantor-Zassenhaus' algorithm: */
2058
+ def br = basering;
2059
+ ring rTemp = 0, x, dp;
2060
+ bigint b; bigint exponent; poly factor;
2061
+ poly h = x^2 - r;
2062
+ ideal redI = h; redI = std(redI);
2063
+ poly q = x^2; bigint root = 0;
2064
+ while (root == 0)
2065
+ {
2066
+ b = bigint(random(1, 2^30));
2067
+ exponent = bigint((p - 1) div 2);
2068
+ /* We need to compute q^exponent mod (x^2 - a) and mod p: */
2069
+ factor = x + b; q = 1;
2070
+ while (exponent > 0)
2071
+ {
2072
+ if ((exponent mod 2) == 1)
2073
+ {
2074
+ q = q * factor;
2075
+ q = reduce(q, redI);
2076
+ q = polyModP(q, p);
2077
+ }
2078
+ exponent = bigint(exponent div 2);
2079
+ factor = factor * factor;
2080
+ factor = reduce(factor, redI);
2081
+ factor = polyModP(factor, p);
2082
+ }
2083
+ if (deg(q) == 1)
2084
+ {
2085
+ q = q - 1;
2086
+ b = inverseModP(bigint(leadcoef(q)), p);
2087
+ q = q - lead(q);
2088
+ root = aMod((bigint(q) * b),p);
2089
+ if (((root * root - r) mod p) != 0) { root = 0; }
2090
+ }
2091
+ }
2092
+ setring br; kill rTemp;
2093
+ return (root);
2094
+ }
2095
+
2096
+
2097
+ ///////////////////////////////////////////////////////////////////////////////
2098
+ static proc inverseModP(bigint r, bigint p)
2099
+ "USAGE: inverseModP(r, p); r, p bigint's
2100
+ ASSUME: 0 <= r < p, and r and p coprime;
2101
+ RETURN: returns the inverse of r in Z/p represented by an element in
2102
+ {1, 2, ..., p-1}
2103
+ THEORY: This uses Euclid's extended gcd algorithm.
2104
+ "
2105
+ {
2106
+ list L = extgcd(r, p);
2107
+ if (L[1] != 1) { ERROR("GCD of", r, "and", p, "should be 1."); }
2108
+ L[2] = aMod(L[2],p);
2109
+ return (L[2]);
2110
+ }
2111
+
2112
+
2113
+ ///////////////////////////////////////////////////////////////////////////////
2114
+ static proc squareRoot(bigint r, bigint m, int justCheck)
2115
+ "USAGE: squareRoot(r, m, j); r, m bigint's, j int
2116
+ RETURN: checks whether r is a square modulo m, i.e., checks whether there is
2117
+ some x such that x^2 = r mod m;
2118
+ If justCheck is 1, then the method will terminate after the check
2119
+ and return 1 if r is a square and -1 otherwise.
2120
+ If justCheck is 0 and r is a square, then the method continues and
2121
+ computes a solution x in {0, 1, m-1} with x^2 = r mod m, which will
2122
+ then be returned
2123
+ THEORY: This algorithm checks solvability by computing the Legendre symbols
2124
+ modulo all primes in m. Then, individual roots will be computed and
2125
+ lifted to the desired square root modulo m using Chinese
2126
+ remaindering.
2127
+ "
2128
+ {
2129
+ if (m == 0) { "ERROR: squareRoot had been invoked with m = 0"; }
2130
+
2131
+ list L = primefactors(m);
2132
+ if ((L[3] != 1) && (L[3] != -1))
2133
+ { "WARNING: command 'primefactors(.)' did not find all prime factors"; }
2134
+ int i;
2135
+ for (i = 1; i <= size(L[2]); i++)
2136
+ {
2137
+ if (legendreSymbol(r, L[1][i]) == -1) { return (-1); }
2138
+ }
2139
+ /* now we know that there is some x in {0, 1, m-1} with
2140
+ x^2 = r mod m */
2141
+ if (justCheck == 1) { return (1); }
2142
+ else
2143
+ {
2144
+ // now we need to compute x; this works in two stages:
2145
+ // 1) write m = p1^e1 * ... * pk^ek (we already have that),
2146
+ // 2) for each i in {1, 2, ..., k}
2147
+ // 2.1) compute a yi such that yi^2 = r mod pi,
2148
+ // 2.2) lift yi to an xi such that xi^2 = r mod (pi^ei),
2149
+ // 3) lift (x1, x2, ..., xk) in Z/p1^e1 * ... * Z/pk^ek
2150
+ // to x in Z/m via Chinese remainder theorem
2151
+
2152
+ list roots;
2153
+ // 2.1):
2154
+ for (i = 1; i <= size(L[1]); i++)
2155
+ {
2156
+ roots = insert(roots, rootModP(aMod(r,L[1][i]), L[1][i]), size(roots));
2157
+ }
2158
+
2159
+ // 2.2):
2160
+ bigint c; bigint l; bigint temp; bigint pPower; int e;
2161
+ for (i = 1; i <= size(roots); i++)
2162
+ {
2163
+ pPower = bigint(L[1][i]);
2164
+ for (e = 2; e <= L[2][i]; e++)
2165
+ {
2166
+ c = bigint(roots[i]); l = pPower;
2167
+ temp = r - c * c; l = bigint(2) * c * l; c = temp;
2168
+ c = aDiv(c,pPower); l = aDiv(l,pPower);
2169
+ c = aMod(c,L[1][i]); l = aMod(l,L[1][i]);
2170
+ c = aMod((c * bigint(inverseModP(l, L[1][i]))), L[1][i]);
2171
+ c = bigint(roots[i]) + c * pPower;
2172
+ pPower = pPower * L[1][i]; roots[i] = c;
2173
+ }
2174
+ }
2175
+
2176
+ // 2.3):
2177
+ list mm; bigint z; int j;
2178
+ for (i = 1; i <= size(L[1]); i++)
2179
+ {
2180
+ z = bigint(L[1][i]);
2181
+ for (j = 2; j <= L[2][i]; j++)
2182
+ {
2183
+ z = z * bigint(L[1][i]);
2184
+ }
2185
+ mm = insert(mm, z, size(mm));
2186
+ }
2187
+ return (aMod(chinrem(roots, mm) , m));
2188
+ }
2189
+ }
2190
+
2191
+
2192
+ ///////////////////////////////////////////////////////////////////////////////
2193
+ static proc chineseRemainder(list rr, list mm)
2194
+ "USAGE: chineseRemainder(rr, mm); rr, mm lists of bigint's
2195
+ ASSUME: lists rr and mm must have same sizes;
2196
+ Furthermore the entries of mm must be mutually coprime.
2197
+ RETURN: an x which fulfills the simultaneous remainder conditions
2198
+ x = rr[i] mod mm[i], 1 <= i <= size(rr)
2199
+ KEYWORDS: Chinese remainder.
2200
+ "
2201
+ {
2202
+ bigint x = bigint(0); int i; bigint N; list l;
2203
+ bigint M = bigint(mm[1]);
2204
+ for (i = 2; i <= size(mm); i++) { M = M * bigint(mm[i]); }
2205
+ for (i = 1; i <= size(mm); i++)
2206
+ {
2207
+ N = aDiv(M,mm[i]);
2208
+ l = extgcd(mm[i], N);
2209
+ x = x + rr[i]*l[3]*N;
2210
+ }
2211
+ return (x);
2212
+ }
2213
+
2214
+
2215
+ ///////////////////////////////////////////////////////////////////////////////
2216
+ static proc rationalPointSpecial(bigint b1, bigint c1)
2217
+ "USAGE: rationalPointSpecial(b1, c1); b1, c1 bigint's
2218
+ ASSUME: b1 <> 0 and c1 <> 0;
2219
+ RETURN: with poly p = var(1)^2 + b1 * var(2)^2 + c1 * var(3)^2, the method
2220
+ returns a list L with either one entry or four entries:
2221
+ case 'three entries':
2222
+ L[1] = 0 signaling that there is no rational point on V(p),
2223
+ L[2] the largest number b such that b^2 divides b1
2224
+ (for subsequent use by the caller of this method),
2225
+ L[3] the largest number c such that c^2 divides c1
2226
+ (for subsequent use by the caller of this method);
2227
+ case 'four entries':
2228
+ L[1] = 1 signaling that there is a rational point on V(p),
2229
+ L[2], L[3], L[4] rational numbers such that the tuple
2230
+ (L[2], L[3], L[4]) is on V(p)
2231
+ "
2232
+ {
2233
+ if (b1 == 0) { "ERROR: rationalPointSpecial(0, c1) had been invoked"; }
2234
+ if (c1 == 0) { "ERROR: rationalPointSpecial(b1, 0) had been invoked"; }
2235
+
2236
+ bigint b_s = largestSquare(b1); bigint b_r = b1/b_s/b_s;
2237
+ bigint c_s = largestSquare(c1); bigint c_r = c1/c_s/c_s;
2238
+ bigint g = gcd(b_r, c_r);
2239
+ def S=basering;
2240
+ ideal mi = maxideal(1);
2241
+ map mm = basering, mi; map mTemp;
2242
+ mm[1] = var(1); mm[2] = var(2)/b_s/g; mm[3] = var(3)/c_s/g;
2243
+ bigint a = g; bigint aa = a; if (aa <= 0) { aa = -aa; }
2244
+ bigint b = b_r/g; bigint bb = b; if (bb <= 0) { bb = -bb; }
2245
+ bigint c = c_r/g; bigint cc = c; if (cc <= 0) { cc = -cc; }
2246
+ bigint R1 = squareRoot(-a*b, cc, 1);
2247
+ if (R1 == -1) { list L = 0, b_s, c_s; return (L); }
2248
+ bigint R2 = squareRoot(-a*c, bb, 1);
2249
+ if (R2 == -1) { list L = 0, b_s, c_s; return (L); }
2250
+ bigint R3 = squareRoot(-b*c, aa, 1);
2251
+ if (R3 == -1) { list L = 0, b_s, c_s; return (L); }
2252
+ bigint t; bigint r1; bigint Q; bigint A; bigint B; bigint C;
2253
+ bigint alpha; bigint beta; bigint gamma;
2254
+ while (jIndex(a, b, c) > 1)
2255
+ {
2256
+ mTemp = basering, mi;
2257
+ if (aa > cc)
2258
+ {
2259
+ t = a; a = c; c = t;
2260
+ t = aa; aa = cc; cc = t;
2261
+ mTemp = basering, mi;
2262
+ mTemp[1] = var(3); mTemp[3] = var(1); mm = mTemp(mm);
2263
+ }
2264
+ if (bb > cc)
2265
+ {
2266
+ t = b; b = c; c = t;
2267
+ t = bb; bb = cc; cc = t;
2268
+ mTemp = basering, mi;
2269
+ mTemp[2] = var(3); mTemp[3] = var(2); mm = mTemp(mm);
2270
+ }
2271
+ if (bb < aa)
2272
+ {
2273
+ t = b; b = a; a = t;
2274
+ t = bb; bb = aa; aa = t;
2275
+ mTemp = basering, mi;
2276
+ mTemp[1] = var(2); mTemp[2] = var(1); mm = mTemp(mm);
2277
+ }
2278
+ /* now, we have established |a| <= |b| <= |c|; and permuted
2279
+ the map mm, accordingly */
2280
+ cc = c; if (cc <= 0) { cc = -cc; }
2281
+ R1 = squareRoot(-a*b, cc, 0);
2282
+ r1 = aMod((R1 * inverseModP(a, cc)), cc);
2283
+ if (r1*bigint(2) > cc) { r1 = r1 - cc; }
2284
+ Q = (a*r1*r1 + b)/c;
2285
+ if (Q == 0)
2286
+ {
2287
+ list L = 1, subst(mm[1], var(1), 1, var(2), 1, var(3), 0),
2288
+ subst(mm[2], var(1), 1, var(2), 1, var(3), 0),
2289
+ subst(mm[3], var(1), 1, var(2), 1, var(3), 0);
2290
+ return (L);
2291
+ }
2292
+ A = gcd(gcd(a*r1*r1, b), c*Q);
2293
+ alpha = r1/A; beta = b/A;
2294
+ B = a*beta;
2295
+ gamma = largestSquare(Q/A);
2296
+ C = Q/A/gamma/gamma;
2297
+ mTemp = basering, mi;
2298
+ mTemp[1] = A*alpha*var(1) - beta*var(2);
2299
+ mTemp[2] = var(1) + a*alpha*var(2);
2300
+ mTemp[3] = C*gamma*var(3);
2301
+ mm = mTemp(mm);
2302
+ a = A; b = B; c = C;
2303
+ aa = a; if (aa <= 0) { aa = -aa; }
2304
+ bb = b; if (bb <= 0) { bb = -bb; }
2305
+ cc = c; if (cc <= 0) { cc = -cc; }
2306
+ }
2307
+ if (a*b < 0)
2308
+ {
2309
+ list L = 1, subst(mm[1], var(1), 1, var(2), 1, var(3), 0),
2310
+ subst(mm[2], var(1), 1, var(2), 1, var(3), 0),
2311
+ subst(mm[3], var(1), 1, var(2), 1, var(3), 0);
2312
+ return (L);
2313
+ }
2314
+ if (a*c < 0)
2315
+ {
2316
+ list L = 1, subst(mm[1], var(1), 1, var(2), 0, var(3), 1),
2317
+ subst(mm[2], var(1), 1, var(2), 0, var(3), 1),
2318
+ subst(mm[3], var(1), 1, var(2), 0, var(3), 1);
2319
+ return (L);
2320
+ }
2321
+ if (b*c < 0)
2322
+ {
2323
+ list L = 1, subst(mm[1], var(1), 0, var(2), 1, var(3), 1),
2324
+ subst(mm[2], var(1), 0, var(2), 1, var(3), 1),
2325
+ subst(mm[3], var(1), 0, var(2), 1, var(3), 1);
2326
+ return (L);
2327
+ }
2328
+ list L = 0, b_s, c_s; return (L);
2329
+ }
2330
+
2331
+
2332
+ ///////////////////////////////////////////////////////////////////////////////
2333
+ static proc extendedEuclid(bigint a, bigint b)
2334
+ "USAGE: extendedEuclid(a, b); a, b bigint's
2335
+ ASSUME: a <> 0 or b <> 0;
2336
+ RETURN: returns a list with three entries:
2337
+ _[1]: gcd(a,b) > 0,
2338
+ _[2], _[3]: s, t, such that s*a + t*b = gcd(a,b)
2339
+ KEYWORDS: extended Euclidean algorithm.
2340
+ "
2341
+ {
2342
+ list l = 0; bigint temp;
2343
+ if (a == 0) { l = b, 0, 1; if (b < 0) { l = -b, 0, -1; } }
2344
+ if (b == 0) { l = a, 1, 0; if (a < 0) { l = -a, -1, 0; } }
2345
+ if (aMod(a , b) == 0) { l = b, 0, 1; if (b < 0) { l = -b, 0, -1; } }
2346
+ if (aMod(b , a) == 0) { l = a, 1, 0; if (a < 0) { l = -a, -1, 0; } }
2347
+ if (size(l) > 1) { return (l); }
2348
+
2349
+ temp = aMod(a , b);
2350
+ l = extendedEuclid(b, temp);
2351
+ temp = (a - temp) / b;
2352
+ temp = bigint(l[2]) - temp * bigint(l[3]);
2353
+ l = l[1], l[3], temp;
2354
+ return (l);
2355
+ }
2356
+
2357
+ static proc legendreSymbol(bigint r, bigint p)
2358
+ "assumes p prime;
2359
+ returns the Legendre symbol (r/p), that is
2360
+ 1 if r appears as residue modulo p of a square,
2361
+ -1 if not,
2362
+ 0 if r is a multiple of p
2363
+ "
2364
+ {
2365
+ bigint rr = aMod(r , p);
2366
+ if (rr == 0) { return (0) }
2367
+ if (rr == 1) { return (1) }
2368
+ /* now, p must be at least 3 */
2369
+ bigint e = (p - 1) / bigint(2);
2370
+ bigint result = 1;
2371
+ bigint power = rr;
2372
+ while (e > 0)
2373
+ {
2374
+ if ((e mod 2) == 1) { result = aMod((result * power), p); }
2375
+ e = e / bigint(2);
2376
+ power = aMod((power * power), p);
2377
+ }
2378
+ if (result > 1) { result = result - p; /* should be -1 */ }
2379
+ return (result);
2380
+ }
2381
+
2382
+
2383
+ ///////////////////////////////////////////////////////////////////////////////
2384
+ static proc buildExtension(bigint b, bigint c, bigint bs, bigint cs)
2385
+ "USAGE: buildExtension(b, c, bs, cs); b, c, bs, cs bigint's
2386
+ ASSUME: assumes that bs is the largest positive number such that bs^2
2387
+ divides b; analogously for cs regarding c;
2388
+ Assumes furthermore that there is no rational point on the conic
2389
+ X^2 + b*Y^2 + c*Z^2 = 0.
2390
+ Assumes that the ground field of the basering is Q.
2391
+ RETURN: builds an appropriate quadratic field extension Q(a) in which a
2392
+ point exists that lies on the given conic. This point is stored in
2393
+ a newly defined and exported (1x3) matrix named 'point'.
2394
+ The method returns the resulting polynomial ring over Q(a).
2395
+ "
2396
+ {
2397
+ bigint br = b/bs/bs;
2398
+ bigint cr = c/cs/cs;
2399
+ /* X^2 + br*bs^2*Y^2 + cr*cs^2*Z^2 = 0 */
2400
+ def bRing = basering;
2401
+ list L = ring_list(bRing);
2402
+
2403
+ if (b != 0)
2404
+ {
2405
+ L[1] = list(0, list("a"), list(list("lp", 1)), ideal(0));
2406
+ def RTemp = ring(L);
2407
+ setring RTemp; list L = ringlist(RTemp);
2408
+ L[1][4] = ideal(a^2 + br);
2409
+ def R = ring(L);
2410
+ setring R; kill RTemp;
2411
+ matrix point[1][3];
2412
+ point[1, 1] = a * bs; point[1, 2] = 1; point[1, 3] = 0;
2413
+ export point;
2414
+ setring bRing;
2415
+ return (R);
2416
+ }
2417
+ if (c != 0)
2418
+ {
2419
+ L[1] = list(0, list("a"), list(list("lp", 1)), ideal(0));
2420
+ def RTemp = ring(L);
2421
+ setring RTemp; list L = ringlist(RTemp);
2422
+ L[1][4] = ideal(a^2 + cr);
2423
+ def R = ring(L);
2424
+ setring R; kill RTemp;
2425
+ matrix point[1][3];
2426
+ point[1, 1] = a * cs; point[1, 2] = 0; point[1, 3] = 1;
2427
+ export point;
2428
+ setring bRing;
2429
+ return (R);
2430
+ }
2431
+
2432
+ "ERROR: unexpectedly encountered conic X^2 + 0*Y^2 + 0*Z^2 = 0";
2433
+ return (bRing);
2434
+ }
2435
+
2436
+
2437
+ ///////////////////////////////////////////////////////////////////////////////
2438
+ static proc testRationalPointConic(poly pp)
2439
+ "USAGE: testRationalPointConic(pp); pp poly
2440
+ RETURN: returns 0 in case of unexpected input (e.g. non-quadratic,
2441
+ reducible); 1 otherwise
2442
+ NOTE: This method calls rationalPointConic, measures time consumption
2443
+ and checks whether the computed point lies indeed on the conic pp.
2444
+ The results will be printed to standard output.
2445
+ "
2446
+ {
2447
+ "testing rationalPointConic(poly) for poly p:";
2448
+ "p =", pp;
2449
+ if (isQuadratic(pp)[1] == 1) { "p is quadratic."; }
2450
+ else { "p is not quadratic."; return (0); }
2451
+ if (isIrreducible(pp) == 1) { "p is irreducible."; }
2452
+ else { "p is not irreducible."; return (0); }
2453
+ def rOrig = basering;
2454
+ int t = rtimer;
2455
+ def rNew = rationalPointConic(pp);
2456
+ t = rtimer - t;
2457
+ "time for finding a point on the conic [sec] =", t;
2458
+ setring rNew;
2459
+ poly ff = fetch(rOrig, pp);
2460
+ if (minpoly == 0)
2461
+ { "there is a rational point on the conic p";
2462
+ "x =", point[1,1], " y =", point[1,2], " z =", point[1,3];
2463
+ "check (should be zero):", subst(ff, var(1), point[1,1],
2464
+ var(2), point[1,2],
2465
+ var(3), point[1,3]);
2466
+ }
2467
+ else
2468
+ {
2469
+ "there is no rational point on the conic p";
2470
+ "but there is a point on the conic in the field extension Q(a),";
2471
+ "with minpoly =", minpoly;
2472
+ "x =", point[1,1], " y =", point[1,2], " z =", point[1,3];
2473
+ "check (should be zero):", subst(ff, var(1), point[1,1],
2474
+ var(2), point[1,2],
2475
+ var(3), point[1,3]);
2476
+ }
2477
+ setring rOrig;
2478
+ }
2479
+
2480
+ example
2481
+ { "EXAMPLE:"; echo=2;
2482
+ ring r = 0, (x,y,z, u, v, w), dp;
2483
+ poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
2484
+ testRationalPointConic(p);
2485
+ }
2486
+
2487
+ ///////////////////////////////////////////////////////////////////////////////
2488
+ proc rationalPointConic(poly p)
2489
+ "USAGE: rationalPointConic(p); p poly
2490
+ ASSUME: assumes that p is an irreducible quadratic polynomial in the first
2491
+ three ring variables;
2492
+ ground field is expected to be Q.
2493
+ RETURN: The method finds a point on the given conic. There are two
2494
+ possibilities:
2495
+ 1) There is a rational point on the curve.
2496
+ 2) There is no rational point on the curve.
2497
+ In the second case, the method creates a modification of the current
2498
+ basering which is a polynomial ring over some quadratic field
2499
+ extension Q(a) of Q. Apart from the replacement of Q by Q(a), the
2500
+ new polynomial ring, R say, is the same as the original basering.
2501
+ (In the first case, R is identical with the basering.)
2502
+ In both cases, the method will then define a (1x3) matrix named
2503
+ 'point' which lives in R and which contains the coordinates of the
2504
+ desired point on q.
2505
+ Finally, the method returns the ring R (which will in the 1st case
2506
+ be the original base ring).
2507
+ EXAMPLE: example rationalPointConic; shows an example
2508
+ "
2509
+ {
2510
+ list L = isQuadratic(p);
2511
+ if (L[1] != 1) { Error("p is not quadratic."); }
2512
+ bigint a = bigint(L[2]); bigint b = bigint(L[3]); bigint c = bigint(L[4]);
2513
+ bigint d = bigint(L[5]); bigint e = bigint(L[6]); bigint f = bigint(L[7]);
2514
+ bigint x; bigint y; bigint z; bigint nn;
2515
+ def R = basering;
2516
+
2517
+ if (b^2 == 4*a*c)
2518
+ {
2519
+ if (c == 0)
2520
+ {
2521
+ x = -2*d*e; y = d^2-4*a*f; z = e*4*a;
2522
+ nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
2523
+ matrix point[1][3];
2524
+ point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
2525
+ export point; return (R);
2526
+ }
2527
+ else
2528
+ {
2529
+ bigint fs = 4*c*f - e^2;
2530
+ bigint ds = 4*c*d - 2*b*e;
2531
+ x = -fs*2*c; y = b*fs-e*ds; z = ds*2*c;
2532
+ nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
2533
+ matrix point[1][3];
2534
+ point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
2535
+ export point; return (R);
2536
+ }
2537
+ }
2538
+
2539
+ if (d^2 == 4*a*f)
2540
+ {
2541
+ if (f == 0)
2542
+ {
2543
+ x = -b*e*2; y = e*4*a; z = b^2-4*a*c;
2544
+ nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
2545
+ matrix point[1][3];
2546
+ point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
2547
+ export point; return (R);
2548
+ }
2549
+ else
2550
+ {
2551
+ bigint c_s = 4*c*f - e^2;
2552
+ bigint b_s = 4*f*b - 2*d*e;
2553
+ x = -c_s*2*f; y = b_s*2*f; z = d*c_s-e*b_s;
2554
+ nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
2555
+ matrix point[1][3];
2556
+ point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
2557
+ export point; return (R);
2558
+ }
2559
+ }
2560
+
2561
+ if (e^2 == 4*c*f)
2562
+ {
2563
+ if (c == 0)
2564
+ {
2565
+ x = b*4*f; y = d^2-4*a*f; z = -b*d*2;
2566
+ nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
2567
+ matrix point[1][3];
2568
+ point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
2569
+ export point; return (R);
2570
+ }
2571
+ else
2572
+ {
2573
+ bigint as = 4*c*a - b^2;
2574
+ bigint ds = 4*c*d - 2*b*e;
2575
+ x = ds*2*c; y = e*as-b*ds; z = -as*2*c;
2576
+ nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
2577
+ matrix point[1][3];
2578
+ point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
2579
+ export point; return (R);
2580
+ }
2581
+ }
2582
+
2583
+ ideal mi = maxideal(1);
2584
+ map mm = R, mi;
2585
+ bigint B; bigint C; bigint D;
2586
+
2587
+ if ((a == 0) && (c == 0))
2588
+ {
2589
+ B = -1; C = 4*b*f - 4*d*e;
2590
+ /* now, b <> 0 since otherwise p would have the factor z,
2591
+ and hence not be irreducible */
2592
+ mm[1] = (var(1)+var(2)-2*e*var(3))/(2*b);
2593
+ mm[2] = (var(1)-var(2)-2*d*var(3))/(2*b);
2594
+ }
2595
+ if ((a != 0) && (c == 0))
2596
+ {
2597
+ mm[1] = var(2);
2598
+ mm[2] = var(1);
2599
+ bigint t = a; a = c; c = t;
2600
+ t = e; e = d; d = t;
2601
+ }
2602
+ if (c != 0)
2603
+ {
2604
+ D = 4*a*c-b^2;
2605
+ mm[2] = (var(2)-e*var(3)-b*var(1))/(2*c);
2606
+ map mTemp = basering, mi;
2607
+ mTemp[1] = (var(1)-2*d*c*var(3)+b*e*var(3))/D;
2608
+ mm = mTemp(mm);
2609
+ B = D;
2610
+ C = 16*a*c^2*f-4*a*c*e^2-4*b^2*c*f+4*b*c*d*e-4*c^2*d^2;
2611
+ }
2612
+ list K;
2613
+ if ((B > 0) && (C >= 0)) { K = 0; }
2614
+ if ((B >= 0) && (C > 0)) { K = 0; }
2615
+ if (B == 0)
2616
+ {
2617
+ /* looking for a point on X^2 = |C| * Z^2 */
2618
+ bigint root = largestSquare(absValue(C));
2619
+ if (absValue(C)/root/root == 1) { K = 1, root, 0, 1; }
2620
+ else { K = 0; }
2621
+ }
2622
+ if (C == 0)
2623
+ {
2624
+ /* looking for a point on X^2 = |B| * Y^2 */
2625
+ bigint root = largestSquare(absValue(B));
2626
+ if (absValue(B)/root/root == 1) { K = 1, root, 1, 0; }
2627
+ else { K = 0; }
2628
+ }
2629
+ else { K = rationalPointSpecial(B, C); }
2630
+ if (K[1] == 0)
2631
+ {
2632
+ /* no rational point on conic;
2633
+ we need to move to an appropriate field extension Q(a) */
2634
+ poly h1 = mm[1]; poly h2 = mm[2]; poly h3 = mm[3];
2635
+ def extendedR = buildExtension(B, C, K[2], K[3]);
2636
+ setring extendedR;
2637
+ poly g1 = fetch(R, h1);
2638
+ poly g2 = fetch(R, h2);
2639
+ poly g3 = fetch(R, h3);
2640
+ matrix temp[1][3];
2641
+ temp[1, 1] = subst(g1, var(1), point[1, 1], var(2), point[1, 2],
2642
+ var(3), point[1, 3]);
2643
+ temp[1, 2] = subst(g2, var(1), point[1, 1], var(2), point[1, 2],
2644
+ var(3), point[1, 3]);
2645
+ temp[1, 3] = subst(g3, var(1), point[1, 1], var(2), point[1, 2],
2646
+ var(3), point[1, 3]);
2647
+ point[1, 1] = temp[1, 1]; point[1, 2] = temp[1, 2];
2648
+ point[1, 3] = temp[1, 3];
2649
+ setring R;
2650
+ return (extendedR);
2651
+ }
2652
+ else
2653
+ {
2654
+ string dummyString = string(K); // without this useless line, we
2655
+ // sometimes get a seg fault because
2656
+ // mm is corrupted; strange!?!?!?!?
2657
+ number nx = number(subst(mm[1], var(1), K[2], var(2), K[3], var(3), K[4]));
2658
+ number ny = number(subst(mm[2], var(1), K[2], var(2), K[3], var(3), K[4]));
2659
+ number nz = number(subst(mm[3], var(1), K[2], var(2), K[3], var(3), K[4]));
2660
+ /* the point (nx, ny, nz) is already a solution;
2661
+ the following lines will just remove denominators and reduce
2662
+ numerators in order to return a nice tuple from Z^3 */
2663
+ bigint nxd = bigint(denominator(absValue(nx)));
2664
+ bigint nyd = bigint(denominator(absValue(ny)));
2665
+ bigint nzd = bigint(denominator(absValue(nz)));
2666
+ nn = nxd * nyd / gcd(nxd, nyd);
2667
+ nn = nn * nzd / gcd(nn, nzd);
2668
+ x = bigint(nx*nn); y = bigint(ny*nn); z = bigint(nz*nn);
2669
+ nn = gcd(gcd(absValue(x), absValue(y)), absValue(z));
2670
+ matrix point[1][3];
2671
+ point[1, 1] = x/nn; point[1, 2] = y/nn; point[1, 3] = z/nn;
2672
+ export point;
2673
+ return (R);
2674
+ }
2675
+ }
2676
+
2677
+ example
2678
+ { "EXAMPLE:"; echo=2;
2679
+ ring R = 0, (x,y,z), dp;
2680
+ system("random", 4711);
2681
+ poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
2682
+ def S = rationalPointConic(p); // quadratic field extension,
2683
+ // minpoly = a^2 - 2
2684
+ testPointConic(p, S);
2685
+ setring R;
2686
+ p = x^2 - 1857669520 * y^2 + 86709575222179747132487270400 * z^2;
2687
+ S = rationalPointConic(p); // same as current basering,
2688
+ // no extension needed
2689
+ testPointConic(p, S);
2690
+ }
2691
+ ///////////////////////////////////////////////////////////////////////////////
2692
+ proc testParametrization(poly f, def rTT)
2693
+ "USAGE: testParametrization(f, rTT); f poly, rTT ring
2694
+ ASSUME: The assumptions on the basering and the polynomial f are as required
2695
+ by @ref{paraPlaneCurve}. The ring rTT has two variables and contains
2696
+ an ideal PARA (such as the ring obtained by applying
2697
+ @ref{paraPlaneCurve} to f).
2698
+ RETURN: int which is 1 if PARA defines a parametrization of the curve
2699
+ {f=0} and 0, otherwise.
2700
+ THEORY: We compute the polynomial defining the image of PARA
2701
+ and compare it with f.
2702
+ KEYWORDS: Parametrization, image.
2703
+ EXAMPLE: example testParametrization; shows an example
2704
+ "
2705
+ {
2706
+ def Roriginal = basering;
2707
+ setring rTT;
2708
+ /* begin workaround elimination*/
2709
+ int k;
2710
+ list rl = ring_list(rTT);
2711
+ rl[2] = list("s","t","x","y","z");
2712
+ rl[3]= list(list("dp",1:5),list("C",0));
2713
+ def Relim = ring(rl);
2714
+ setring Relim;
2715
+ ideal PARA = fetch(rTT,PARA);
2716
+ ideal JJ;
2717
+ for(k=1;k<=3;k++)
2718
+ {
2719
+ JJ=JJ,var(k+2)-PARA[k];
2720
+ }
2721
+ ideal SJJ = std(JJ);
2722
+ bigintvec HJJ = hilb(SJJ,1);
2723
+ ideal J = eliminate(JJ,var(1)*var(2),HJJ);
2724
+ setring rTT;
2725
+ /*end workaround elimination*/
2726
+ rl[2] = list("x","y","z");
2727
+ rl[3] = list(list("dp",1:3),list("C",0));
2728
+ def RP2 = ring(rl);
2729
+ setring RP2;
2730
+ ideal f = fetch(Roriginal,f);
2731
+ ideal ftest = imap(Relim,J);
2732
+ poly g = reduce(f[1],std(ftest));
2733
+ if(g!=0){return(0)}
2734
+ g = reduce(ftest[1],std(ideal(f)));
2735
+ if(g!=0){return(0)}
2736
+ return (1);
2737
+ }
2738
+
2739
+ example
2740
+ { "EXAMPLE:"; echo=2;
2741
+ ring R = 0,(x,y,z),dp;
2742
+ poly f = y^8-x^3*(z+x)^5;
2743
+ def RP1 = paraPlaneCurve(f);
2744
+ testParametrization(f, RP1);
2745
+ }
2746
+
2747
+ ///////////////////////////////////////////////////////////////////////////////
2748
+ proc testPointConic(poly p, def r)
2749
+ "USAGE: testPointConic(p, r); p poly, r ring
2750
+ ASSUME: assumes that p is a homogeneous quadratic polynomial in the
2751
+ first three ring variables of the current basering;
2752
+ Assumes that there is a (1x3) matrix named 'point' in r with
2753
+ entries from the ground field of r.
2754
+ RETURN: returns 1 iff the point named 'point', residing in r, lies on
2755
+ the conic given by p; 0 otherwise
2756
+ NOTE: This method temporarily changes the basering to r. Afterwards,
2757
+ the basering will be the same as before.
2758
+ EXAMPLE: example testPointConic; shows an example
2759
+ "
2760
+ {
2761
+ def rOrig = basering;
2762
+ "conic:", p;
2763
+ setring r;
2764
+ string s = "point: " + string(point[1,1]) + ", " + string(point[1,2]);
2765
+ s = s + ", " + string(point[1,3]);
2766
+ s;
2767
+ if (minpoly != 0) { "minpoly:", minpoly; }
2768
+ poly f = fetch(rOrig, p);
2769
+ poly g = subst(f, var(1), point[1,1],
2770
+ var(2), point[1,2],
2771
+ var(3), point[1,3]);
2772
+ int result = 0; if (g == 0) { result = 1; }
2773
+ setring rOrig;
2774
+ return (result);
2775
+ }
2776
+
2777
+ example
2778
+ { "EXAMPLE:"; echo=2;
2779
+ ring R = 0, (x,y,z), dp;
2780
+ system("random", 4711);
2781
+ poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
2782
+ def S = rationalPointConic(p);
2783
+ if (testPointConic(p, S) == 1)
2784
+ { "point lies on conic"; }
2785
+ else
2786
+ { "point does not lie on conic"; }
2787
+ }
2788
+
2789
+ /////////////////////////////////////////////////////////////////////////////
2790
+ /////////////////////////////////////////////////////////////////////////////
2791
+ /////////////////////////////////////////////////////////////////////////////
2792
+ /*
2793
+ /////////////////////////////////////////////////////////////////////////////
2794
+ /// Further examples for testing the main procedures
2795
+ /// Timings on wawa Sept 29
2796
+ /////////////////////////////////////////////////////////////////////////////
2797
+ LIB"paraplanecurves.lib";
2798
+ // -------------------------------------------------------
2799
+ // Example 1
2800
+ // -------------------------------------------------------
2801
+ ring RR = 0, (x,y,z), dp;
2802
+ poly f = 7*z2+11*y2+13*z*y+17*x2+19*x*y; // conic
2803
+ def RP1 = paraConic(f);
2804
+ setring RP1; PARACONIC;
2805
+ setring RR;
2806
+ RP1 = paraPlaneCurve(f);
2807
+ testParametrization(f,RP1);
2808
+ setring RP1; PARA;
2809
+ kill RR;kill RP1;
2810
+ // -------------------------------------------------------
2811
+ // Example 2
2812
+ // -------------------------------------------------------
2813
+ ring RR = 0, (x,y,z), dp;
2814
+ poly f = y3-x2z; // cusp at origin
2815
+ adjointIdeal(f,1);
2816
+ adjointIdeal(f,2);
2817
+ def RP1 = paraPlaneCurve(f); // time 0
2818
+ testParametrization(f,RP1);
2819
+ setring RP1; PARA;
2820
+ kill RR;kill RP1;
2821
+ // -------------------------------------------------------
2822
+ // Example 3
2823
+ // -------------------------------------------------------
2824
+ ring RR = 0, (x,y,z), dp;
2825
+ poly f=(xz-y^2)^2-x*y^3; // 1 sing at origin, 1 cusp, no OMPs
2826
+ adjointIdeal(f,1);
2827
+ adjointIdeal(f,2);
2828
+ def RP1 = paraPlaneCurve(f); // time 0
2829
+ testParametrization(f,RP1);
2830
+ setring RP1; PARA;
2831
+ kill RR;kill RP1;
2832
+ // -------------------------------------------------------
2833
+ // Example 4
2834
+ // -------------------------------------------------------
2835
+ ring RR = 0, (x,y,z), dp;
2836
+ poly f = y5-y4x+4y2x2z-x4z; // 1 sing at origin, no OMPs, no cusps
2837
+ adjointIdeal(f,1);
2838
+ adjointIdeal(f,2);
2839
+ def RP1 = paraPlaneCurve(f); // time 0
2840
+ testParametrization(f,RP1);
2841
+ setring RP1; PARA;
2842
+ kill RR;kill RP1;
2843
+ // -------------------------------------------------------
2844
+ // Example 5
2845
+ // -------------------------------------------------------
2846
+ ring RR = 0, (x,y,z), dp;
2847
+ poly f = 259x5-31913x4y+939551x3y2+2871542x2y3+2845801xy4;
2848
+ f = f+914489y5+32068x4z-1884547x3yz-8472623x2y2z-11118524xy3z;
2849
+ f = f-4589347y4z+944585x3z2+8563304x2yz2+16549772xy2z2+9033035y3z2;
2850
+ f = f-2962425x2z3-11214315xyz3-8951744y2z3+2937420xz4+4547571yz4-953955z5;
2851
+ // 6 nodes
2852
+ adjointIdeal(f,1);
2853
+ adjointIdeal(f,2);
2854
+ def RP1 = paraPlaneCurve(f); // time 0
2855
+ testParametrization(f,RP1);
2856
+ setring RP1; PARA;
2857
+ kill RR;kill RP1;
2858
+ // -------------------------------------------------------
2859
+ // Example 7
2860
+ // -------------------------------------------------------
2861
+ ring RR = 0, (x,y,z), dp;
2862
+ poly f = y^8-x^3*(z+x)^5; // 1 sing at origin, 1 further sing, no OMPs,
2863
+ // no cusps
2864
+ adjointIdeal(f,1);
2865
+ adjointIdeal(f,2);
2866
+ def RP1 = paraPlaneCurve(f); // time 0
2867
+ testParametrization(f,RP1);
2868
+ setring RP1; PARA;
2869
+ kill RR;kill RP1;
2870
+ // -------------------------------------------------------
2871
+ // Example 8
2872
+ // -------------------------------------------------------
2873
+ ring RR = 0, (x,y,z), dp;
2874
+ poly f = 11y7+7y6x+8y5x2-3y4x3-10y3x4-10y2x5-x7-33y6-29y5x-13y4x2+26y3x3;
2875
+ f = f+30y2x4+10yx5+3x6+33y5+37y4x-8y3x2-33y2x3-20yx4-3x5-11y4-15y3x;
2876
+ f = f+13y2x2+10yx3+x4; // 3 OMPs of mult 3, 1 OMP of mult 4
2877
+ f = homog(f,z);
2878
+ adjointIdeal(f,1);
2879
+ adjointIdeal(f,2);
2880
+ def RP1 = paraPlaneCurve(f); // time 0
2881
+ testParametrization(f,RP1);
2882
+ setring RP1; PARA;
2883
+ kill RR;kill RP1;
2884
+ // -------------------------------------------------------
2885
+ // Example 9
2886
+ // -------------------------------------------------------
2887
+ ring RR = 0, (x,y,z), dp;
2888
+ poly f = y^8-x^3*(z+x)^5; // 1 sing at origin, 1 further sing, no OMPs,
2889
+ // no cusps
2890
+ adjointIdeal(f,1);
2891
+ adjointIdeal(f,2);
2892
+ def RP1 = paraPlaneCurve(f); // time 0
2893
+ testParametrization(f,RP1);
2894
+ setring RP1; PARA;
2895
+ kill RR;kill RP1;
2896
+ // -------------------------------------------------------
2897
+ // Example 10
2898
+ // -------------------------------------------------------
2899
+ ring SS = 0, (u,v,z), dp;
2900
+ poly f = u^4-14*u^2*v^2+v^4+8*u^2*v*z+8*v^3*z; // 1 OMP of mult 3 at origin
2901
+ adjointIdeal(f,1);
2902
+ adjointIdeal(f,2);
2903
+ def RP1 = paraPlaneCurve(f); // time 0
2904
+ testParametrization(f,RP1);
2905
+ setring RP1; PARA;
2906
+ kill SS;kill RP1;
2907
+ // -------------------------------------------------------
2908
+ // Example 11
2909
+ // -------------------------------------------------------
2910
+ ring SS = 0, (u,v,z), dp;
2911
+ poly f = 14440*u^5-16227*u^4*v+10812*u^3*v^2-13533*u^2*v^3+3610*u*v^4;
2912
+ f = f+1805*v^5+14440*u^4*z-18032*u^3*v*z+16218*u^2*v^2*z-12626*u*v^3*z;
2913
+ f = f+3610*v^4*z+3610*u^3*z^2-4508*u^2*v*z^2+5406*u*v^2*z^2-2703*v^3*z^2;
2914
+ // 1 OMP of mult 3 at origin, 2 nodes
2915
+ adjointIdeal(f,1);
2916
+ adjointIdeal(f,2);
2917
+ def RP1 = paraPlaneCurve(f); // time 0
2918
+ testParametrization(f,RP1);
2919
+ setring RP1; PARA;
2920
+ kill SS;kill RP1;
2921
+ // -------------------------------------------------------
2922
+ // Example 12
2923
+ // -------------------------------------------------------
2924
+ ring SS = 0, (u,v,z), dp;
2925
+ poly f = u^6+3*u^4*v^2+3*u^2*v^4+v^6-4*u^4*z^2-34*u^3*v*z^2-7*u^2*v^2*z^2;
2926
+ f = f+12*u*v^3*z^2+6*v^4*z^2+36*u^2*z^4+36*u*v*z^4+9*v^2*z^4;
2927
+ // needs field extension *** 6 nodes, 2 cusps, 1 sing at 0
2928
+ adjointIdeal(f,1);
2929
+ adjointIdeal(f,2);
2930
+ def RP1 = paraPlaneCurve(f); // time 0
2931
+ testParametrization(f,RP1);
2932
+ setring RP1; PARA;
2933
+ kill SS;kill RP1;
2934
+ // -------------------------------------------------------
2935
+ // Example 13
2936
+ // -------------------------------------------------------
2937
+ ring SS = 0, (u,v,z), dp;
2938
+ poly f = -24135/322*u^6-532037/6440*u^5*v+139459/560*u^4*v^2;
2939
+ f = f-1464887/12880*u^3*v^3+72187/25760*u^2*v^4+9/8*u*v^5+1/8*v^6;
2940
+ f = f-403511/3220*u^5*z-40817/920*u^4*v*z+10059/80*u^3*v^2*z;
2941
+ f = f-35445/1288*u^2*v^3*z+19/4*u*v^4*z+3/4*v^5*z-20743/805*u^4*z^2;
2942
+ f = f+126379/3220*u^3*v*z^2-423417/6440*u^2*v^2*z^2+11/2*u*v^3*z^2;
2943
+ f = f+3/2*v^4*z^2+3443/140*u^3*z^3+u^2*v*z^3+u*v^2*z^3+v^3*z^3;
2944
+ // 2 OMPs of mult 3 (1 at origin), 4 nodes
2945
+ adjointIdeal(f,1);
2946
+ adjointIdeal(f,2);
2947
+ def RP1 = paraPlaneCurve(f); // time 14
2948
+ testParametrization(f,RP1);
2949
+ setring RP1; PARA;
2950
+ kill SS;kill RP1;
2951
+ // -------------------------------------------------------
2952
+ // Example 14
2953
+ // -------------------------------------------------------
2954
+ ring SS = 0, (u,v,z), dp;
2955
+ poly f =
2956
+ 2*u^7+u^6*v+3*u^5*v^2+u^4*v^3+2*u^3*v^4+u^2*v^5+2*u*v^6+v^7
2957
+ -7780247/995328*u^6*z-78641/9216*u^5*v*z-10892131/995328*u^4*v^2*z
2958
+ -329821/31104*u^3*v^3*z-953807/331776*u^2*v^4*z-712429/248832*u*v^5*z
2959
+ +1537741/331776*v^6*z+2340431/248832*u^5*z^2+5154337/248832*u^4*v*z^2
2960
+ +658981/41472*u^3*v^2*z^2+1737757/124416*u^2*v^3*z^2
2961
+ -1234733/248832*u*v^4*z^2-1328329/82944*v^5*z^2-818747/248832*u^4*z^3
2962
+ -1822879/124416*u^3*v*z^3-415337/31104*u^2*v^2*z^3
2963
+ +1002655/124416*u*v^3*z^3+849025/82944*v^4*z^3;
2964
+ // 3 OMPs of mult 3, 1 OMP of mult 4 at origin
2965
+ adjointIdeal(f,2);
2966
+ def RP1 = paraPlaneCurve(f); // time 1
2967
+ testParametrization(f,RP1);
2968
+ setring RP1; PARA;
2969
+ kill SS;kill RP1;
2970
+ // -------------------------------------------------------
2971
+ // Example 15
2972
+ // -------------------------------------------------------
2973
+ ring SS = 0, (u,v,z), dp;
2974
+ poly f = 590819418867856650536224u7-147693905508217596067968u6v;
2975
+ f = f+229117518934972047619978u5v2-174050799674982973889542u4v3;
2976
+ f = f-92645796479789150855110u3v4-65477418713685583062704u2v5;
2977
+ f = f+4529961835917468460168uv6+7715404057796585983136v7;
2978
+ f = f-413640780091141905428104u6z+571836835577486968144618u5vz;
2979
+ f = f-551807810327826605739444u4v2z-488556410340789283359926u3v3z;
2980
+ f = f-473466023008413178155962u2v4z+48556741573432247323608uv5z;
2981
+ f = f+77647371229172269259528v6z+340450118906560552282893u5z2;
2982
+ f = f-433598825064368371610344u4vz2-937281070591684636591672u3v2z2;
2983
+ f = f-1388949843915129934647751u2v3z2+204081793110898617103998uv4z2;
2984
+ f = f+335789953068251652554308v5z2+6485661002496681852577u4z3;
2985
+ f = f-772700266516318390630202u3vz3-2068348417248100329533330u2v2z3;
2986
+ f = f+440320154612359641806108uv3z3+808932515589210854581618v4z3;
2987
+ f = f-229384307132237615286548u3z4-1564303565658228216055227u2vz4;
2988
+ f = f+520778334468674798322974uv2z4+1172483905704993294097655v3z4;
2989
+ f = f-480789741398016816562100u2z5+322662751598958620410786uvz5;
2990
+ f = f+1022525576391791616258310v2z5+82293493608853837667471uz6;
2991
+ f = f+496839109904761426785889vz6+103766136235628614937587z7; // 15 nodes
2992
+ adjointIdeal(f,2);
2993
+ def RP1 = paraPlaneCurve(f); // time 72
2994
+ testParametrization(f,RP1);
2995
+ setring RP1; PARA;
2996
+ kill SS;kill RP1;
2997
+
2998
+ // -------------------------------------------------------
2999
+ // Example 16
3000
+ // -------------------------------------------------------
3001
+ ring SS = 0, (u,v,z), dp;
3002
+ poly f = 25*u^8+184*u^7*v+518*u^6*v^2+720*u^5*v^3+576*u^4*v^4+282*u^3*v^5;
3003
+ f = f+84*u^2*v^6+14*u*v^7+v^8+244*u^7*z+1326*u^6*v*z+2646*u^5*v^2*z;
3004
+ f = f+2706*u^4*v^3*z+1590*u^3*v^4*z+546*u^2*v^5*z+102*u*v^6*z+8*v^7*z;
3005
+ f = f+854*u^6*z^2+3252*u^5*v*z^2+4770*u^4*v^2*z^2+3582*u^3*v^3*z^2;
3006
+ f = f+1476*u^2*v^4*z^2+318*u*v^5*z^2+28*v^6*z^2+1338*u^5*z^3+3740*u^4*v*z^3;
3007
+ f = f+4030*u^3*v^2*z^3+2124*u^2*v^3*z^3+550*u*v^4*z^3+56*v^5*z^3+1101*u^4*z^4;
3008
+ f = f+2264*u^3*v*z^4+1716*u^2*v^2*z^4+570*u*v^3*z^4+70*v^4*z^4+508*u^3*z^5;
3009
+ f = f+738*u^2*v*z^5+354*u*v^2*z^5+56*v^3*z^5+132*u^2*z^6+122*u*v*z^6;
3010
+ f = f+28*v^2*z^6+18*u*z^7+8*v*z^7+z^8; // 3 nodes, 1 sing
3011
+ adjointIdeal(f,1);
3012
+ adjointIdeal(f,2);
3013
+ def RP1 = paraPlaneCurve(f); // time 20
3014
+ testParametrization(f,RP1);
3015
+ setring RP1; PARA;
3016
+ kill SS;kill RP1;
3017
+ // -------------------------------------------------------
3018
+ // Example 17
3019
+ // -------------------------------------------------------
3020
+ ring SS = 0, (u,v,z), dp;
3021
+ poly f = -2*u*v^4*z^4+u^4*v^5+12*u^4*v^3*z^2+12*u^2*v^4*z^3-u^3*v*z^5;
3022
+ f = f+11*u^3*v^2*z^4-21*u^3*v^3*z^3-4*u^4*v*z^4+2*u^4*v^2*z^3-6*u^4*v^4*z;
3023
+ f = f+u^5*z^4-3*u^5*v^2*z^2+u^5*v^3*z-3*u*v^5*z^3-2*u^2*v^3*z^4+u^3*v^4*z^2;
3024
+ f = f+v^5*z^4; // 2 OMPs of mult 4, 1 OMP of mult 5, 1 sing at origin
3025
+ f = subst(f,z,u+v+z);
3026
+ adjointIdeal(f,2);
3027
+ def RP1 = paraPlaneCurve(f); // time 5
3028
+ testParametrization(f,RP1);
3029
+ setring RP1; PARA;
3030
+ kill SS;kill RP1;
3031
+ // -------------------------------------------------------
3032
+ // Example 18
3033
+ // -------------------------------------------------------
3034
+ ring SS = 0, (u,v,z), dp;
3035
+ poly f = u^5*v^5+21*u^5*v^4*z-36*u^4*v^5*z-19*u^5*v^3*z^2+12*u^4*v^4*z^2;
3036
+ f = f+57*u^3*v^5*z^2+u^5*v^2*z^3+u^4*v^3*z^3-53*u^3*v^4*z^3-19*u^2*v^5*z^3;
3037
+ f = f+u^5*v*z^4+43*u^3*v^3*z^4+u*v^5*z^4+u^5*z^5-15*u^3*v^2*z^5+u^2*v^3*z^5;
3038
+ f = f+u*v^4*z^5+v^5*z^5; // 1 OMP of mult 4, 3 OMPs of mult 5 (1 at origin)
3039
+ adjointIdeal(f,2);
3040
+ def RP1 = paraPlaneCurve(f); // time 8
3041
+ testParametrization(f,RP1);
3042
+ setring RP1; PARA;
3043
+ kill SS;kill RP1;
3044
+ // -------------------------------------------------------
3045
+ // Example 19
3046
+ // -------------------------------------------------------
3047
+ ring SS = 0, (u,v,z), dp;
3048
+ poly f = u^10+6*u^9*v-30*u^7*v^3-15*u^6*v^4+u^5*v^5+u^4*v^6+6*u^3*v^7;
3049
+ f = f+u^2*v^8+7*u*v^9+v^10+5*u^9*z+24*u^8*v*z-30*u^7*v^2*z-120*u^6*v^3*z;
3050
+ f = f-43*u^5*v^4*z+5*u^4*v^5*z+20*u^3*v^6*z+10*u^2*v^7*z+29*u*v^8*z+5*v^9*z;
3051
+ f = f+10*u^8*z^2+36*u^7*v*z^2-105*u^6*v^2*z^2-179*u^5*v^3*z^2-38*u^4*v^4*z^2;
3052
+ f = f+25*u^3*v^5*z^2+25*u^2*v^6*z^2+46*u*v^7*z^2+10*v^8*z^2+10*u^7*z^3;
3053
+ f = f+24*u^6*v*z^3-135*u^5*v^2*z^3-117*u^4*v^3*z^3-u^3*v^4*z^3+25*u^2*v^5*z^3;
3054
+ f = f+34*u*v^6*z^3+10*v^7*z^3+5*u^6*z^4+6*u^5*v*z^4-75*u^4*v^2*z^4;
3055
+ f = f-27*u^3*v^3*z^4+10*u^2*v^4*z^4+11*u*v^5*z^4+5*v^6*z^4+u^5*z^5;
3056
+ f = f-15*u^3*v^2*z^5+u^2*v^3*z^5+u*v^4*z^5+v^5*z^5;
3057
+ // 1 OMP of mult 4, 3 OMPs of mult 5 (1 at origin)
3058
+ adjointIdeal(f,2);
3059
+ def RP1 = paraPlaneCurve(f); // time 2 // see Ex. 18
3060
+ testParametrization(f,RP1);
3061
+ setring RP1; PARA;
3062
+ kill SS;kill RP1;
3063
+ // -------------------------------------------------------
3064
+ // Example 20
3065
+ // -------------------------------------------------------
3066
+ ring R = 0, (x,y,z), dp;
3067
+ system("random", 4711);
3068
+ poly p = x^2 + 2*y^2 + 5*z^2 - 4*x*y + 3*x*z + 17*y*z;
3069
+ def S = rationalPointConic(p); // quadratic field extension,
3070
+ // minpoly = a^2 - 2
3071
+ if (testPointConic(p, S) == 1)
3072
+ { "point lies on conic"; }
3073
+ else
3074
+ { "point does not lie on conic"; }
3075
+ kill R;kill S;
3076
+ // -------------------------------------------------------
3077
+ // Example 21
3078
+ // -------------------------------------------------------
3079
+ ring R = 0, (x,y,z), dp;
3080
+ system("random", 4711);
3081
+ poly p = x^2 - 1857669520 * y^2 + 86709575222179747132487270400 * z^2;
3082
+ def S = rationalPointConic(p); // same as current basering,
3083
+ // no extension needed
3084
+ if (testPointConic(p, S) == 1)
3085
+ { "point lies on conic"; }
3086
+ else
3087
+ { "point does not lie on conic"; }
3088
+ kill R;kill S;
3089
+ // -------------------------------------------------------
3090
+ // Example 21
3091
+ // -------------------------------------------------------
3092
+ ring RR = 0, (x,y,z), dp;
3093
+ poly f = -1965466244509920x5y+34871245546721380061760x4y2;
3094
+ f = f+104613747941595046117320x3y3+113331564241941002407560x2y4;
3095
+ f = f+52306876673313609259800xy5+8717812860780028397880y6;
3096
+ f = f+1040297748510024x5z+4468147845634872x4yz;
3097
+ f = f-22398508728211453743258x3y2z-33223996581074443306854x2y3z;
3098
+ f = f-10638598235041298082366xy4z+186886189971594356382y5z;
3099
+ f = f-1385078844909312x4z2-34893092731637052532683x3yz2;
3100
+ f = f-98591463214095439056609x2y2z2-92339459334829609336485xy3z2;
3101
+ f = f-24923289542522905755711y4z2+472440640471377x3z3;
3102
+ f = f+33821511925664516716011x2yz3+49745237303968344397437xy2z3;
3103
+ f = f+11040465960074786720475y3z3+8728735735878837099404x2z4;
3104
+ f = f+17676785754519678518537xyz4+17935885079051421934609y2z4;
3105
+ f = f-11314701999743172607075xz5-16164284825803158969425yz5;
3106
+ f = f+3666695988537425618750z6;
3107
+ // 4 nodes, 1 OMP of mult 4
3108
+ adjointIdeal(f,2);
3109
+ kill RR;
3110
+ */