passagemath-singular 10.6.31rc3__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-singular might be problematic. Click here for more details.

Files changed (493) hide show
  1. PySingular.cpython-314-x86_64-linux-musl.so +0 -0
  2. passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
  3. passagemath_singular-10.6.31rc3.dist-info/RECORD +493 -0
  4. passagemath_singular-10.6.31rc3.dist-info/WHEEL +5 -0
  5. passagemath_singular-10.6.31rc3.dist-info/top_level.txt +3 -0
  6. passagemath_singular.libs/libSingular-4-67059f19.4.1.so +0 -0
  7. passagemath_singular.libs/libcddgmp-30166d29.so.0.1.3 +0 -0
  8. passagemath_singular.libs/libfactory-4-9d37bcf4.4.1.so +0 -0
  9. passagemath_singular.libs/libflint-fd6f12fc.so.21.0.0 +0 -0
  10. passagemath_singular.libs/libgcc_s-0cd532bd.so.1 +0 -0
  11. passagemath_singular.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  12. passagemath_singular.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
  13. passagemath_singular.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  14. passagemath_singular.libs/libgsl-42cda06f.so.28.0.0 +0 -0
  15. passagemath_singular.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  16. passagemath_singular.libs/libncursesw-9c9e32c3.so.6.5 +0 -0
  17. passagemath_singular.libs/libntl-26885ca2.so.44.0.1 +0 -0
  18. passagemath_singular.libs/libomalloc-0-e9ff96db.9.6.so +0 -0
  19. passagemath_singular.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
  20. passagemath_singular.libs/libpolys-4-8bcf8e7d.4.1.so +0 -0
  21. passagemath_singular.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
  22. passagemath_singular.libs/libreadline-06542304.so.8.2 +0 -0
  23. passagemath_singular.libs/libsingular_resources-4-73bf7623.4.1.so +0 -0
  24. passagemath_singular.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  25. sage/algebras/all__sagemath_singular.py +3 -0
  26. sage/algebras/fusion_rings/all.py +19 -0
  27. sage/algebras/fusion_rings/f_matrix.py +2448 -0
  28. sage/algebras/fusion_rings/fast_parallel_fmats_methods.cpython-314-x86_64-linux-musl.so +0 -0
  29. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pxd +5 -0
  30. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +538 -0
  31. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.cpython-314-x86_64-linux-musl.so +0 -0
  32. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pxd +3 -0
  33. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +331 -0
  34. sage/algebras/fusion_rings/fusion_double.py +899 -0
  35. sage/algebras/fusion_rings/fusion_ring.py +1580 -0
  36. sage/algebras/fusion_rings/poly_tup_engine.cpython-314-x86_64-linux-musl.so +0 -0
  37. sage/algebras/fusion_rings/poly_tup_engine.pxd +24 -0
  38. sage/algebras/fusion_rings/poly_tup_engine.pyx +579 -0
  39. sage/algebras/fusion_rings/shm_managers.cpython-314-x86_64-linux-musl.so +0 -0
  40. sage/algebras/fusion_rings/shm_managers.pxd +24 -0
  41. sage/algebras/fusion_rings/shm_managers.pyx +780 -0
  42. sage/algebras/letterplace/all.py +1 -0
  43. sage/algebras/letterplace/free_algebra_element_letterplace.cpython-314-x86_64-linux-musl.so +0 -0
  44. sage/algebras/letterplace/free_algebra_element_letterplace.pxd +18 -0
  45. sage/algebras/letterplace/free_algebra_element_letterplace.pyx +755 -0
  46. sage/algebras/letterplace/free_algebra_letterplace.cpython-314-x86_64-linux-musl.so +0 -0
  47. sage/algebras/letterplace/free_algebra_letterplace.pxd +35 -0
  48. sage/algebras/letterplace/free_algebra_letterplace.pyx +914 -0
  49. sage/algebras/letterplace/letterplace_ideal.cpython-314-x86_64-linux-musl.so +0 -0
  50. sage/algebras/letterplace/letterplace_ideal.pyx +408 -0
  51. sage/algebras/quatalg/all.py +2 -0
  52. sage/algebras/quatalg/quaternion_algebra.py +4778 -0
  53. sage/algebras/quatalg/quaternion_algebra_cython.cpython-314-x86_64-linux-musl.so +0 -0
  54. sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
  55. sage/algebras/quatalg/quaternion_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
  56. sage/algebras/quatalg/quaternion_algebra_element.pxd +29 -0
  57. sage/algebras/quatalg/quaternion_algebra_element.pyx +2176 -0
  58. sage/all__sagemath_singular.py +11 -0
  59. sage/ext_data/all__sagemath_singular.py +1 -0
  60. sage/ext_data/singular/function_field/core.lib +98 -0
  61. sage/interfaces/all__sagemath_singular.py +1 -0
  62. sage/interfaces/singular.py +2835 -0
  63. sage/libs/all__sagemath_singular.py +1 -0
  64. sage/libs/singular/__init__.py +1 -0
  65. sage/libs/singular/decl.pxd +1168 -0
  66. sage/libs/singular/function.cpython-314-x86_64-linux-musl.so +0 -0
  67. sage/libs/singular/function.pxd +87 -0
  68. sage/libs/singular/function.pyx +1901 -0
  69. sage/libs/singular/function_factory.py +61 -0
  70. sage/libs/singular/groebner_strategy.cpython-314-x86_64-linux-musl.so +0 -0
  71. sage/libs/singular/groebner_strategy.pxd +22 -0
  72. sage/libs/singular/groebner_strategy.pyx +582 -0
  73. sage/libs/singular/option.cpython-314-x86_64-linux-musl.so +0 -0
  74. sage/libs/singular/option.pyx +671 -0
  75. sage/libs/singular/polynomial.cpython-314-x86_64-linux-musl.so +0 -0
  76. sage/libs/singular/polynomial.pxd +39 -0
  77. sage/libs/singular/polynomial.pyx +661 -0
  78. sage/libs/singular/ring.cpython-314-x86_64-linux-musl.so +0 -0
  79. sage/libs/singular/ring.pxd +58 -0
  80. sage/libs/singular/ring.pyx +893 -0
  81. sage/libs/singular/singular.cpython-314-x86_64-linux-musl.so +0 -0
  82. sage/libs/singular/singular.pxd +72 -0
  83. sage/libs/singular/singular.pyx +1944 -0
  84. sage/libs/singular/standard_options.py +145 -0
  85. sage/matrix/all__sagemath_singular.py +1 -0
  86. sage/matrix/matrix_mpolynomial_dense.cpython-314-x86_64-linux-musl.so +0 -0
  87. sage/matrix/matrix_mpolynomial_dense.pxd +7 -0
  88. sage/matrix/matrix_mpolynomial_dense.pyx +615 -0
  89. sage/rings/all__sagemath_singular.py +1 -0
  90. sage/rings/function_field/all__sagemath_singular.py +1 -0
  91. sage/rings/function_field/derivations_polymod.py +911 -0
  92. sage/rings/function_field/element_polymod.cpython-314-x86_64-linux-musl.so +0 -0
  93. sage/rings/function_field/element_polymod.pyx +406 -0
  94. sage/rings/function_field/function_field_polymod.py +2611 -0
  95. sage/rings/function_field/ideal_polymod.py +1775 -0
  96. sage/rings/function_field/order_polymod.py +1475 -0
  97. sage/rings/function_field/place_polymod.py +681 -0
  98. sage/rings/polynomial/all__sagemath_singular.py +1 -0
  99. sage/rings/polynomial/multi_polynomial_ideal_libsingular.cpython-314-x86_64-linux-musl.so +0 -0
  100. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pxd +5 -0
  101. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +339 -0
  102. sage/rings/polynomial/multi_polynomial_libsingular.cpython-314-x86_64-linux-musl.so +0 -0
  103. sage/rings/polynomial/multi_polynomial_libsingular.pxd +30 -0
  104. sage/rings/polynomial/multi_polynomial_libsingular.pyx +6277 -0
  105. sage/rings/polynomial/plural.cpython-314-x86_64-linux-musl.so +0 -0
  106. sage/rings/polynomial/plural.pxd +48 -0
  107. sage/rings/polynomial/plural.pyx +3171 -0
  108. sage/symbolic/all__sagemath_singular.py +1 -0
  109. sage/symbolic/comparison_impl.pxi +428 -0
  110. sage/symbolic/constants_c_impl.pxi +178 -0
  111. sage/symbolic/expression.cpython-314-x86_64-linux-musl.so +0 -0
  112. sage/symbolic/expression.pxd +7 -0
  113. sage/symbolic/expression.pyx +14200 -0
  114. sage/symbolic/getitem_impl.pxi +202 -0
  115. sage/symbolic/pynac.pxi +572 -0
  116. sage/symbolic/pynac_constant_impl.pxi +133 -0
  117. sage/symbolic/pynac_function_impl.pxi +206 -0
  118. sage/symbolic/pynac_impl.pxi +2576 -0
  119. sage/symbolic/pynac_wrap.h +124 -0
  120. sage/symbolic/series_impl.pxi +272 -0
  121. sage/symbolic/substitution_map_impl.pxi +94 -0
  122. sage_wheels/bin/ESingular +0 -0
  123. sage_wheels/bin/Singular +0 -0
  124. sage_wheels/bin/TSingular +0 -0
  125. sage_wheels/lib/singular/MOD/cohomo.la +41 -0
  126. sage_wheels/lib/singular/MOD/cohomo.so +0 -0
  127. sage_wheels/lib/singular/MOD/customstd.la +41 -0
  128. sage_wheels/lib/singular/MOD/customstd.so +0 -0
  129. sage_wheels/lib/singular/MOD/freealgebra.la +41 -0
  130. sage_wheels/lib/singular/MOD/freealgebra.so +0 -0
  131. sage_wheels/lib/singular/MOD/gfanlib.la +41 -0
  132. sage_wheels/lib/singular/MOD/gfanlib.so +0 -0
  133. sage_wheels/lib/singular/MOD/gitfan.la +41 -0
  134. sage_wheels/lib/singular/MOD/gitfan.so +0 -0
  135. sage_wheels/lib/singular/MOD/interval.la +41 -0
  136. sage_wheels/lib/singular/MOD/interval.so +0 -0
  137. sage_wheels/lib/singular/MOD/loctriv.la +41 -0
  138. sage_wheels/lib/singular/MOD/loctriv.so +0 -0
  139. sage_wheels/lib/singular/MOD/machinelearning.la +41 -0
  140. sage_wheels/lib/singular/MOD/machinelearning.so +0 -0
  141. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.la +41 -0
  142. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.so +0 -0
  143. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.la +41 -0
  144. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.so +0 -0
  145. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.la +41 -0
  146. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.so +0 -0
  147. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.la +41 -0
  148. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.so +0 -0
  149. sage_wheels/lib/singular/MOD/partialgb.la +41 -0
  150. sage_wheels/lib/singular/MOD/partialgb.so +0 -0
  151. sage_wheels/lib/singular/MOD/pyobject.la +41 -0
  152. sage_wheels/lib/singular/MOD/pyobject.so +0 -0
  153. sage_wheels/lib/singular/MOD/singmathic.la +41 -0
  154. sage_wheels/lib/singular/MOD/singmathic.so +0 -0
  155. sage_wheels/lib/singular/MOD/sispasm.la +41 -0
  156. sage_wheels/lib/singular/MOD/sispasm.so +0 -0
  157. sage_wheels/lib/singular/MOD/subsets.la +41 -0
  158. sage_wheels/lib/singular/MOD/subsets.so +0 -0
  159. sage_wheels/lib/singular/MOD/systhreads.la +41 -0
  160. sage_wheels/lib/singular/MOD/systhreads.so +0 -0
  161. sage_wheels/lib/singular/MOD/syzextra.la +41 -0
  162. sage_wheels/lib/singular/MOD/syzextra.so +0 -0
  163. sage_wheels/libexec/singular/MOD/change_cost +0 -0
  164. sage_wheels/libexec/singular/MOD/singularsurf +11 -0
  165. sage_wheels/libexec/singular/MOD/singularsurf_jupyter +9 -0
  166. sage_wheels/libexec/singular/MOD/singularsurf_win +10 -0
  167. sage_wheels/libexec/singular/MOD/solve_IP +0 -0
  168. sage_wheels/libexec/singular/MOD/surfex +16 -0
  169. sage_wheels/libexec/singular/MOD/toric_ideal +0 -0
  170. sage_wheels/share/factory/gftables/10201 +342 -0
  171. sage_wheels/share/factory/gftables/1024 +37 -0
  172. sage_wheels/share/factory/gftables/10609 +356 -0
  173. sage_wheels/share/factory/gftables/11449 +384 -0
  174. sage_wheels/share/factory/gftables/11881 +398 -0
  175. sage_wheels/share/factory/gftables/121 +6 -0
  176. sage_wheels/share/factory/gftables/12167 +408 -0
  177. sage_wheels/share/factory/gftables/125 +7 -0
  178. sage_wheels/share/factory/gftables/12769 +428 -0
  179. sage_wheels/share/factory/gftables/128 +7 -0
  180. sage_wheels/share/factory/gftables/1331 +47 -0
  181. sage_wheels/share/factory/gftables/1369 +48 -0
  182. sage_wheels/share/factory/gftables/14641 +490 -0
  183. sage_wheels/share/factory/gftables/15625 +523 -0
  184. sage_wheels/share/factory/gftables/16 +3 -0
  185. sage_wheels/share/factory/gftables/16129 +540 -0
  186. sage_wheels/share/factory/gftables/16384 +549 -0
  187. sage_wheels/share/factory/gftables/16807 +563 -0
  188. sage_wheels/share/factory/gftables/1681 +58 -0
  189. sage_wheels/share/factory/gftables/169 +8 -0
  190. sage_wheels/share/factory/gftables/17161 +574 -0
  191. sage_wheels/share/factory/gftables/1849 +64 -0
  192. sage_wheels/share/factory/gftables/18769 +628 -0
  193. sage_wheels/share/factory/gftables/19321 +646 -0
  194. sage_wheels/share/factory/gftables/19683 +659 -0
  195. sage_wheels/share/factory/gftables/2048 +71 -0
  196. sage_wheels/share/factory/gftables/2187 +75 -0
  197. sage_wheels/share/factory/gftables/2197 +76 -0
  198. sage_wheels/share/factory/gftables/2209 +76 -0
  199. sage_wheels/share/factory/gftables/22201 +742 -0
  200. sage_wheels/share/factory/gftables/22801 +762 -0
  201. sage_wheels/share/factory/gftables/2401 +82 -0
  202. sage_wheels/share/factory/gftables/243 +11 -0
  203. sage_wheels/share/factory/gftables/24389 +815 -0
  204. sage_wheels/share/factory/gftables/24649 +824 -0
  205. sage_wheels/share/factory/gftables/25 +3 -0
  206. sage_wheels/share/factory/gftables/256 +11 -0
  207. sage_wheels/share/factory/gftables/26569 +888 -0
  208. sage_wheels/share/factory/gftables/27 +3 -0
  209. sage_wheels/share/factory/gftables/27889 +932 -0
  210. sage_wheels/share/factory/gftables/2809 +96 -0
  211. sage_wheels/share/factory/gftables/28561 +954 -0
  212. sage_wheels/share/factory/gftables/289 +12 -0
  213. sage_wheels/share/factory/gftables/29791 +995 -0
  214. sage_wheels/share/factory/gftables/29929 +1000 -0
  215. sage_wheels/share/factory/gftables/3125 +107 -0
  216. sage_wheels/share/factory/gftables/32 +4 -0
  217. sage_wheels/share/factory/gftables/32041 +1070 -0
  218. sage_wheels/share/factory/gftables/32761 +1094 -0
  219. sage_wheels/share/factory/gftables/32768 +1095 -0
  220. sage_wheels/share/factory/gftables/343 +14 -0
  221. sage_wheels/share/factory/gftables/3481 +118 -0
  222. sage_wheels/share/factory/gftables/361 +14 -0
  223. sage_wheels/share/factory/gftables/36481 +1218 -0
  224. sage_wheels/share/factory/gftables/3721 +126 -0
  225. sage_wheels/share/factory/gftables/37249 +1244 -0
  226. sage_wheels/share/factory/gftables/38809 +1296 -0
  227. sage_wheels/share/factory/gftables/39601 +1322 -0
  228. sage_wheels/share/factory/gftables/4 +3 -0
  229. sage_wheels/share/factory/gftables/4096 +139 -0
  230. sage_wheels/share/factory/gftables/44521 +1486 -0
  231. sage_wheels/share/factory/gftables/4489 +152 -0
  232. sage_wheels/share/factory/gftables/49 +4 -0
  233. sage_wheels/share/factory/gftables/4913 +166 -0
  234. sage_wheels/share/factory/gftables/49729 +1660 -0
  235. sage_wheels/share/factory/gftables/5041 +170 -0
  236. sage_wheels/share/factory/gftables/50653 +1691 -0
  237. sage_wheels/share/factory/gftables/512 +20 -0
  238. sage_wheels/share/factory/gftables/51529 +1720 -0
  239. sage_wheels/share/factory/gftables/52441 +1750 -0
  240. sage_wheels/share/factory/gftables/529 +20 -0
  241. sage_wheels/share/factory/gftables/5329 +180 -0
  242. sage_wheels/share/factory/gftables/54289 +1812 -0
  243. sage_wheels/share/factory/gftables/57121 +1906 -0
  244. sage_wheels/share/factory/gftables/58081 +1938 -0
  245. sage_wheels/share/factory/gftables/59049 +1971 -0
  246. sage_wheels/share/factory/gftables/6241 +210 -0
  247. sage_wheels/share/factory/gftables/625 +23 -0
  248. sage_wheels/share/factory/gftables/63001 +2102 -0
  249. sage_wheels/share/factory/gftables/64 +5 -0
  250. sage_wheels/share/factory/gftables/6561 +221 -0
  251. sage_wheels/share/factory/gftables/6859 +231 -0
  252. sage_wheels/share/factory/gftables/6889 +232 -0
  253. sage_wheels/share/factory/gftables/729 +27 -0
  254. sage_wheels/share/factory/gftables/7921 +266 -0
  255. sage_wheels/share/factory/gftables/8 +3 -0
  256. sage_wheels/share/factory/gftables/81 +5 -0
  257. sage_wheels/share/factory/gftables/8192 +276 -0
  258. sage_wheels/share/factory/gftables/841 +30 -0
  259. sage_wheels/share/factory/gftables/9 +3 -0
  260. sage_wheels/share/factory/gftables/9409 +316 -0
  261. sage_wheels/share/factory/gftables/961 +34 -0
  262. sage_wheels/share/info/singular.info +191898 -0
  263. sage_wheels/share/singular/LIB/GND.lib +1359 -0
  264. sage_wheels/share/singular/LIB/JMBTest.lib +976 -0
  265. sage_wheels/share/singular/LIB/JMSConst.lib +1363 -0
  266. sage_wheels/share/singular/LIB/KVequiv.lib +699 -0
  267. sage_wheels/share/singular/LIB/SingularityDBM.lib +491 -0
  268. sage_wheels/share/singular/LIB/VecField.lib +1542 -0
  269. sage_wheels/share/singular/LIB/absfact.lib +959 -0
  270. sage_wheels/share/singular/LIB/ainvar.lib +730 -0
  271. sage_wheels/share/singular/LIB/aksaka.lib +419 -0
  272. sage_wheels/share/singular/LIB/alexpoly.lib +2542 -0
  273. sage_wheels/share/singular/LIB/algebra.lib +1193 -0
  274. sage_wheels/share/singular/LIB/all.lib +136 -0
  275. sage_wheels/share/singular/LIB/arcpoint.lib +514 -0
  276. sage_wheels/share/singular/LIB/arnold.lib +4553 -0
  277. sage_wheels/share/singular/LIB/arnoldclassify.lib +2058 -0
  278. sage_wheels/share/singular/LIB/arr.lib +3486 -0
  279. sage_wheels/share/singular/LIB/assprimeszerodim.lib +755 -0
  280. sage_wheels/share/singular/LIB/autgradalg.lib +3361 -0
  281. sage_wheels/share/singular/LIB/bfun.lib +1964 -0
  282. sage_wheels/share/singular/LIB/bimodules.lib +774 -0
  283. sage_wheels/share/singular/LIB/brillnoether.lib +226 -0
  284. sage_wheels/share/singular/LIB/brnoeth.lib +5017 -0
  285. sage_wheels/share/singular/LIB/central.lib +2169 -0
  286. sage_wheels/share/singular/LIB/chern.lib +4162 -0
  287. sage_wheels/share/singular/LIB/cimonom.lib +571 -0
  288. sage_wheels/share/singular/LIB/cisimplicial.lib +1835 -0
  289. sage_wheels/share/singular/LIB/classify.lib +3239 -0
  290. sage_wheels/share/singular/LIB/classify2.lib +1462 -0
  291. sage_wheels/share/singular/LIB/classifyMapGerms.lib +1515 -0
  292. sage_wheels/share/singular/LIB/classify_aeq.lib +3253 -0
  293. sage_wheels/share/singular/LIB/classifyceq.lib +2092 -0
  294. sage_wheels/share/singular/LIB/classifyci.lib +1133 -0
  295. sage_wheels/share/singular/LIB/combinat.lib +91 -0
  296. sage_wheels/share/singular/LIB/compregb.lib +276 -0
  297. sage_wheels/share/singular/LIB/control.lib +1636 -0
  298. sage_wheels/share/singular/LIB/crypto.lib +3795 -0
  299. sage_wheels/share/singular/LIB/curveInv.lib +667 -0
  300. sage_wheels/share/singular/LIB/curvepar.lib +1817 -0
  301. sage_wheels/share/singular/LIB/customstd.lib +100 -0
  302. sage_wheels/share/singular/LIB/deRham.lib +5979 -0
  303. sage_wheels/share/singular/LIB/decodegb.lib +2134 -0
  304. sage_wheels/share/singular/LIB/decomp.lib +1655 -0
  305. sage_wheels/share/singular/LIB/deflation.lib +872 -0
  306. sage_wheels/share/singular/LIB/deform.lib +925 -0
  307. sage_wheels/share/singular/LIB/difform.lib +3055 -0
  308. sage_wheels/share/singular/LIB/divisors.lib +750 -0
  309. sage_wheels/share/singular/LIB/dmod.lib +5817 -0
  310. sage_wheels/share/singular/LIB/dmodapp.lib +3269 -0
  311. sage_wheels/share/singular/LIB/dmodideal.lib +1211 -0
  312. sage_wheels/share/singular/LIB/dmodloc.lib +2645 -0
  313. sage_wheels/share/singular/LIB/dmodvar.lib +818 -0
  314. sage_wheels/share/singular/LIB/dummy.lib +17 -0
  315. sage_wheels/share/singular/LIB/elim.lib +1009 -0
  316. sage_wheels/share/singular/LIB/ellipticcovers.lib +548 -0
  317. sage_wheels/share/singular/LIB/enumpoints.lib +146 -0
  318. sage_wheels/share/singular/LIB/equising.lib +2127 -0
  319. sage_wheels/share/singular/LIB/ffmodstd.lib +2384 -0
  320. sage_wheels/share/singular/LIB/ffsolve.lib +1289 -0
  321. sage_wheels/share/singular/LIB/findifs.lib +778 -0
  322. sage_wheels/share/singular/LIB/finitediff.lib +1768 -0
  323. sage_wheels/share/singular/LIB/finvar.lib +7989 -0
  324. sage_wheels/share/singular/LIB/fpadim.lib +2429 -0
  325. sage_wheels/share/singular/LIB/fpalgebras.lib +1666 -0
  326. sage_wheels/share/singular/LIB/fpaprops.lib +1462 -0
  327. sage_wheels/share/singular/LIB/freegb.lib +3853 -0
  328. sage_wheels/share/singular/LIB/general.lib +1350 -0
  329. sage_wheels/share/singular/LIB/gfan.lib +1768 -0
  330. sage_wheels/share/singular/LIB/gitfan.lib +3130 -0
  331. sage_wheels/share/singular/LIB/gkdim.lib +99 -0
  332. sage_wheels/share/singular/LIB/gmspoly.lib +589 -0
  333. sage_wheels/share/singular/LIB/gmssing.lib +1739 -0
  334. sage_wheels/share/singular/LIB/goettsche.lib +909 -0
  335. sage_wheels/share/singular/LIB/graal.lib +1366 -0
  336. sage_wheels/share/singular/LIB/gradedModules.lib +2541 -0
  337. sage_wheels/share/singular/LIB/graphics.lib +360 -0
  338. sage_wheels/share/singular/LIB/grobcov.lib +7706 -0
  339. sage_wheels/share/singular/LIB/groups.lib +1123 -0
  340. sage_wheels/share/singular/LIB/grwalk.lib +507 -0
  341. sage_wheels/share/singular/LIB/hdepth.lib +194 -0
  342. sage_wheels/share/singular/LIB/help.cnf +57 -0
  343. sage_wheels/share/singular/LIB/hess.lib +1946 -0
  344. sage_wheels/share/singular/LIB/hnoether.lib +4292 -0
  345. sage_wheels/share/singular/LIB/hodge.lib +400 -0
  346. sage_wheels/share/singular/LIB/homolog.lib +1965 -0
  347. sage_wheels/share/singular/LIB/hyperel.lib +975 -0
  348. sage_wheels/share/singular/LIB/inout.lib +679 -0
  349. sage_wheels/share/singular/LIB/integralbasis.lib +6224 -0
  350. sage_wheels/share/singular/LIB/interval.lib +1418 -0
  351. sage_wheels/share/singular/LIB/intprog.lib +778 -0
  352. sage_wheels/share/singular/LIB/invar.lib +443 -0
  353. sage_wheels/share/singular/LIB/involut.lib +980 -0
  354. sage_wheels/share/singular/LIB/jacobson.lib +1215 -0
  355. sage_wheels/share/singular/LIB/kskernel.lib +534 -0
  356. sage_wheels/share/singular/LIB/latex.lib +3146 -0
  357. sage_wheels/share/singular/LIB/lejeune.lib +651 -0
  358. sage_wheels/share/singular/LIB/linalg.lib +2040 -0
  359. sage_wheels/share/singular/LIB/locnormal.lib +212 -0
  360. sage_wheels/share/singular/LIB/lrcalc.lib +526 -0
  361. sage_wheels/share/singular/LIB/makedbm.lib +294 -0
  362. sage_wheels/share/singular/LIB/mathml.lib +813 -0
  363. sage_wheels/share/singular/LIB/matrix.lib +1372 -0
  364. sage_wheels/share/singular/LIB/maxlike.lib +1132 -0
  365. sage_wheels/share/singular/LIB/methods.lib +212 -0
  366. sage_wheels/share/singular/LIB/moddiq.lib +322 -0
  367. sage_wheels/share/singular/LIB/modfinduni.lib +181 -0
  368. sage_wheels/share/singular/LIB/modnormal.lib +218 -0
  369. sage_wheels/share/singular/LIB/modprimdec.lib +1278 -0
  370. sage_wheels/share/singular/LIB/modquotient.lib +269 -0
  371. sage_wheels/share/singular/LIB/modstd.lib +1024 -0
  372. sage_wheels/share/singular/LIB/modular.lib +545 -0
  373. sage_wheels/share/singular/LIB/modules.lib +2561 -0
  374. sage_wheels/share/singular/LIB/modwalk.lib +609 -0
  375. sage_wheels/share/singular/LIB/mondromy.lib +1016 -0
  376. sage_wheels/share/singular/LIB/monomialideal.lib +3851 -0
  377. sage_wheels/share/singular/LIB/mprimdec.lib +2353 -0
  378. sage_wheels/share/singular/LIB/mregular.lib +1863 -0
  379. sage_wheels/share/singular/LIB/multigrading.lib +5629 -0
  380. sage_wheels/share/singular/LIB/ncHilb.lib +777 -0
  381. sage_wheels/share/singular/LIB/ncModslimgb.lib +791 -0
  382. sage_wheels/share/singular/LIB/ncalg.lib +16311 -0
  383. sage_wheels/share/singular/LIB/ncall.lib +31 -0
  384. sage_wheels/share/singular/LIB/ncdecomp.lib +468 -0
  385. sage_wheels/share/singular/LIB/ncfactor.lib +13371 -0
  386. sage_wheels/share/singular/LIB/ncfrac.lib +1023 -0
  387. sage_wheels/share/singular/LIB/nchilbert.lib +448 -0
  388. sage_wheels/share/singular/LIB/nchomolog.lib +759 -0
  389. sage_wheels/share/singular/LIB/ncloc.lib +361 -0
  390. sage_wheels/share/singular/LIB/ncpreim.lib +795 -0
  391. sage_wheels/share/singular/LIB/ncrat.lib +2849 -0
  392. sage_wheels/share/singular/LIB/nctools.lib +1887 -0
  393. sage_wheels/share/singular/LIB/nets.lib +1456 -0
  394. sage_wheels/share/singular/LIB/nfmodstd.lib +1000 -0
  395. sage_wheels/share/singular/LIB/nfmodsyz.lib +732 -0
  396. sage_wheels/share/singular/LIB/noether.lib +1106 -0
  397. sage_wheels/share/singular/LIB/normal.lib +8700 -0
  398. sage_wheels/share/singular/LIB/normaliz.lib +2226 -0
  399. sage_wheels/share/singular/LIB/ntsolve.lib +362 -0
  400. sage_wheels/share/singular/LIB/numerAlg.lib +560 -0
  401. sage_wheels/share/singular/LIB/numerDecom.lib +2261 -0
  402. sage_wheels/share/singular/LIB/olga.lib +1933 -0
  403. sage_wheels/share/singular/LIB/orbitparam.lib +351 -0
  404. sage_wheels/share/singular/LIB/parallel.lib +319 -0
  405. sage_wheels/share/singular/LIB/paraplanecurves.lib +3110 -0
  406. sage_wheels/share/singular/LIB/perron.lib +202 -0
  407. sage_wheels/share/singular/LIB/pfd.lib +2223 -0
  408. sage_wheels/share/singular/LIB/phindex.lib +642 -0
  409. sage_wheels/share/singular/LIB/pointid.lib +673 -0
  410. sage_wheels/share/singular/LIB/polybori.lib +1430 -0
  411. sage_wheels/share/singular/LIB/polyclass.lib +525 -0
  412. sage_wheels/share/singular/LIB/polylib.lib +1174 -0
  413. sage_wheels/share/singular/LIB/polymake.lib +1902 -0
  414. sage_wheels/share/singular/LIB/presolve.lib +1533 -0
  415. sage_wheels/share/singular/LIB/primdec.lib +9576 -0
  416. sage_wheels/share/singular/LIB/primdecint.lib +1782 -0
  417. sage_wheels/share/singular/LIB/primitiv.lib +401 -0
  418. sage_wheels/share/singular/LIB/puiseuxexpansions.lib +1631 -0
  419. sage_wheels/share/singular/LIB/purityfiltration.lib +960 -0
  420. sage_wheels/share/singular/LIB/qhmoduli.lib +1561 -0
  421. sage_wheels/share/singular/LIB/qmatrix.lib +293 -0
  422. sage_wheels/share/singular/LIB/random.lib +455 -0
  423. sage_wheels/share/singular/LIB/ratgb.lib +489 -0
  424. sage_wheels/share/singular/LIB/realclassify.lib +5759 -0
  425. sage_wheels/share/singular/LIB/realizationMatroids.lib +772 -0
  426. sage_wheels/share/singular/LIB/realrad.lib +1197 -0
  427. sage_wheels/share/singular/LIB/recover.lib +2628 -0
  428. sage_wheels/share/singular/LIB/redcgs.lib +3984 -0
  429. sage_wheels/share/singular/LIB/reesclos.lib +465 -0
  430. sage_wheels/share/singular/LIB/resbinomial.lib +2802 -0
  431. sage_wheels/share/singular/LIB/resgraph.lib +789 -0
  432. sage_wheels/share/singular/LIB/resjung.lib +820 -0
  433. sage_wheels/share/singular/LIB/resolve.lib +5110 -0
  434. sage_wheels/share/singular/LIB/resources.lib +170 -0
  435. sage_wheels/share/singular/LIB/reszeta.lib +5473 -0
  436. sage_wheels/share/singular/LIB/ring.lib +1328 -0
  437. sage_wheels/share/singular/LIB/ringgb.lib +343 -0
  438. sage_wheels/share/singular/LIB/rinvar.lib +1153 -0
  439. sage_wheels/share/singular/LIB/rootisolation.lib +1481 -0
  440. sage_wheels/share/singular/LIB/rootsmr.lib +709 -0
  441. sage_wheels/share/singular/LIB/rootsur.lib +886 -0
  442. sage_wheels/share/singular/LIB/rstandard.lib +607 -0
  443. sage_wheels/share/singular/LIB/rwalk.lib +336 -0
  444. sage_wheels/share/singular/LIB/sagbi.lib +1353 -0
  445. sage_wheels/share/singular/LIB/sagbiNormaliz.lib +1622 -0
  446. sage_wheels/share/singular/LIB/sagbiNormaliz0.lib +1498 -0
  447. sage_wheels/share/singular/LIB/sagbigrob.lib +449 -0
  448. sage_wheels/share/singular/LIB/schreyer.lib +321 -0
  449. sage_wheels/share/singular/LIB/schubert.lib +2551 -0
  450. sage_wheels/share/singular/LIB/sets.lib +524 -0
  451. sage_wheels/share/singular/LIB/sheafcoh.lib +1663 -0
  452. sage_wheels/share/singular/LIB/signcond.lib +437 -0
  453. sage_wheels/share/singular/LIB/sing.lib +1094 -0
  454. sage_wheels/share/singular/LIB/sing4ti2.lib +419 -0
  455. sage_wheels/share/singular/LIB/solve.lib +2243 -0
  456. sage_wheels/share/singular/LIB/spcurve.lib +1077 -0
  457. sage_wheels/share/singular/LIB/spectrum.lib +62 -0
  458. sage_wheels/share/singular/LIB/sresext.lib +757 -0
  459. sage_wheels/share/singular/LIB/ssi.lib +143 -0
  460. sage_wheels/share/singular/LIB/standard.lib +2769 -0
  461. sage_wheels/share/singular/LIB/stanleyreisner.lib +473 -0
  462. sage_wheels/share/singular/LIB/stdmodule.lib +547 -0
  463. sage_wheels/share/singular/LIB/stratify.lib +1070 -0
  464. sage_wheels/share/singular/LIB/surf.lib +506 -0
  465. sage_wheels/share/singular/LIB/surf_jupyter.lib +223 -0
  466. sage_wheels/share/singular/LIB/surfacesignature.lib +522 -0
  467. sage_wheels/share/singular/LIB/surfex.lib +1462 -0
  468. sage_wheels/share/singular/LIB/swalk.lib +877 -0
  469. sage_wheels/share/singular/LIB/symodstd.lib +1570 -0
  470. sage_wheels/share/singular/LIB/systhreads.lib +74 -0
  471. sage_wheels/share/singular/LIB/tasks.lib +1324 -0
  472. sage_wheels/share/singular/LIB/tateProdCplxNegGrad.lib +2412 -0
  473. sage_wheels/share/singular/LIB/teachstd.lib +858 -0
  474. sage_wheels/share/singular/LIB/template.lib +116 -0
  475. sage_wheels/share/singular/LIB/toric.lib +1119 -0
  476. sage_wheels/share/singular/LIB/transformation.lib +116 -0
  477. sage_wheels/share/singular/LIB/triang.lib +1197 -0
  478. sage_wheels/share/singular/LIB/tropical.lib +8741 -0
  479. sage_wheels/share/singular/LIB/tropicalEllipticCovers.lib +2922 -0
  480. sage_wheels/share/singular/LIB/tropicalNewton.lib +1128 -0
  481. sage_wheels/share/singular/LIB/tst.lib +1108 -0
  482. sage_wheels/share/singular/LIB/weierstr.lib +241 -0
  483. sage_wheels/share/singular/LIB/zeroset.lib +1478 -0
  484. sage_wheels/share/singular/emacs/.emacs-general +184 -0
  485. sage_wheels/share/singular/emacs/.emacs-singular +234 -0
  486. sage_wheels/share/singular/emacs/COPYING +44 -0
  487. sage_wheels/share/singular/emacs/cmd-cmpl.el +241 -0
  488. sage_wheels/share/singular/emacs/ex-cmpl.el +1681 -0
  489. sage_wheels/share/singular/emacs/hlp-cmpl.el +4318 -0
  490. sage_wheels/share/singular/emacs/lib-cmpl.el +179 -0
  491. sage_wheels/share/singular/emacs/singular.el +4273 -0
  492. sage_wheels/share/singular/emacs/singular.xpm +39 -0
  493. sage_wheels/share/singular/singular.idx +5002 -0
@@ -0,0 +1,4292 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+ version="version hnoether.lib 4.1.2.0 Feb_2019 "; // $Id: d4cdabd1c3d9eea5ed69888b50820f22475ad6fa $
3
+
4
+ category="Singularities";
5
+ info="
6
+ LIBRARY: hnoether.lib Hamburger-Noether (Puiseux) Expansion
7
+ AUTHORS: Martin Lamm, lamm@mathematik.uni-kl.de
8
+ Christoph Lossen, lossen@mathematik.uni-kl.de
9
+
10
+ OVERVIEW:
11
+ A library for computing the Hamburger-Noether expansion (analogue of
12
+ Puiseux expansion over fields of arbitrary characteristic) of a reduced
13
+ plane curve singularity following [Campillo, A.: Algebroid curves in
14
+ positive characteristic, Springer LNM 813 (1980)]. @*
15
+ The library contains also procedures for computing the (topological)
16
+ numerical invariants of plane curve singularities.
17
+
18
+ PROCEDURES:
19
+ hnexpansion(f [,\"ess\"]); Hamburger-Noether (HN) expansion of f
20
+ develop(f [,n]); HN expansion of irreducible plane curve germs
21
+ extdevelop(hne,n); extension of the H-N expansion hne of f
22
+ param(hne [,s]); parametrization of branches described by HN data
23
+ displayHNE(hne); display HN expansion as an ideal
24
+ invariants(hne); invariants of f, e.g. the characteristic exponents
25
+ displayInvariants(hne); display invariants of f
26
+ multsequence(hne); sequence of multiplicities
27
+ displayMultsequence(hne); display sequence of multiplicities
28
+ intersection(hne1,hne2); intersection multiplicity of two local branches
29
+ is_irred(f); test whether f is irreducible as power series
30
+ delta(f); delta invariant of f
31
+ newtonpoly(f); (local) Newton polygon of f
32
+ is_NND(f); test whether f is Newton non-degenerate
33
+
34
+
35
+ stripHNE(hne); reduce amount of memory consumed by hne
36
+ puiseux2generators(m,n); convert Puiseux pairs to generators of semigroup
37
+ separateHNE(hne1,hne2); number of quadratic transf. needed for separation
38
+ squarefree(f); a squarefree divisor of the polynomial f
39
+ allsquarefree(f,l); the maximal squarefree divisor of the polynomial f
40
+ further_hn_proc(); show further procedures useful for interactive use
41
+
42
+ KEYWORDS: Hamburger-Noether expansion; Puiseux expansion; curve singularities
43
+ ";
44
+
45
+ // essdevelop(f); HN expansion of essential branches
46
+ // multiplicities(hne); multiplicities of blowed up curves
47
+
48
+ ///////////////////////////////////////////////////////////////////////////////
49
+ LIB "primitiv.lib";
50
+ LIB "inout.lib";
51
+ LIB "sing.lib";
52
+ LIB "ring.lib";
53
+
54
+ ///////////////////////////////////////////////////////////////////////////////
55
+
56
+ proc further_hn_proc()
57
+ "USAGE: further_hn_proc();
58
+ NOTE: The library @code{hnoether.lib} contains some more procedures which
59
+ are not shown when typing @code{help hnoether.lib;}. They may be useful
60
+ for interactive use (e.g. if you want to do the calculation of an HN
61
+ development \"by hand\" to see the intermediate results), and they
62
+ can be enumerated by calling @code{further_hn_proc()}. @*
63
+ Use @code{help <procedure>;} for detailed information about each of
64
+ them.
65
+ "
66
+ {
67
+ "
68
+ The following procedures are also part of 'hnoether.lib':
69
+
70
+ getnm(f); intersection pts. of Newton polygon with axes
71
+ T_Transform(f,Q,N); returns f(y,xy^Q)/y^NQ (f: poly, Q,N: int)
72
+ T1_Transform(f,d,M); returns f(x,y+d*x^M) (f: poly,d:number,M:int)
73
+ T2_Transform(f,d,M,N,ref); a composition of T1 & T
74
+ koeff(f,I,J); gets coefficient of indicated monomial of polynomial f
75
+ redleit(f,S,E); restriction of monomials of f to line (S-E)
76
+ leit(f,n,m); special case of redleit (for irred. polynomials)
77
+ testreducible(f,n,m); tests whether f is reducible
78
+ charPoly(f,M,N); characteristic polynomial of f
79
+ find_in_list(L,p); find int p in list L
80
+ get_last_divisor(M,N); last divisor in Euclid's algorithm
81
+ factorfirst(f,M,N); try to factor f without 'factorize'
82
+ factorlist(L); factorize a list L of polynomials
83
+ referencepoly(D); a polynomial f s.t. D is the Newton diagram of f";
84
+
85
+ // static procedures not useful for interactive use:
86
+ // polytest(f); tests coefficients and exponents of polynomial f
87
+ // extractHNEs(H,t); extracts output H of HN to output of hnexpansion
88
+ // HN(f,grenze); recursive subroutine for hnexpansion
89
+ // constructHNEs(...); subroutine for HN
90
+ }
91
+ example
92
+ { echo=2;
93
+ further_hn_proc();
94
+ }
95
+ ///////////////////////////////////////////////////////////////////////////////
96
+
97
+ proc getnm (poly f)
98
+ "USAGE: getnm(f); f bivariate polynomial
99
+ RETURN: intvec(n,m) : (0,n) is the intersection point of the Newton
100
+ polygon of f with the y-axis, n=-1 if it doesn't exist
101
+ (m,0) is its intersection point with the x-axis,
102
+ m=-1 if this point doesn't exist
103
+ ASSUME: ring has ordering 'ls' or 'ds'
104
+ EXAMPLE: example getnm; shows an example
105
+ "
106
+ {
107
+ // assume being called by develop ==> ring ordering is ls (ds would also work)
108
+ return(ord(subst(f,var(1),0)),ord(subst(f,var(2),0)));
109
+ }
110
+ example
111
+ { "EXAMPLE:"; echo = 2;
112
+ ring r = 0,(x,y),ds;
113
+ poly f = x5+x4y3-y2+y4;
114
+ getnm(f);
115
+ }
116
+ ///////////////////////////////////////////////////////////////////////////////
117
+
118
+ proc leit (poly f, int n, int m)
119
+ "USAGE: leit(f,n,m); poly f, int n,m
120
+ RETURN: all monomials on the line from (0,n) to (m,0) in the Newton diagram
121
+ EXAMPLE: example leit; shows an example
122
+ "
123
+ {
124
+ return(jet(f,m*n,intvec(n,m))-jet(f,m*n-1,intvec(n,m)))
125
+ }
126
+ example
127
+ { "EXAMPLE:"; echo = 2;
128
+ ring r = 0,(x,y),ds;
129
+ poly f = x5+x4y3-y2+y4;
130
+ leit(f,2,5);
131
+ }
132
+ ///////////////////////////////////////////////////////////////////////////////
133
+ proc testreducible (poly f, int n, int m)
134
+ "USAGE: testreducible(f,n,m); f poly, n,m int
135
+ RETURN: 1 if there are points in the Newton diagram below the line (0,n)-(m,0)
136
+ 0 else
137
+ EXAMPLE: example testreducible; shows an example
138
+ "
139
+ {
140
+ return(size(jet(f,m*n-1,intvec(n,m))) != 0)
141
+ }
142
+ example
143
+ { "EXAMPLE:"; echo = 2;
144
+ ring rg=0,(x,y),ls;
145
+ testreducible(x2+y3-xy4,3,2);
146
+ }
147
+ ///////////////////////////////////////////////////////////////////////////////
148
+ proc T_Transform (poly f, int Q, int N)
149
+ "USAGE: T_Transform(f,Q,N); f poly, Q,N int
150
+ RETURN: f(y,xy^Q)/y^NQ if x,y are the ring variables
151
+ NOTE: this is intended for irreducible power series f
152
+ EXAMPLE: example T_Transform; shows an example
153
+ "
154
+ {
155
+ map T = basering,var(2),var(1)*var(2)^Q;
156
+ return(T(f)/var(2)^(N*Q));
157
+ }
158
+ example
159
+ { "EXAMPLE:"; echo = 2;
160
+ ring exrg=0,(x,y),ls;
161
+ export exrg;
162
+ T_Transform(x3+y2-xy3,1,2);
163
+ kill exrg;
164
+ }
165
+ ///////////////////////////////////////////////////////////////////////////////
166
+ proc T1_Transform (poly f, number d, int Q)
167
+ "USAGE: T1_Transform(f,d,Q); f poly, d number, Q int
168
+ RETURN: f(x,y+d*x^Q) if x,y are the ring variables
169
+ EXAMPLE: example T1_Transform; shows an example
170
+ "
171
+ {
172
+ map T1 = basering,var(1),var(2)+d*var(1)^Q;
173
+ return(T1(f));
174
+ }
175
+ example
176
+ { "EXAMPLE:"; echo = 2;
177
+ ring exrg=0,(x,y),ls;
178
+ export exrg;
179
+ T1_Transform(y2-2xy+x2+x2y,1,1);
180
+ kill exrg;
181
+ }
182
+ ///////////////////////////////////////////////////////////////////////////////
183
+
184
+ proc T2_Transform (poly f_neu, number d, int M, int N, poly refpoly)
185
+ "USAGE: T2_Transform(f,d,M,N,ref); f poly, d number; M,N int; ref poly
186
+ RETURN: list: poly T2(f,d',M,N), number d' in \{ d, 1/d \}
187
+ ASSUME: ref has the same Newton polygon as f (but can be simpler)
188
+ for this you can e.g. use the proc 'referencepoly' or simply f again
189
+ COMMENT: T2 is a composition of T_Transform and T1_Transform; the exact
190
+ definition can be found in Rybowicz: 'Sur le calcul des places ...'
191
+ or in Lamm: 'Hamburger-Noether-Entwicklung von Kurvensingularitaeten'
192
+ SEE ALSO: T_Transform, T1_Transform, referencepoly
193
+ EXAMPLE: example T2_Transform; shows an example
194
+ "
195
+ {
196
+ //---------------------- compute gcd and extgcd of N,M -----------------------
197
+ int ggt=gcd(M,N);
198
+ M=M div ggt; N=N div ggt;
199
+ list ts=extgcd(M,N);
200
+ int tau,sigma=ts[2],-ts[3];
201
+ int s,t;
202
+ poly xp=var(1);
203
+ poly yp=var(2);
204
+ poly hilf;
205
+ if (sigma<0) { tau=-tau; sigma=-sigma;}
206
+ // es gilt: 0<=tau<=N, 0<=sigma<=M, |N*sigma-M*tau| = 1 = ggT(M,N)
207
+ if (N*sigma < M*tau) { d = 1/d; }
208
+ //--------------------------- euklid. Algorithmus ----------------------------
209
+ int R;
210
+ int M1,N1=M,N;
211
+ for ( R=M1%N1; R!=0; ) { M1=N1; N1=R; R=M1%N1;}
212
+ int Q=M1 div N1;
213
+ map T1 = basering,xp,yp+d*xp^Q;
214
+ map Tstar=basering,xp^(N-Q*tau)*yp^tau,xp^(M-sigma*Q)*yp^sigma;
215
+ if (defined(HNDebugOn)) {
216
+ "Trafo. T2: x->x^"+string(N-Q*tau)+"*y^"+string(tau)+", y->x^"
217
+ +string(M-sigma*Q)+"*y^"+string(sigma);
218
+ "delt =",d,"Q =",Q,"tau,sigma =",tau,sigma;
219
+ }
220
+ //------------------- Durchfuehrung der Transformation T2 --------------------
221
+ f_neu=Tstar(f_neu);
222
+ refpoly=Tstar(refpoly);
223
+ //--- dividiere f_neu so lange durch x & y, wie die Division aufgeht,
224
+ // benutze ein Referenzpolynom mit gleichem Newtonpolynom wie f_neu zur
225
+ // Beschleunigung: ---
226
+ for (hilf=refpoly/xp; hilf*xp==refpoly; hilf=refpoly/xp) {refpoly=hilf; s++;}
227
+ for (hilf=refpoly/yp; hilf*yp==refpoly; hilf=refpoly/yp) {refpoly=hilf; t++;}
228
+ f_neu=f_neu/(xp^s*yp^t);
229
+ return(list(T1(f_neu),d));
230
+ }
231
+ example
232
+ { "EXAMPLE:"; echo = 2;
233
+ ring exrg=0,(x,y),ds;
234
+ export exrg;
235
+ poly f=y2-2x2y+x6-x5y+x4y2;
236
+ T2_Transform(f,1/2,4,1,f);
237
+ T2_Transform(f,1/2,4,1,referencepoly(newtonpoly(f,1)));
238
+ // if size(referencepoly) << size(f) the 2nd example would be faster
239
+ referencepoly(newtonpoly(f,1));
240
+ kill exrg;
241
+ }
242
+ ///////////////////////////////////////////////////////////////////////////////
243
+
244
+ proc koeff (poly f, int I, int J)
245
+ "USAGE: koeff(f,I,J); f bivariate polynomial, I,J integers
246
+ RETURN: if f = sum(a(i,j)*x^i*y^j), then koeff(f,I,J)= a(I,J) (of type number)
247
+ NOTE: J must be in the range of the exponents of the 2nd ring variable
248
+ EXAMPLE: example koeff; shows an example
249
+ "
250
+ {
251
+ matrix mat = coeffs(coeffs(f,var(2))[J+1,1],var(1));
252
+ if (size(mat) <= I) { return(0);}
253
+ else { return(leadcoef(mat[I+1,1]));}
254
+ }
255
+ example
256
+ { "EXAMPLE:"; echo = 2;
257
+ ring r=0,(x,y),dp;
258
+ koeff(x2+2xy+3xy2-x2y-2y3,1,2);
259
+ }
260
+ ///////////////////////////////////////////////////////////////////////////////
261
+
262
+ proc squarefree (poly f)
263
+ "USAGE: squarefree(f); f poly
264
+ ASSUME: f is a bivariate polynomial (in the first 2 ring variables).
265
+ RETURN: poly, a squarefree divisor of f.
266
+ NOTE: Usually, the return value is the greatest squarefree divisor, but
267
+ there is one exception: factors with a p-th root, p the
268
+ characteristic of the basering, are lost.
269
+ SEE ALSO: allsquarefree
270
+ EXAMPLE: example squarefree; shows some examples.
271
+ "
272
+ {
273
+ //----------------- Wechsel in geeigneten Ring & Variablendefinition ---------
274
+ if (nvars(basering)!=2)
275
+ { ERROR("basering must have exactly 2 variables for Hnoether::squarefree"); }
276
+ def altring = basering;
277
+ int e;
278
+ string mipl="0";
279
+ if (size(parstr(altring))==1) { mipl=string(minpoly); }
280
+ //---- test: char = (p^k,a) (-> gcd not implemented) or (p,a) (gcd works) ----
281
+ //if ((char(basering)!=0) and (charstr(basering)!=string(char(basering))))
282
+ int gcd_ok= ! hasGFCoefficient(basering);
283
+ ring rsqrf = create_ring(ringlist(altring)[1],"(x,y)","dp","no_minpoly");
284
+ if ((gcd_ok!=0) && (mipl!="0")) { execute("minpoly="+mipl+";"); }
285
+ poly f=fetch(altring,f);
286
+ poly dif,g,l;
287
+ if (gcd_ok!=0) {
288
+ //--------------------- Berechne f/ggT(f,df/dx,df/dy) ------------------------
289
+ dif=diff(f,x);
290
+ if (dif==0) { g=f; } // zur Beschleunigung
291
+ else { g=gcd(f,dif); }
292
+ if (g!=1) { // sonst schon sicher, dass f quadratfrei
293
+ dif=diff(f,y);
294
+ if (dif!=0) { g=gcd(g,dif); }
295
+ }
296
+ if (g!=1) {
297
+ e=0;
298
+ if (g==f) { l=1; } // zur Beschleunigung
299
+ else {
300
+ module m=syz(ideal(g,f));
301
+ if (deg(m[2,1])>0) {
302
+ "!! The Singular command 'syz' has returned a wrong result !!";
303
+ l=1; // Division f/g muss aufgehen
304
+ }
305
+ else { l=m[1,1]; }
306
+ }
307
+ }
308
+ else { e=1; }
309
+ }
310
+ else {
311
+ //------------------- Berechne syz(f,df/dx) oder syz(f,df/dy) ----------------
312
+ //-- Achtung: Ist f reduzibel, koennen Faktoren mit Ableitung Null verloren --
313
+ //-- gehen! Ist aber nicht weiter schlimm, weil char (p^k,a) nur im irred. --
314
+ //-- Fall vorkommen kann. Wenn f nicht g^p ist, wird auf jeden Fall --
315
+ //------------------------ ein Faktor gefunden. ------------------------------
316
+ dif=diff(f,x);
317
+ if (dif == 0) {
318
+ dif=diff(f,y);
319
+ if (dif==0) { e=2; l=1; } // f is of power divisible by char of basefield
320
+ else { l=syz(ideal(dif,f))[1,1]; // x^p+y^(p-1) abgedeckt
321
+ if (subst(f,x,0)==0) { l=l*x; }
322
+ if (deg(l)==deg(f)) { e=1;}
323
+ else {e=0;}
324
+ }
325
+ }
326
+ else { l=syz(ideal(dif,f))[1,1];
327
+ if (subst(f,y,0)==0) { l=l*y; }
328
+ if (deg(l)==deg(f)) { e=1;}
329
+ else {e=0;}
330
+ }
331
+ }
332
+ //--------------- Wechsel in alten Ring und Rueckgabe des Ergebnisses --------
333
+ setring altring;
334
+ if (e==1) { return(f); } // zur Beschleunigung
335
+ else {
336
+ poly l=fetch(rsqrf,l);
337
+ return(l);
338
+ }
339
+ }
340
+ example
341
+ { "EXAMPLE:"; echo = 2;
342
+ ring exring=3,(x,y),dp;
343
+ squarefree((x3+y)^2);
344
+ squarefree((x+y)^3*(x-y)^2); // Warning: (x+y)^3 is lost
345
+ squarefree((x+y)^4*(x-y)^2); // result is (x+y)*(x-y)
346
+ }
347
+ ///////////////////////////////////////////////////////////////////////////////
348
+
349
+ proc allsquarefree (poly f, poly l)
350
+ "USAGE : allsquarefree(f,g); f,g poly
351
+ ASSUME: g is the output of @code{squarefree(f)}.
352
+ RETURN: the greatest squarefree divisor of f.
353
+ NOTE : This proc uses factorize to get the missing factors of f not in g and,
354
+ therefore, may be slow.
355
+ SEE ALSO: squarefree
356
+ EXAMPLE: example allsquarefree; shows an example
357
+ "
358
+ {
359
+ //------------------------ Wechsel in geeigneten Ring ------------------------
360
+ def altring = basering;
361
+ string mipl="0";
362
+ if (size(parstr(altring))==1) { mipl=string(minpoly); }
363
+ if (hasGFCoefficient(basering))
364
+ {
365
+ ERROR(" Sorry -- not implemented for this ring (gcd doesn't work)");
366
+ }
367
+ ring rsqrf = create_ring(ringlist(altring)[1],"(x,y)","dp","no_minpoly");
368
+ if (mipl!="0") { execute("minpoly="+mipl+";"); }
369
+ poly f=fetch(altring,f);
370
+ poly l=fetch(altring,l);
371
+ //---------- eliminiere bereits mit squarefree gefundene Faktoren ------------
372
+ poly g=l;
373
+ while (deg(g)!=0) {
374
+ f=syz(ideal(g,f))[1,1]; // f=f/g;
375
+ g=gcd(f,l);
376
+ } // jetzt f=h^p
377
+ //--------------- Berechne uebrige Faktoren mit factorize --------------------
378
+ if (deg(f)>0) {
379
+ g=1;
380
+ //*CL old: ideal factf=factorize(f,1);
381
+ //* for (int i=1; i<=size(factf); i++) { g=g*factf[i]; }
382
+ ideal factf=factorize(f)[1];
383
+ for (int i=2; i<=size(factf); i++) { g=g*factf[i]; }
384
+ poly testp=squarefree(g);
385
+ if (deg(testp)<deg(g)) {
386
+ "!! factorize has not worked correctly !!";
387
+ if (testp==1) {" We cannot proceed ..."; g=1;}
388
+ else {" But we could recover some factors..."; g=testp;}
389
+ }
390
+ l=l*g;
391
+ }
392
+ //--------------- Wechsel in alten Ring und Rueckgabe des Ergebnisses --------
393
+ setring altring;
394
+ l=fetch(rsqrf,l);
395
+ return(l);
396
+ }
397
+ example
398
+ { "EXAMPLE:"; echo = 2;
399
+ ring exring=7,(x,y),dp;
400
+ poly f=(x+y)^7*(x-y)^8;
401
+ poly g=squarefree(f);
402
+ g; // factor x+y lost, since characteristic=7
403
+ allsquarefree(f,g); // all factors (x+y)*(x-y) found
404
+ }
405
+ ///////////////////////////////////////////////////////////////////////////////
406
+
407
+ proc is_irred (poly f)
408
+ "USAGE: is_irred(f); f poly
409
+ ASSUME: f is a squarefree bivariate polynomial (in the first 2 ring
410
+ variables).
411
+ RETURN: int (0 or 1): @*
412
+ - @code{is_irred(f)=1} if f is irreducible as a formal power
413
+ series over the algebraic closure of its coefficient field (f
414
+ defines an analytically irreducible curve at zero), @*
415
+ - @code{is_irred(f)=0} otherwise.
416
+ NOTE: 0 and units in the ring of formal power series are considered to be
417
+ not irreducible.
418
+ KEYWORDS: irreducible power series
419
+ EXAMPLE: example is_irred; shows an example
420
+ "
421
+ {
422
+ int pl=printlevel;
423
+ printlevel=-1;
424
+ list hnl=develop(f,-1);
425
+ printlevel=pl;
426
+ return(hnl[5]);
427
+ }
428
+ example
429
+ { "EXAMPLE:"; echo = 2;
430
+ ring exring=0,(x,y),ls;
431
+ is_irred(x2+y3);
432
+ is_irred(x2+y2);
433
+ is_irred(x2+y3+1);
434
+ }
435
+ ///////////////////////////////////////////////////////////////////////////////
436
+
437
+ static proc polytest(poly f)
438
+ "USAGE : polytest(f); f poly in x and y
439
+ RETURN: a monomial of f with |coefficient| > 16001
440
+ or exponent divisible by 32003, if there is one
441
+ 0 else (in this case computing a squarefree divisor
442
+ in characteristic 32003 could make sense)
443
+ NOTE: this procedure is only useful in characteristic zero, because otherwise
444
+ there is no appropriate ordering of the leading coefficients
445
+ "
446
+ {
447
+ poly verbrecher=0;
448
+ intvec leitexp;
449
+ for (; (f<>0) and (verbrecher==0); f=f-lead(f)) {
450
+ if ((leadcoef(f)<-16001) or (leadcoef(f)>16001)) {verbrecher=lead(f);}
451
+ leitexp=leadexp(f);
452
+ if (( ((leitexp[1] % 32003) == 0) and (leitexp[1]<>0))
453
+ or ( ((leitexp[2] % 32003) == 0) and (leitexp[2]<>0)) )
454
+ {verbrecher=lead(f);}
455
+ }
456
+ return(verbrecher);
457
+ }
458
+
459
+ //////////////////////////////////////////////////////////////////////////////
460
+
461
+
462
+ proc develop(list #)
463
+ "USAGE: develop(f [,n]); f poly, n int
464
+ ASSUME: f is a bivariate polynomial (in the first 2 ring variables) and
465
+ irreducible as power series (for reducible f use @code{hnexpansion}).
466
+ RETURN: list @code{L} with:
467
+ @texinfo
468
+ @table @asis
469
+ @item @code{L[1]}; matrix:
470
+ Each row contains the coefficients of the corresponding line of the
471
+ Hamburger-Noether expansion (HNE). The end of the line is marked in
472
+ the matrix by the first ring variable (usually x).
473
+ @item @code{L[2]}; intvec:
474
+ indicating the length of lines of the HNE
475
+ @item @code{L[3]}; int:
476
+ 0 if the 1st ring variable was transversal (with respect to f), @*
477
+ 1 if the variables were changed at the beginning of the
478
+ computation, @*
479
+ -1 if an error has occurred.
480
+ @item @code{L[4]}; poly:
481
+ the transformed polynomial of f to make it possible to extend the
482
+ Hamburger-Noether development a posteriori without having to do
483
+ all the previous calculation once again (0 if not needed)
484
+ @item @code{L[5]}; int:
485
+ 1 if the curve has exactly one branch (i.e., is irreducible), @*
486
+ 0 else (i.e., the curve has more than one HNE, or f is not valid).
487
+ @end table
488
+ @end texinfo
489
+ DISPLAY: The (non zero) elements of the HNE (if not called by another proc).
490
+ NOTE: The optional parameter @code{n} affects only the computation of
491
+ the LAST line of the HNE. If it is given, the HN-matrix @code{L[1]}
492
+ will have at least @code{n} columns. @*
493
+ Otherwise, the number of columns will be chosen minimal such that the
494
+ matrix contains all necessary information (i.e., all lines of the HNE
495
+ but the last (which is in general infinite) have place). @*
496
+ If @code{n} is negative, the algorithm is stopped as soon as the
497
+ computed information is sufficient for @code{invariants(L)}, but the
498
+ HN-matrix @code{L[1]} may still contain undetermined elements, which
499
+ are marked with the 2nd variable (of the basering). @*
500
+ For time critical computations it is recommended to use
501
+ @code{ring ...,(x,y),ls} as basering - it increases the algorithm's
502
+ speed. @*
503
+ If @code{printlevel>=0} comments are displayed (default is
504
+ @code{printlevel=0}).
505
+ SEE ALSO: hnexpansion, extdevelop, displayHNE
506
+ EXAMPLES: example develop; shows an example
507
+ example parametrize; shows an example for using the 2nd parameter
508
+ "
509
+ {
510
+ //--------- Abfangen unzulaessiger Ringe: 1) nur eine Unbestimmte ------------
511
+ poly f=#[1];
512
+ if (size(#) > 1) {int maxspalte=#[2];}
513
+ else {int maxspalte= 1 ; }
514
+ if (nvars(basering) < 2) {
515
+ " Sorry. I need two variables in the ring.";
516
+ return(list(matrix(maxideal(1)[1]),intvec(0),-1,poly(0),0));}
517
+ if (nvars(basering) > 2) {
518
+ dbprint(printlevel-voice+2,
519
+ " Warning! You have defined too many variables!
520
+ All variables except the first two will be ignored!"
521
+ );
522
+ }
523
+
524
+ string namex=varstr(1); string namey=varstr(2);
525
+ list return_error=matrix(maxideal(1)[2]),intvec(0),int(-1),poly(0),int(0);
526
+
527
+ //------------- 2) mehrere Unbestimmte, weitere unzulaessige Ringe -----------
528
+ // Wir koennen einheitlichen Rueckgabewert benutzen, aus dem ersichtlich ist,
529
+ // dass ein Fehler aufgetreten ist: return_error.
530
+ //----------------------------------------------------------------------------
531
+
532
+ if (find(charstr(basering),"Float(")) {
533
+ " The algorithm doesn't work with 'Float' as coefficient field.";
534
+ // denn : map from characteristic -1 to -1 not implemented
535
+ return(return_error);
536
+ }
537
+ if (((char(basering)!=0)
538
+ and ((hasAlgExtensionCoefficient(basering)
539
+ ||(hasTransExtensionCoefficient(basering)))))
540
+ || (npars(basering)>1))
541
+ {
542
+ //-- teste, ob char = (p^k,a) (-> a primitiv; erlaubt) oder (p,a[,b,...]) ----
543
+ " Such extensions of Z/p are not implemented.";
544
+ " Please try (p^k,a) as ground field or use 'hnexpansion'.";
545
+ return(return_error);
546
+ }
547
+ //---- Ende der unzulaessigen Ringe; Ringwechsel in einen guenstigen Ring: ---
548
+
549
+ int ringwechsel=(varstr(basering)!="x,y") or (ordstr(basering)!="ls(2),C");
550
+
551
+ def altring = basering;
552
+ if (ringwechsel) {
553
+ string mipl=string(minpoly);
554
+ ring guenstig = create_ring(ringlist(altring)[1],"(x,y)","ls","no_minpoly");
555
+ if ((char(basering)==0) && (mipl!="0")) {
556
+ execute("minpoly="+mipl+";");
557
+ }}
558
+ else { def guenstig=basering; }
559
+ export guenstig;
560
+
561
+ //-------------------------- Initialisierungen -------------------------------
562
+ map m=altring,x,y;
563
+ if (ringwechsel) { poly f=m(f); }
564
+ if (defined(HNDebugOn))
565
+ {"received polynomial: ",f,", where x =",namex,", y =",namey;}
566
+ kill m;
567
+ int M,N,Q,R,l,e,hilf,eps,getauscht,Abbruch,zeile,exponent,Ausgabe;
568
+
569
+ // Werte von Ausgabe: 0 : normale HNE-Matrix,
570
+ // 1 : Fehler aufgetreten - Matrix (namey) zurueck
571
+ // 2 : Die HNE ist eine Nullzeile - Matrix (0) zurueck
572
+ // int maxspalte=1; geaendert: wird jetzt am Anfang gesetzt
573
+
574
+ int minimalHNE=0; // Flag fuer minimale HNE-Berechnung
575
+ int einzweig=1; // Flag fuer Irreduzibilit"at
576
+ intvec hqs; // erhaelt die Werte von h(zeile)=Q;
577
+
578
+ if (maxspalte<0) {
579
+ minimalHNE=1;
580
+ maxspalte=1;
581
+ }
582
+
583
+ number c,delt;
584
+ int p = char(basering);
585
+ map xytausch = basering,y,x;
586
+ if ((p!=0) and (hasGFCoefficient(basering))) {
587
+ // coefficient field is extension of Z/pZ
588
+ int n_elements=size(basering);
589
+ // number of elements of actual ring
590
+ number generat=par(1); // generator of the coefficient field of the ring
591
+ }
592
+
593
+
594
+ //========= Abfangen von unzulaessigen oder trivialen Eingaben ===============
595
+ //------------ Nullpolynom oder Einheit im Potenzreihenring: -----------------
596
+ if (f == 0) {
597
+ dbprint(printlevel+1,"The given polynomial is the zero-polynomial !");
598
+ Abbruch=1; Ausgabe=1;
599
+ }
600
+ else {
601
+ intvec nm = getnm(f);
602
+ N = nm[1]; M = nm[2]; // Berechne Schnittpunkte Newtonpolygon mit Achsen
603
+ if (N == 0) {
604
+ dbprint(printlevel+1,"The given polynomial is a unit as power series !");
605
+ Abbruch=1; Ausgabe=1;
606
+ }
607
+ else {
608
+ if (N == -1) {
609
+ if ((voice==2) && (printlevel > -1)) { "The HNE is x = 0"; }
610
+ Abbruch=1; Ausgabe=2; getauscht=1;
611
+ if (M <> 1) { einzweig=0; }
612
+ }
613
+ else {
614
+ if (M == -1) {
615
+ if ((voice==2) && (printlevel > -1)) { "The HNE is y = 0"; }
616
+ Abbruch=1; Ausgabe=2;
617
+ if (N <> 1) { einzweig=0; }
618
+ }}}
619
+ }
620
+ //--------------------- Test auf Quadratfreiheit -----------------------------
621
+ if (Abbruch==0) {
622
+
623
+ //-------- Fall basering==0,... : Wechsel in Ring mit char >0 ----------------
624
+ // weil squarefree eine Standardbasis berechnen muss (verwendet Syzygien)
625
+ // -- wenn f in diesem Ring quadratfrei ist, dann erst recht im Ring guenstig
626
+ //----------------------------------------------------------------------------
627
+
628
+ if ((p==0) and (size(charstr(basering))==1)) {
629
+ int testerg=(polytest(f)==0);
630
+ ring zweitring = 32003,(x,y),dp;
631
+ map polyhinueber=guenstig,x,y; // fetch geht nicht
632
+ poly f=polyhinueber(f);
633
+ poly test_sqr=squarefree(f);
634
+ if (test_sqr != f) {
635
+ if (printlevel>0) {
636
+ "Most probably the given polynomial is not squarefree. But the test was";
637
+ "made in characteristic 32003 and not 0 to improve speed. You can";
638
+ "(r) redo the test in char 0 (but this may take some time)";
639
+ "(c) continue the development, if you're sure that the polynomial",
640
+ "IS squarefree";
641
+ if (testerg==1) {
642
+ "(s) continue the development with a squarefree factor (*)";}
643
+ "(q) or just quit the algorithm (default action)";
644
+ "";"Please enter the letter of your choice:";
645
+ string str=read("")[1];
646
+ }
647
+ else { string str="r"; } // printlevel <= 0: non-interactive behaviour
648
+ setring guenstig;
649
+ map polyhinueber=zweitring,x,y;
650
+ if (str=="r") {
651
+ poly test_sqr=squarefree(f);
652
+ if (test_sqr != f) {
653
+ if (printlevel>0) { "The given polynomial is in fact not squarefree."; }
654
+ else { "The given polynomial is not squarefree!"; }
655
+ "I'll continue with the radical.";
656
+ if (printlevel>0) { pause("Hit RETURN to continue:"); }
657
+ f=test_sqr;
658
+ }
659
+ else {
660
+ dbprint(printlevel,
661
+ "everything is ok -- the polynomial is squarefree in char(k)=0");
662
+ }
663
+ }
664
+ else {
665
+ if ((str=="s") and (testerg==1)) {
666
+ "(*) attention: it could be that the factor is only one in char 32003!";
667
+ f=polyhinueber(test_sqr);
668
+ }
669
+ else {
670
+ if (str<>"c") {
671
+ setring altring;kill guenstig;kill zweitring;
672
+ return(return_error);}
673
+ else { "if the algorithm doesn't terminate, you were wrong...";}
674
+ }}
675
+ kill zweitring;
676
+ nm = getnm(f); // N,M haben sich evtl. veraendert
677
+ N = nm[1]; M = nm[2]; // Berechne Schnittpunkte Newtonpolynom mit Achsen
678
+ if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
679
+ }
680
+ else {
681
+ setring guenstig;
682
+ kill zweitring;
683
+ }
684
+ }
685
+ // ------------------- Fall Charakteristik > 0 -------------------------------
686
+ else {
687
+ poly test_sqr=squarefree(f);
688
+ if (test_sqr == 1) {
689
+ "The given polynomial is of the form g^"+string(p)+", therefore",
690
+ "reducible.";"Please try again.";
691
+ setring altring;
692
+ kill guenstig;
693
+ return(return_error);}
694
+ if (test_sqr != f) {
695
+ "The given polynomial is not squarefree. I'll continue with the radical.";
696
+ if (p != 0)
697
+ {"But if the polynomial contains a factor of the form g^"+string(p)+",";
698
+ "this factor will be lost.";}
699
+ if (printlevel>0) { pause("Hit RETURN to continue:"); }
700
+ f=test_sqr;
701
+ nm = getnm(f); // N,M haben sich veraendert
702
+ N = nm[1]; M = nm[2]; // Berechne Schnittpunkte Newtonpolynom mit Achsen
703
+ if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
704
+ }
705
+
706
+ } // endelse(p==0)
707
+
708
+ if (N==0) {
709
+ " Sorry. The remaining polynomial is a unit in the power series ring...";
710
+ setring altring;kill guenstig;return(return_error);
711
+ }
712
+ //---------------------- gewaehrleiste, dass x transvers ist -----------------
713
+ if (M < N)
714
+ { f = xytausch(f); // Variablentausch : x jetzt transvers
715
+ getauscht = 1; // den Tausch merken
716
+ M = M+N; N = M-N; M = M-N; // M, N auch vertauschen
717
+ }
718
+ if (defined(HNDebugOn)) {
719
+ if (getauscht) {"x<->y were exchanged; polynomial is now ",f;}
720
+ else {"x , y were not exchanged";}
721
+ "M resp. N are now",M,N;
722
+ }
723
+ } // end(if Abbruch==0)
724
+
725
+ ideal a(0);
726
+ while (Abbruch==0) {
727
+
728
+ //================= Beginn der Schleife (eigentliche Entwicklung) ============
729
+
730
+ //------------------- ist das Newtonpolygon eine gerade Linie? ---------------
731
+ if (testreducible(f,N,M)) {
732
+ dbprint(printlevel+1," The given polynomial is not irreducible");
733
+ kill guenstig;
734
+ setring altring;
735
+ return(return_error); // Abbruch der Prozedur!
736
+ }
737
+ R = M%N;
738
+ Q = M div N;
739
+
740
+ //-------------------- Fall Rest der Division R = 0 : ------------------------
741
+ if (R == 0) {
742
+ c = koeff(f,0,N);
743
+ if (c == 0) {"Something has gone wrong! I didn't get N correctly!"; exit;}
744
+ e = gcd(M,N);
745
+ //----------------- Test, ob leitf = c*(y^N - delta*x^(m/e))^e ist -----------
746
+ if (p==0) {
747
+ delt = koeff(f,M div e,N - N div e) / (-1*e*c);
748
+ if (defined(HNDebugOn)) {"quasihomogeneous leading form:",
749
+ leit(f,N,M)," = ",c,"* (y -",delt,"* x^"+string(M div e)+")^",e," ?";}
750
+ if (leit(f,N,M) != c*(y^(N div e) - delt*x^(M div e))^e) {
751
+ dbprint(printlevel+1," The given polynomial is reducible !");
752
+ Abbruch=1; Ausgabe=1; }
753
+ }
754
+ else { // p!=0
755
+ if (e%p != 0) {
756
+ delt = koeff(f,M div e,N - N div e) / (-1*e*c);
757
+ if (defined(HNDebugOn)) {"quasihomogeneous leading form:",
758
+ leit(f,N,M)," = ",c,"* (y -",delt,"* x^"+string(M div e)+")^",e," ?";}
759
+ if (leit(f,N,M) != c*(y^(N div e) - delt*x^(M div e))^e) {
760
+ dbprint(printlevel+1," The given polynomial is reducible !");
761
+ Abbruch=1; Ausgabe=1; }
762
+ }
763
+
764
+ else { // e%p == 0
765
+ eps = e;
766
+ for (l = 0; eps%p == 0; l=l+1) { eps=eps div p;}
767
+ if (defined(HNDebugOn)) {e," -> ",eps,"*",p,"^",l;}
768
+ delt = koeff(f,(M div e)*p^l,(N div e)*p^l*(eps-1)) / (-1*eps*c);
769
+
770
+ if ((!hasZpCoefficient(basering)) and (delt != 0)) {
771
+ //- coeff. field is not Z/pZ => we've to correct delta by taking (p^l)th root-
772
+ if (delt == generat) {exponent=1;}
773
+ else {
774
+ if (delt == 1) {exponent=0;}
775
+ else {
776
+ exponent=pardeg(delt);
777
+
778
+ //-- an dieser Stelle kann ein Fehler auftreten, wenn wir eine transzendente -
779
+ //-- Erweiterung von Z/pZ haben: dann ist das hinzuadjungierte Element kein -
780
+ //-- Erzeuger der mult. Gruppe, d.h. in Z/pZ (a) gibt es i.allg. keinen -
781
+ //-- Exponenten mit z.B. a2+a = a^exp -
782
+ //----------------------------------------------------------------------------
783
+ }}
784
+ delt = generat^(extgcd(n_elements-1,p^l)[3]*exponent);
785
+ }
786
+
787
+ if (defined(HNDebugOn)) {"quasihomogeneous leading form:",
788
+ leit(f,N,M)," = ",c,"* (y^"+string(N div e),"-",delt,"* x^"
789
+ +string(M div e)+")^",e," ?";}
790
+ if (leit(f,N,M) != c*(y^(N div e) - delt*x^(M div e))^e) {
791
+ dbprint(printlevel+1," The given polynomial is reducible !");
792
+ Abbruch=1; Ausgabe=1; }
793
+ }
794
+ }
795
+ if (Abbruch == 0) {
796
+ f = T1_Transform(f,delt,M div e);
797
+ dbprint(printlevel-voice+2,"a("+string(zeile)+","+string(Q)+") = "
798
+ +string(delt));
799
+ a(zeile)[Q]=delt;
800
+ if (defined(HNDebugOn)) {"transformed polynomial: ",f;}}
801
+
802
+ nm=getnm(f); N=nm[1]; M=nm[2]; // Neuberechnung des Newtonpolygons
803
+ }
804
+ //--------------------------- Fall R > 0 : -----------------------------------
805
+ else {
806
+ dbprint(printlevel-voice+2, "h("+string(zeile)+ ") ="+string(Q));
807
+ hqs[zeile+1]=Q; // denn zeile beginnt mit dem Wert 0
808
+ a(zeile)[Q+1]=x; // Markierung des Zeilenendes der HNE
809
+ maxspalte=maxspalte*((Q+1) < maxspalte) + (Q+1)*((Q+1) >= maxspalte);
810
+ // Anpassung der Sp.zahl der HNE-Matrix
811
+ f = T_Transform(f,Q,N);
812
+ if (defined(HNDebugOn)) {"transformed polynomial: ",f;}
813
+ zeile=zeile+1;
814
+ //------------ Bereitstellung von Speicherplatz fuer eine neue Zeile: --------
815
+ ideal a(zeile);
816
+ M=N;N=R;
817
+ }
818
+
819
+ //--------------- schneidet das Newtonpolygon beide Achsen? ------------------
820
+ if (M==-1) {
821
+ dbprint(printlevel-voice+2,"The HNE is finite!");
822
+ a(zeile)[Q+1]=x; // Markiere das Ende der Zeile
823
+ hqs[zeile+1]=Q;
824
+ maxspalte=maxspalte*((Q+1) < maxspalte) + (Q+1)*((Q+1) >= maxspalte);
825
+ if (N <> 1) { einzweig=0; }
826
+ f=0; // transformiertes Polynom wird nicht mehr gebraucht
827
+ Abbruch=1;
828
+ }
829
+ else {if (M<N) {"Something has gone wrong: M<N";}}
830
+ if(defined(HNDebugOn)) {"new M,N:",M,N;}
831
+
832
+ //----------------- Abbruchbedingungen fuer die Schleife: --------------------
833
+ if ((N==1) and (Abbruch!=1) and ((M > maxspalte) or (minimalHNE==1))
834
+ and (size(a(zeile))>0))
835
+ //----------------------------------------------------------------------------
836
+ // Abbruch, wenn die Matrix so voll ist, dass eine neue Spalte angefangen
837
+ // werden muesste und die letzte Zeile nicht nur Nullen enthaelt
838
+ // oder wenn die Matrix nicht voll gemacht werden soll (minimale Information)
839
+ //----------------------------------------------------------------------------
840
+ { Abbruch=1; hqs[zeile+1]=-1;
841
+ if (maxspalte < ncols(a(zeile))) { maxspalte=ncols(a(zeile));}
842
+ if ((minimalHNE==1) and (M <= maxspalte)) {
843
+ // teile param mit, dass Eintraege der letzten Zeile nur teilw. richtig sind:-
844
+ hqs[zeile+1]=-M;
845
+ //------------- markiere den Rest der Zeile als unbekannt: -------------------
846
+ for (R=M; R <= maxspalte; R++) { a(zeile)[R]=y;}
847
+ } // R wird nicht mehr gebraucht
848
+ }
849
+ //========================= Ende der Schleife ================================
850
+
851
+ }
852
+ setring altring;
853
+ if (Ausgabe == 0) {
854
+ //-------------------- Ergebnis in den alten Ring transferieren: -------------
855
+ map zurueck=guenstig,maxideal(1)[1],maxideal(1)[2];
856
+ matrix amat[zeile+1][maxspalte];
857
+ ideal uebergabe;
858
+ for (e=0; e<=zeile; e=e+1) {
859
+ uebergabe=zurueck(a(e));
860
+ if (ncols(uebergabe) > 1) {
861
+ amat[e+1,1..ncols(uebergabe)]=uebergabe;}
862
+ else {amat[e+1,1]=uebergabe[1];}
863
+ }
864
+ if (ringwechsel) {
865
+ if (nvars(altring)==2) { f=fetch(guenstig,f); }
866
+ else { f=zurueck(f); }
867
+ }
868
+ }
869
+
870
+ kill guenstig;
871
+ if ((einzweig==0) && (voice==2) && (printlevel > -1)) {
872
+ "// Note: The curve is reducible, but we were able to compute a HNE.";
873
+ "// This means the result is only one of several existing HNE's.";
874
+ }
875
+ if (Ausgabe == 0) { return(list(amat,hqs,getauscht,f,einzweig));}
876
+ if (Ausgabe == 1) { return(return_error);} // error has occurred
877
+ if (Ausgabe == 2) { return(list(matrix(ideal(0,x)),intvec(1),getauscht,
878
+ poly(0),einzweig));} // HNE is x=0 or y=0
879
+ }
880
+ example
881
+ { "EXAMPLE:"; echo = 2;
882
+ ring exring = 7,(x,y),ds;
883
+ list Hne=develop(4x98+2x49y7+x11y14+2y14);
884
+ print(Hne[1]);
885
+ // therefore the HNE is:
886
+ // z(-1)= 3*z(0)^7 + z(0)^7*z(1),
887
+ // z(0) = z(1)*z(2), (there is 1 zero in the 2nd row before x)
888
+ // z(1) = z(2)^3*z(3), (there are 3 zeroes in the 3rd row)
889
+ // z(2) = z(3)*z(4),
890
+ // z(3) = -z(4)^2 + 0*z(4)^3 +...+ 0*z(4)^8 + ?*z(4)^9 + ...
891
+ // (the missing x in the last line indicates that it is not complete.)
892
+ Hne[2];
893
+ param(Hne);
894
+ // parametrization: x(t)= -t^14+O(t^21), y(t)= -3t^98+O(t^105)
895
+ // (the term -t^109 in y may have a wrong coefficient)
896
+ displayHNE(Hne);
897
+ }
898
+
899
+
900
+ ///////////////////////////////////////////////////////////////////////////////
901
+ // procedures to extract information out of HNE //
902
+ ///////////////////////////////////////////////////////////////////////////////
903
+
904
+ proc param (list L, list #)
905
+ "USAGE: param(L [,s]); L list, s any type (optional)
906
+ ASSUME: L is the output of @code{develop(f)}, or of
907
+ @code{extdevelop(develop(f),n)}, or (one entry in) the list of HN
908
+ data created by @code{hnexpansion(f[,\"ess\"])}.
909
+ RETURN: If L are the HN data of an irreducible plane curve singularity f: a
910
+ parametrization for f in the following format: @*
911
+ - if only the list L is given, the result is an ideal of two
912
+ polynomials p[1],p[2]: if the HNE was finite then f(p[1],p[2])=0};
913
+ if not, the true parametrization will be given by two power series,
914
+ and p[1],p[2] are truncations of these series.@*
915
+ - if the optional parameter s is given, the result is a list l:
916
+ l[1]=param(L) (ideal) and l[2]=intvec with two entries indicating
917
+ the highest degree up to which the coefficients of the monomials in
918
+ l[1] are exact (entry -1 means that the corresponding parametrization
919
+ is exact).
920
+ If L collects the HN data of a reducible plane curve singularity f,
921
+ the return value is a list of parametrizations in the respective
922
+ format.
923
+ NOTE: If the basering has only 2 variables, the first variable is chosen
924
+ as indefinite. Otherwise, the 3rd variable is chosen.
925
+ SEE ALSO: develop, extdevelop
926
+ KEYWORDS: parametrization
927
+ EXAMPLE: example param; shows an example
928
+ example develop; shows another example
929
+ "
930
+ {
931
+ //-------------------------- Initialisierungen -------------------------------
932
+ int return_list;
933
+ if (size(#)>0) { return_list=1; }
934
+
935
+ if (typeof(L[1])=="list") { // output of hnexpansion (> 1 branch)
936
+ list Ergebnis;
937
+ for (int i=1; i<=size(L); i++) {
938
+ dbprint(printlevel-voice+4,"// Parametrization of branch number "
939
+ +string(i)+" computed.");
940
+ printlevel=printlevel+1;
941
+ if (return_list==1) { Ergebnis[i]=param(L[i],1); }
942
+ else { Ergebnis[i]=param(L[i]); }
943
+ printlevel=printlevel-1;
944
+ }
945
+ return(Ergebnis);
946
+ }
947
+ else {
948
+ matrix m=L[1];
949
+ intvec v=L[2];
950
+ int switch=L[3];
951
+ }
952
+ if (switch==-1) {
953
+ "An error has occurred in develop, so there is no HNE.";
954
+ return(ideal(0,0));
955
+ }
956
+ int fehler,fehlervor,untergrad,untervor,beginn,i,zeile,hilf;
957
+
958
+ if (nvars(basering) > 2) { poly z(size(v)+1)=var(3); }
959
+ else { poly z(size(v)+1)=var(1); }
960
+ poly z(size(v));
961
+ zeile=size(v);
962
+ //------------- Parametrisierung der untersten Zeile der HNE -----------------
963
+ if (v[zeile] > 0) {
964
+ fehler=0; // die Parametrisierung wird exakt werden
965
+ for (i=1; i<=v[zeile]; i++) {
966
+ z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
967
+ }
968
+ }
969
+ else {
970
+ untervor=1; // = Untergrad der vorhergehenden Zeile
971
+ if (v[zeile]==-1) {
972
+ fehler=ncols(m)+1;
973
+ for (i=1; i<=ncols(m); i++) {
974
+ z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
975
+ if ((untergrad==0) and (m[zeile,i]!=0)) {untergrad=i;}
976
+ // = Untergrad der aktuellen Zeile
977
+ }
978
+ }
979
+ else {
980
+ fehler= -v[zeile];
981
+ for (i=1; i<-v[zeile]; i++) {
982
+ z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
983
+ if ((untergrad==0) and (m[zeile,i]!=0)) {untergrad=i;}
984
+ }
985
+ }
986
+ }
987
+ //------------- Parametrisierung der restlichen Zeilen der HNE ---------------
988
+ for (zeile=size(v)-1; zeile>0; zeile--) {
989
+ poly z(zeile);
990
+ beginn=0; // Beginn der aktuellen Zeile
991
+ for (i=1; i<=v[zeile]; i++) {
992
+ z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i;
993
+ if ((beginn==0) and (m[zeile,i]!=0)) { beginn=i;}
994
+ }
995
+ z(zeile)=z(zeile) + z(zeile+1)^v[zeile] * z(zeile+2);
996
+ if (beginn==0) {
997
+ if (fehler>0) { // damit fehler=0 bleibt bei exakter Param.
998
+ fehlervor=fehler; // Fehler der letzten Zeile
999
+ fehler=fehler+untergrad*(v[zeile]-1)+untervor; // Fehler dieser Zeile
1000
+ hilf=untergrad;
1001
+ untergrad=untergrad*v[zeile]+untervor;
1002
+ untervor=hilf;} // untervor = altes untergrad
1003
+ }
1004
+ else {
1005
+ fehlervor=fehler;
1006
+ fehler=fehler+untergrad*(beginn-1);
1007
+ untervor=untergrad;
1008
+ untergrad=untergrad*beginn;
1009
+ }
1010
+ }
1011
+ //--------------------- Ausgabe der Fehlerabschaetzung -----------------------
1012
+ if (switch==0) {
1013
+ if (fehler>0) {
1014
+ if (fehlervor>0) {
1015
+ dbprint(printlevel-voice+4,""+
1016
+ "// ** Warning: result is exact up to order "+string(fehlervor-1)+
1017
+ " in "+ string(var(1))+" and "+string(fehler-1)+" in " +
1018
+ string(var(2))+" !");
1019
+ }
1020
+ else {
1021
+ dbprint(printlevel-voice+4,""+
1022
+ "// ** Warning: result is exact up to order "+ string(fehler-1)+
1023
+ " in "+string(var(2))+" !");
1024
+ }
1025
+ }
1026
+ if (return_list==0) { return(ideal(z(2),z(1))); }
1027
+ else { return(list(ideal(z(2),z(1)),intvec(fehlervor-1,fehler-1))); }
1028
+ }
1029
+ else {
1030
+ if (fehler>0) {
1031
+ if (fehlervor>0) {
1032
+ dbprint(printlevel-voice+4,""+
1033
+ "// ** Warning: result is exact up to order "+string(fehler-1)+
1034
+ " in "+ string(var(1))+" and "+string(fehlervor-1)+" in " +
1035
+ string(var(2))+" !");
1036
+ }
1037
+ else {
1038
+ dbprint(printlevel-voice+4,""+
1039
+ "// ** Warning: result is exact up to order "+ string(fehler-1)+
1040
+ " in "+string(var(1))+" !");
1041
+ }
1042
+ }
1043
+ if (return_list==0) { return(ideal(z(1),z(2))); }
1044
+ else { return(list(ideal(z(1),z(2)),intvec(fehler-1,fehlervor-1))); }
1045
+ }
1046
+ }
1047
+ example
1048
+ { "EXAMPLE:"; echo = 2;
1049
+ ring exring=0,(x,y,t),ds;
1050
+ poly f=x3+2xy2+y2;
1051
+ list Hne=develop(f);
1052
+ list hne_extended=extdevelop(Hne,10);
1053
+ // compare the HNE matrices ...
1054
+ print(Hne[1]);
1055
+ print(hne_extended[1]);
1056
+ // ... and the resulting parametrizations:
1057
+ param(Hne);
1058
+ param(hne_extended);
1059
+ param(hne_extended,0);
1060
+
1061
+ // An example with more than one branch:
1062
+ list L=hnexpansion(f*(x2+y4));
1063
+ def HNring = L[1]; setring HNring;
1064
+ param(hne);
1065
+ }
1066
+
1067
+ ///////////////////////////////////////////////////////////////////////////////
1068
+
1069
+ proc invariants
1070
+ "USAGE: invariants(INPUT); INPUT list or poly
1071
+ ASSUME: @code{INPUT} is the output of @code{develop(f)}, or of
1072
+ @code{extdevelop(develop(f),n)}, or one entry of the list of HN data
1073
+ computed by @code{hnexpansion(f[,\"ess\"])}.
1074
+ RETURN: list @code{INV} of the following format:
1075
+ @format
1076
+ INV[1]: intvec (characteristic exponents)
1077
+ INV[2]: intvec (generators of the semigroup)
1078
+ INV[3]: intvec (Puiseux pairs, 1st components)
1079
+ INV[4]: intvec (Puiseux pairs, 2nd components)
1080
+ INV[5]: int (degree of the conductor)
1081
+ INV[6]: intvec (sequence of multiplicities)
1082
+ @end format
1083
+ If @code{INPUT} contains no valid HN expansion, the empty list is
1084
+ returned.
1085
+ ASSUME: @code{INPUT} is a bivariate polynomial f, or the output of
1086
+ @code{hnexpansion(f)}, or the list of HN data computed by
1087
+ @code{hnexpansion(f [,\"ess\"])}.
1088
+ RETURN: list @code{INV}, such that @code{INV[i]} coincides with the output of
1089
+ @code{invariants(develop(f[i]))}, where f[i] is the i-th branch of
1090
+ f, and the last entry of @code{INV} contains further invariants of
1091
+ f in the format:
1092
+ @format
1093
+ INV[last][1] : intmat (contact matrix of the branches)
1094
+ INV[last][2] : intmat (intersection multiplicities of the branches)
1095
+ INV[last][3] : int (delta invariant of f)
1096
+ @end format
1097
+ NOTE: In case the Hamburger-Noether expansion of the curve f is needed
1098
+ for other purposes as well it is better to calculate this first
1099
+ with the aid of @code{hnexpansion} and use it as input instead of
1100
+ the polynomial itself.
1101
+ SEE ALSO: hnexpansion, develop, displayInvariants, multsequence, intersection
1102
+ KEYWORDS: characteristic exponents; semigroup of values; Puiseux pairs;
1103
+ conductor, degree; multiplicities, sequence of
1104
+ EXAMPLE: example invariants; shows an example
1105
+ "
1106
+ {
1107
+ //---- INPUT = poly, or HNEring, or hne of reducible curve -----------------
1108
+ if (typeof(#[1])!="matrix") {
1109
+ if (typeof(#[1])=="poly") {
1110
+ list L=hnexpansion(#[1]);
1111
+ if (typeof(L[1])=="ring") {
1112
+ def altring = basering;
1113
+ def HNring = L[1]; setring HNring;
1114
+ list Ergebnis = invariants(hne);
1115
+ setring altring;
1116
+ kill HNring;
1117
+ return(Ergebnis);
1118
+ }
1119
+ else {
1120
+ return(invariants(L));
1121
+ }
1122
+ }
1123
+ if (typeof(#[1])=="ring") {
1124
+ def altring = basering;
1125
+ def HNring = #[1]; setring HNring;
1126
+ list Ergebnis = invariants(hne);
1127
+ setring altring;
1128
+ kill HNring;
1129
+ return(Ergebnis);
1130
+ }
1131
+ if (typeof(#[1])=="list") {
1132
+ list hne=#;
1133
+ list Ergebnis;
1134
+ for (int lauf=1;lauf<=size(hne);lauf++) {
1135
+ Ergebnis[lauf]=invariants(hne[lauf]);
1136
+ }
1137
+ // Calculate the intersection matrix and the intersection multiplicities.
1138
+ intmat contact[size(hne)][size(hne)];
1139
+ intmat intersectionmatrix[size(hne)][size(hne)];
1140
+ int Lauf;
1141
+ for (lauf=1;lauf<=size(hne);lauf++) {
1142
+ for (Lauf=lauf+1;Lauf<=size(hne);Lauf++) {
1143
+ contact[lauf,Lauf]=separateHNE(hne[lauf],hne[Lauf]);
1144
+ contact[Lauf,lauf]=contact[lauf,Lauf];
1145
+ intersectionmatrix[lauf,Lauf]=intersection(hne[lauf],hne[Lauf]);
1146
+ intersectionmatrix[Lauf,lauf]=intersectionmatrix[lauf,Lauf];
1147
+ }
1148
+ }
1149
+ // Calculate the delta invariant.
1150
+ int inters;
1151
+ int del=Ergebnis[size(hne)][5] div 2;
1152
+ for(lauf=1;lauf<=size(hne)-1;lauf++) {
1153
+ del=del+Ergebnis[lauf][5] div 2;
1154
+ for(Lauf=lauf+1;Lauf<=size(hne);Lauf++) {
1155
+ inters=inters+intersectionmatrix[lauf,Lauf];
1156
+ }
1157
+ }
1158
+ del=del+inters;
1159
+ list LAST=contact,intersectionmatrix,del;
1160
+ Ergebnis[size(hne)+1]=LAST;
1161
+ return(Ergebnis);
1162
+ }
1163
+ }
1164
+ //-------------------------- Initialisierungen -------------------------------
1165
+ matrix m=#[1];
1166
+ intvec v=#[2];
1167
+ int switch=#[3];
1168
+ list ergebnis;
1169
+ if (switch==-1) {
1170
+ "An error has occurred in develop, so there is no HNE.";
1171
+ return(ergebnis);
1172
+ }
1173
+ intvec beta,s,svorl,ordnung,multseq,mpuiseux,npuiseux,halbgr;
1174
+ int genus,zeile,i,j,k,summe,conductor,ggT;
1175
+ string Ausgabe;
1176
+ int nc=ncols(m); int nr=nrows(m);
1177
+ ordnung[nr]=1;
1178
+ // alle Indizes muessen (gegenueber [Ca]) um 1 erhoeht werden,
1179
+ // weil 0..r nicht als Wertebereich erlaubt ist (aber nrows(m)==r+1)
1180
+
1181
+ //---------------- Bestimme den Untergrad der einzelnen Zeilen ---------------
1182
+ for (zeile=nr; zeile>1; zeile--) {
1183
+ if ((size(ideal(m[zeile,1..nc])) > 1) or (zeile==nr)) { // keine Nullzeile
1184
+ k=1;
1185
+ while (m[zeile,k]==0) {k++;}
1186
+ ordnung[zeile-1]=k*ordnung[zeile]; // vgl. auch Def. von untergrad in
1187
+ genus++; // proc param
1188
+ svorl[genus]=zeile;} // werden gerade in umgekehrter Reihenfolge abgelegt
1189
+ else {
1190
+ ordnung[zeile-1]=v[zeile]*ordnung[zeile]+ordnung[zeile+1];
1191
+ }}
1192
+ //----------------- charakteristische Exponenten (beta) ----------------------
1193
+ s[1]=1;
1194
+ for (k=1; k <= genus; k++) { s[k+1]=svorl[genus-k+1];} // s[2]==s(1), u.s.w.
1195
+ beta[1]=ordnung[1]; //charakt. Exponenten: Index wieder verschoben
1196
+ for (k=1; k <= genus; k++) {
1197
+ summe=0;
1198
+ for (i=1; i <= s[k]; i++) {summe=summe+v[i]*ordnung[i];}
1199
+ beta[k+1]=summe+ordnung[s[k]]+ordnung[s[k]+1]-ordnung[1];
1200
+ }
1201
+ //--------------------------- Puiseuxpaare -----------------------------------
1202
+ int produkt=1;
1203
+ for (i=1; i<=genus; i++) {
1204
+ ggT=gcd(beta[1],beta[i+1]*produkt);
1205
+ mpuiseux[i]=beta[i+1]*produkt div ggT;
1206
+ npuiseux[i]=beta[1] div ggT;
1207
+ produkt=produkt*npuiseux[i];
1208
+ }
1209
+ //---------------------- Grad des Konduktors ---------------------------------
1210
+ summe=1-ordnung[1];
1211
+ if (genus > 0) {
1212
+ for (i=2; i <= genus+1; i++) {
1213
+ summe=summe + beta[i] * (ordnung[s[i-1]] - ordnung[s[i]]);
1214
+ } // n.b.: Indizierung wieder um 1 verschoben
1215
+ }
1216
+ conductor=summe;
1217
+ //------------------- Erzeuger der Halbgruppe: -------------------------------
1218
+ halbgr=puiseux2generators(mpuiseux,npuiseux);
1219
+
1220
+ //------------------- Multiplizitaetensequenz: -------------------------------
1221
+ k=1;
1222
+ for (i=1; i<size(v); i++) {
1223
+ for (j=1; j<=v[i]; j++) {
1224
+ multseq[k]=ordnung[i];
1225
+ k++;
1226
+ }}
1227
+ multseq[k]=1;
1228
+ //--- fuelle die Multipl.seq. mit den notwendigen Einsen auf -- T.Keilen ----
1229
+ int tester=k;
1230
+ while((multseq[tester]==1) and (tester>1))
1231
+ {
1232
+ tester=tester-1;
1233
+ }
1234
+ if ((multseq[tester]!=1) and (multseq[tester]!=k-tester))
1235
+ {
1236
+ for (i=k+1; i<=tester+multseq[tester]; i++)
1237
+ {
1238
+ multseq[i]=1;
1239
+ }
1240
+ }
1241
+ //--- Ende T.Keilen --- 06.05.02
1242
+ //------------------------- Rueckgabe ----------------------------------------
1243
+ ergebnis=beta,halbgr,mpuiseux,npuiseux,conductor,multseq;
1244
+ return(ergebnis);
1245
+ }
1246
+ example
1247
+ { "EXAMPLE:"; echo = 2;
1248
+ ring exring=0,(x,y),dp;
1249
+ list Hne=develop(y4+2x3y2+x6+x5y);
1250
+ list INV=invariants(Hne);
1251
+ INV[1]; // the characteristic exponents
1252
+ INV[2]; // the generators of the semigroup of values
1253
+ INV[3],INV[4]; // the Puiseux pairs in packed form
1254
+ INV[5] div 2; // the delta-invariant
1255
+ INV[6]; // the sequence of multiplicities
1256
+ // To display the invariants more 'nicely':
1257
+ displayInvariants(Hne);
1258
+ /////////////////////////////
1259
+ INV=invariants((x2-y3)*(x3-y5));
1260
+ INV[1][1]; // the characteristic exponents of the first branch
1261
+ INV[2][6]; // the sequence of multiplicities of the second branch
1262
+ print(INV[size(INV)][1]); // the contact matrix of the branches
1263
+ print(INV[size(INV)][2]); // the intersection numbers of the branches
1264
+ INV[size(INV)][3]; // the delta invariant of the curve
1265
+ }
1266
+
1267
+ ///////////////////////////////////////////////////////////////////////////////
1268
+
1269
+ proc displayInvariants
1270
+ "USAGE: displayInvariants(INPUT); INPUT list or poly
1271
+ ASSUME: @code{INPUT} is a bivariate polynomial, or the output of
1272
+ @code{develop(f)}, resp. of @code{extdevelop(develop(f),n)}, or (one
1273
+ entry of) the list of HN data computed by
1274
+ @code{hnexpansion(f[,\"ess\"])}.
1275
+ RETURN: none
1276
+ DISPLAY: invariants of the corresponding branch, resp. of all branches,
1277
+ in a better readable form.
1278
+ NOTE: If the Hamburger-Noether expansion of the curve f is needed
1279
+ for other purposes as well it is better to calculate this first
1280
+ with the aid of @code{hnexpansion} and use it as input instead of
1281
+ the polynomial itself.
1282
+ SEE ALSO: invariants, intersection, develop, hnexpansion
1283
+ EXAMPLE: example displayInvariants; shows an example
1284
+ "
1285
+ {
1286
+ // INPUT = polynomial or ring
1287
+ if (typeof(#[1])=="poly") {
1288
+ list L=hnexpansion(#[1]);
1289
+ if (typeof(L[1])=="ring") {
1290
+ def HNring = L[1]; setring HNring;
1291
+ displayInvariants(hne);
1292
+ return();
1293
+ }
1294
+ else {
1295
+ displayInvariants(L);
1296
+ return();
1297
+ }
1298
+ }
1299
+ if (typeof(#[1])=="ring")
1300
+ {
1301
+ def HNring = #[1]; setring HNring;
1302
+ displayInvariants(hne);
1303
+ return();
1304
+ }
1305
+ // INPUT = hne of a plane curve
1306
+ int i,j,k,mul;
1307
+ string Ausgabe;
1308
+ list ergebnis;
1309
+ //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: --
1310
+ #=stripHNE(#);
1311
+ //-------------------- Ausgabe eines Zweiges ---------------------------------
1312
+ if (typeof(#[1])=="matrix") {
1313
+ ergebnis=invariants(#);
1314
+ if (size(ergebnis)!=0) {
1315
+ " characteristic exponents :",ergebnis[1];
1316
+ " generators of semigroup :",ergebnis[2];
1317
+ if (size(ergebnis[1])>1) {
1318
+ for (i=1; i<=size(ergebnis[3]); i++) {
1319
+ Ausgabe=Ausgabe+"("+string(ergebnis[3][i])+","
1320
+ +string(ergebnis[4][i])+")";
1321
+ }}
1322
+ " Puiseux pairs :",Ausgabe;
1323
+ " degree of the conductor :",ergebnis[5];
1324
+ " delta invariant :",ergebnis[5] div 2;
1325
+ " sequence of multiplicities:",ergebnis[6];
1326
+ }}
1327
+ //-------------------- Ausgabe aller Zweige ----------------------------------
1328
+ else {
1329
+ ergebnis=invariants(#);
1330
+ intmat contact=ergebnis[size(#)+1][1];
1331
+ intmat intersectionmatrix=ergebnis[size(#)+1][2];
1332
+ for (j=1; j<=size(#); j++) {
1333
+ " --- invariants of branch number",j,": ---";
1334
+ " characteristic exponents :",ergebnis[j][1];
1335
+ " generators of semigroup :",ergebnis[j][2];
1336
+ Ausgabe="";
1337
+ if (size(ergebnis[j][1])>1) {
1338
+ for (i=1; i<=size(ergebnis[j][3]); i++) {
1339
+ Ausgabe=Ausgabe+"("+string(ergebnis[j][3][i])+","
1340
+ +string(ergebnis[j][4][i])+")";
1341
+ }}
1342
+ " Puiseux pairs :",Ausgabe;
1343
+ " degree of the conductor :",ergebnis[j][5];
1344
+ " delta invariant :",ergebnis[j][5] div 2;
1345
+ " sequence of multiplicities:",ergebnis[j][6];
1346
+ "";
1347
+ }
1348
+ if (size(#)>1)
1349
+ {
1350
+ " -------------- contact numbers : -------------- ";"";
1351
+ Ausgabe="branch | ";
1352
+ for (j=size(#); j>1; j--)
1353
+ {
1354
+ if (size(string(j))==1) { Ausgabe=Ausgabe+" "+string(j)+" "; }
1355
+ else { Ausgabe=Ausgabe+string(j)+" "; }
1356
+ }
1357
+ Ausgabe;
1358
+ Ausgabe="-------+";
1359
+ for (j=2; j<size(#); j++) { Ausgabe=Ausgabe+"------"; }
1360
+ Ausgabe=Ausgabe+"-----";
1361
+ Ausgabe;
1362
+ }
1363
+ for (j=1; j<size(#); j++)
1364
+ {
1365
+ if (size(string(j))==1) { Ausgabe=" "+string(j)+" |"; }
1366
+ else { Ausgabe=" " +string(j)+" |"; }
1367
+ for (k=size(#); k>j; k--)
1368
+ {
1369
+ mul=contact[j,k];//separateHNE(#[j],#[k]);
1370
+ for (i=1; i<=5-size(string(mul)); i++) { Ausgabe=Ausgabe+" "; }
1371
+ Ausgabe=Ausgabe+string(mul);
1372
+ if (k>j+1) { Ausgabe=Ausgabe+","; }
1373
+ }
1374
+ Ausgabe;
1375
+ }
1376
+ "";
1377
+ if (size(#)>1)
1378
+ {
1379
+ " -------------- intersection multiplicities : -------------- ";"";
1380
+ Ausgabe="branch | ";
1381
+ for (j=size(#); j>1; j--)
1382
+ {
1383
+ if (size(string(j))==1) { Ausgabe=Ausgabe+" "+string(j)+" "; }
1384
+ else { Ausgabe=Ausgabe+string(j)+" "; }
1385
+ }
1386
+ Ausgabe;
1387
+ Ausgabe="-------+";
1388
+ for (j=2; j<size(#); j++) { Ausgabe=Ausgabe+"------"; }
1389
+ Ausgabe=Ausgabe+"-----";
1390
+ Ausgabe;
1391
+ }
1392
+ for (j=1; j<size(#); j++)
1393
+ {
1394
+ if (size(string(j))==1) { Ausgabe=" "+string(j)+" |"; }
1395
+ else { Ausgabe=" " +string(j)+" |"; }
1396
+ for (k=size(#); k>j; k--)
1397
+ {
1398
+ mul=intersectionmatrix[j,k];//intersection(#[j],#[k]);
1399
+ for (i=1; i<=5-size(string(mul)); i++) { Ausgabe=Ausgabe+" "; }
1400
+ Ausgabe=Ausgabe+string(mul);
1401
+ if (k>j+1) { Ausgabe=Ausgabe+","; }
1402
+ }
1403
+ Ausgabe;
1404
+ }
1405
+ "";
1406
+ " -------------- delta invariant of the curve : ",ergebnis[size(#)+1][3];
1407
+
1408
+ }
1409
+ return();
1410
+ }
1411
+ example
1412
+ { "EXAMPLE:"; echo = 2;
1413
+ ring exring=0,(x,y),dp;
1414
+ list Hne=develop(y4+2x3y2+x6+x5y);
1415
+ displayInvariants(Hne);
1416
+ }
1417
+ ///////////////////////////////////////////////////////////////////////////////
1418
+
1419
+ proc multiplicities
1420
+ "USAGE: multiplicities(L); L list
1421
+ ASSUME: L is the output of @code{develop(f)}, or of
1422
+ @code{extdevelop(develop(f),n)}, or one entry in the list @code{hne}
1423
+ in the ring created by @code{hnexpansion(f[,\"ess\"])}.
1424
+ RETURN: intvec of the different multiplicities that occur when successively
1425
+ blowing-up the curve singularity corresponding to f.
1426
+ SEE ALSO: multsequence, develop
1427
+ EXAMPLE: example multiplicities; shows an example
1428
+ "
1429
+ {
1430
+ matrix m=#[1];
1431
+ intvec v=#[2];
1432
+ int switch=#[3];
1433
+ list ergebnis;
1434
+ if (switch==-1) {
1435
+ "An error has occurred in develop, so there is no HNE.";
1436
+ return(intvec(0));
1437
+ }
1438
+ intvec ordnung;
1439
+ int zeile,k;
1440
+ int nc=ncols(m); int nr=nrows(m);
1441
+ ordnung[nr]=1;
1442
+ //---------------- Bestimme den Untergrad der einzelnen Zeilen ---------------
1443
+ for (zeile=nr; zeile>1; zeile--) {
1444
+ if ((size(ideal(m[zeile,1..nc])) > 1) or (zeile==nr)) { // keine Nullzeile
1445
+ k=1;
1446
+ while (m[zeile,k]==0) {k++;}
1447
+ ordnung[zeile-1]=k*ordnung[zeile];
1448
+ }
1449
+ else {
1450
+ ordnung[zeile-1]=v[zeile]*ordnung[zeile]+ordnung[zeile+1];
1451
+ }}
1452
+ return(ordnung);
1453
+ }
1454
+ example
1455
+ { "EXAMPLE:"; echo = 2;
1456
+ int p=printlevel; printlevel=-1;
1457
+ ring r=0,(x,y),dp;
1458
+ multiplicities(develop(x5+y7));
1459
+ // The first value is the multiplicity of the curve itself, here it's 5
1460
+ printlevel=p;
1461
+ }
1462
+ ///////////////////////////////////////////////////////////////////////////////
1463
+
1464
+ proc puiseux2generators (intvec m, intvec n)
1465
+ "USAGE: puiseux2generators(m,n); m,n intvec
1466
+ ASSUME: m, resp. n, represent the 1st, resp. 2nd, components of Puiseux pairs
1467
+ (e.g., @code{m=invariants(L)[3]}, @code{n=invariants(L)[4]}).
1468
+ RETURN: intvec of the generators of the semigroup of values.
1469
+ SEE ALSO: invariants
1470
+ EXAMPLE: example puiseux2generators; shows an example
1471
+ "
1472
+ {
1473
+ intvec beta;
1474
+ int q=1;
1475
+ //------------ glatte Kurve (eigentl. waeren m,n leer): ----------------------
1476
+ if (m==0) { return(intvec(1)); }
1477
+ //------------------- singulaere Kurve: --------------------------------------
1478
+ for (int i=1; i<=size(n); i++) { q=q*n[i]; }
1479
+ beta[1]=q; // == q_0
1480
+ m=1,m; n=1,n; // m[1] ist damit m_0 usw., genau wie beta[1]==beta_0
1481
+ for (i=2; i<=size(n); i++) {
1482
+ beta[i]=m[i]*q div n[i] - m[i-1]*q + n[i-1]*beta[i-1];
1483
+ q=q div n[i]; // == q_i
1484
+ }
1485
+ return(beta);
1486
+ }
1487
+ example
1488
+ { "EXAMPLE:"; echo = 2;
1489
+ // take (3,2),(7,2),(15,2),(31,2),(63,2),(127,2) as Puiseux pairs:
1490
+ puiseux2generators(intvec(3,7,15,31,63,127),intvec(2,2,2,2,2,2));
1491
+ }
1492
+ ///////////////////////////////////////////////////////////////////////////////
1493
+
1494
+ proc intersection (list hn1, list hn2)
1495
+ "USAGE: intersection(hne1,hne2); hne1, hne2 lists
1496
+ ASSUME: @code{hne1, hne2} represent an HN expansion of an irreducible plane
1497
+ curve singularity (that is, are the output of @code{develop(f)}, or of
1498
+ @code{extdevelop(develop(f),n)}, or one entry of the list of HN data
1499
+ computed by @code{hnexpansion(f[,\"ess\"])}).
1500
+ RETURN: int, the intersection multiplicity of the irreducible plane curve
1501
+ singularities corresponding to @code{hne1} and @code{hne2}.
1502
+ SEE ALSO: hnexpansion, displayInvariants
1503
+ KEYWORDS: intersection multiplicity
1504
+ EXAMPLE: example intersection; shows an example
1505
+ "
1506
+ {
1507
+ //------------------ 'intersect' ist schon reserviert ... --------------------
1508
+ int i,j,s,sum,schnitt,unterschied;
1509
+ matrix a1=hn1[1];
1510
+ matrix a2=hn2[1];
1511
+ intvec h1=hn1[2];
1512
+ intvec h2=hn2[2];
1513
+ intvec n1=multiplicities(hn1);
1514
+ intvec n2=multiplicities(hn2);
1515
+ if (hn1[3]!=hn2[3]) {
1516
+ //-- die jeweils erste Zeile von hn1,hn2 gehoert zu verschiedenen Parametern -
1517
+ //---------------- d.h. beide Kurven schneiden sich transversal --------------
1518
+ schnitt=n1[1]*n2[1]; // = mult(hn1)*mult(hn2)
1519
+ }
1520
+ else {
1521
+ //--------- die jeweils erste Zeile gehoert zum gleichen Parameter -----------
1522
+ unterschied=0;
1523
+ for (s=1; (h1[s]==h2[s]) && (s<size(h1)) && (s<size(h2))
1524
+ && (unterschied==0); s++) {
1525
+ for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]); i++) {;}
1526
+ if (i<=h1[s]) {
1527
+ unterschied=1;
1528
+ s--; // um s++ am Schleifenende wieder auszugleichen
1529
+ }
1530
+ }
1531
+ if (unterschied==0) {
1532
+ if ((s<size(h1)) && (s<size(h2))) {
1533
+ for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]) && (i<=h2[s]); i++) {;}
1534
+ }
1535
+ else {
1536
+ //-------------- Sonderfall: Unterschied in letzter Zeile suchen -------------
1537
+ // Beachte: Es koennen undefinierte Stellen auftreten, bei abbrechender HNE
1538
+ // muss die Ende-Markierung weg, h_[r] ist unendlich, die Matrix muss mit
1539
+ // Nullen fortgesetzt gedacht werden
1540
+ //----------------------------------------------------------------------------
1541
+ if (ncols(a1)>ncols(a2)) { j=ncols(a1); }
1542
+ else { j=ncols(a2); }
1543
+ unterschied=0;
1544
+ if ((h1[s]>0) && (s==size(h1))) {
1545
+ a1[s,h1[s]+1]=0;
1546
+ if (ncols(a1)<=ncols(a2)) { unterschied=1; }
1547
+ }
1548
+ if ((h2[s]>0) && (s==size(h2))) {
1549
+ a2[s,h2[s]+1]=0;
1550
+ if (ncols(a2)<=ncols(a1)) { unterschied=1; }
1551
+ }
1552
+ if (unterschied==1) { // mind. eine HNE war endlich
1553
+ matrix ma1[1][j]=a1[s,1..ncols(a1)]; // und bedarf der Fortsetzung
1554
+ matrix ma2[1][j]=a2[s,1..ncols(a2)]; // mit Nullen
1555
+ }
1556
+ else {
1557
+ if (ncols(a1)>ncols(a2)) { j=ncols(a2); }
1558
+ else { j=ncols(a1); }
1559
+ matrix ma1[1][j]=a1[s,1..j]; // Beschr. auf vergleichbaren
1560
+ matrix ma2[1][j]=a2[s,1..j]; // Teil (der evtl. y's enth.)
1561
+ }
1562
+ for (i=1; (ma1[1,i]==ma2[1,i]) && (i<j) && (ma1[1,i]!=var(2)); i++) {;}
1563
+ if (ma1[1,i]==ma2[1,i]) {
1564
+ "//** The two HNE's are identical!";
1565
+ "//** You have either tried to intersect a branch with itself,";
1566
+ "//** or the two branches have been developed separately.";
1567
+ "// In the latter case use 'extdevelop' to extend the HNE's until",
1568
+ "they differ.";
1569
+ return(-1);
1570
+ }
1571
+ if ((ma1[1,i]==var(2)) || (ma2[1,i]==var(2))) {
1572
+ "//** The two HNE's are (so far) identical. This is because they",
1573
+ "have been";
1574
+ "//** computed separately. I need more data; use 'extdevelop' to",
1575
+ "extend them,";
1576
+ if (ma1[1,i]==var(2)) {"//** at least the first one.";}
1577
+ else {"//** at least the second one.";}
1578
+ return(-1);
1579
+ }
1580
+ }
1581
+ }
1582
+ sum=0;
1583
+ h1[size(h1)]=ncols(a1)+42; // Ersatz fuer h1[r]=infinity
1584
+ h2[size(h2)]=ncols(a2)+42;
1585
+ for (j=1; j<s; j++) {sum=sum+h1[j]*n1[j]*n2[j];}
1586
+ if ((i<=h1[s]) && (i<=h2[s])) { schnitt=sum+i*n1[s]*n2[s]; }
1587
+ if (i==h2[s]+1) { schnitt=sum+h2[s]*n1[s]*n2[s]+n2[s+1]*n1[s]; }
1588
+ if (i==h1[s]+1) { schnitt=sum+h1[s]*n2[s]*n1[s]+n1[s+1]*n2[s]; }
1589
+ // "s:",s-1,"i:",i,"S:",sum;
1590
+ }
1591
+ return(schnitt);
1592
+ }
1593
+ example
1594
+ {
1595
+ "EXAMPLE:"; echo = 2;
1596
+ ring r=0,(x,y),dp;
1597
+ list Hne=hnexpansion((x2-y3)*(x2+y3));
1598
+ intersection(Hne[1],Hne[2]);
1599
+ }
1600
+ ///////////////////////////////////////////////////////////////////////////////
1601
+
1602
+ proc multsequence
1603
+ "USAGE: multsequence(INPUT); INPUT list or poly
1604
+ ASSUME: @code{INPUT} is the output of @code{develop(f)}, or of
1605
+ @code{extdevelop(develop(f),n)}, or one entry of the list of HN data
1606
+ computed by @code{hnexpansion(f[,\"ess\"])}.
1607
+ RETURN: intvec corresponding to the multiplicity sequence of the irreducible
1608
+ plane curve singularity described by the HN data (return value
1609
+ coincides with @code{invariants(INPUT)[6]}).
1610
+
1611
+ ASSUME: @code{INPUT} is a bivariate polynomial f, or the output of
1612
+ @code{hnexpansion(f)}, or the list of HN data computed by
1613
+ @code{hnexpansion(f [,\"ess\"])}.
1614
+ RETURN: list of two integer matrices:
1615
+ @texinfo
1616
+ @table @asis
1617
+ @item @code{multsequence(INPUT)[1][i,*]}
1618
+ contains the multiplicities of the branches at their infinitely near point
1619
+ of 0 in its (i-1) order neighbourhood (i.e., i=1: multiplicity of the
1620
+ branches themselves, i=2: multiplicity of their 1st quadratic transform,
1621
+ etc., @*
1622
+ Hence, @code{multsequence(INPUT)[1][*,j]} is the multiplicity sequence
1623
+ of branch j.
1624
+ @item @code{multsequence(INPUT)[2][i,*]}:
1625
+ contains the information which of these infinitely near points coincide.
1626
+ @end table
1627
+ @end texinfo
1628
+ NOTE: The order of the elements of the list of HN data obtained from
1629
+ @code{hnexpansion(f [,\"ess\"])} must not be changed (because otherwise
1630
+ the coincident infinitely near points couldn't be grouped together,
1631
+ see the meaning of the 2nd intmat in the example).
1632
+ Hence, it is not wise to compute the HN expansion of polynomial factors
1633
+ separately, put them into a list INPUT and call
1634
+ @code{multsequence(INPUT)}. @*
1635
+ Use @code{displayMultsequence} to produce a better readable output for
1636
+ reducible curves on the screen. @*
1637
+ In case the Hamburger-Noether expansion of the curve f is needed
1638
+ for other purposes as well it is better to calculate this first
1639
+ with the aid of @code{hnexpansion} and use it as input instead of
1640
+ the polynomial itself.
1641
+ SEE ALSO: displayMultsequence, develop, hnexpansion, separateHNE
1642
+ KEYWORDS: multiplicity sequence
1643
+ EXAMPLE: example multsequence; shows an example
1644
+ "
1645
+ {
1646
+ //---- INPUT = poly, or HNEring --------------------
1647
+ if (typeof(#[1])=="poly") {
1648
+ list L=hnexpansion(#[1]);
1649
+ if (typeof(L[1])=="ring") {
1650
+ def altring = basering;
1651
+ def HNring = L[1]; setring HNring;
1652
+ list Ergebnis = multsequence(hne);
1653
+ setring altring;
1654
+ kill HNring;
1655
+ return(Ergebnis);
1656
+ }
1657
+ else {
1658
+ return(multsequence(L));
1659
+ }
1660
+ }
1661
+ if (typeof(#[1])=="ring") {
1662
+ def altring = basering;
1663
+ def HNring = #[1]; setring HNring;
1664
+ list Ergebnis = multsequence(hne);
1665
+ setring altring;
1666
+ kill HNring;
1667
+ return(Ergebnis);
1668
+ }
1669
+ //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: --
1670
+ #=stripHNE(#);
1671
+ int k,i,j;
1672
+ //----------------- Multiplizitaetensequenz eines Zweiges --------------------
1673
+ if (typeof(#[1])=="matrix") {
1674
+ intvec v=#[2];
1675
+ list ergebnis;
1676
+ if (#[3]==-1) {
1677
+ "An error has occurred in develop, so there is no HNE.";
1678
+ return(intvec(0));
1679
+ }
1680
+ intvec multips,multseq;
1681
+ multips=multiplicities(#);
1682
+ k=1;
1683
+ for (i=1; i<size(v); i++) {
1684
+ for (j=1; j<=v[i]; j++) {
1685
+ multseq[k]=multips[i];
1686
+ k++;
1687
+ }}
1688
+ multseq[k]=1;
1689
+ //--- fuelle die Multipl.seq. mit den notwendigen Einsen auf -- T.Keilen ----
1690
+ int tester=k;
1691
+ while((multseq[tester]==1) and (tester>1))
1692
+ {
1693
+ tester=tester-1;
1694
+ }
1695
+ if((multseq[tester]!=1) and (multseq[tester]!=k-tester))
1696
+ {
1697
+ for (i=k+1; i<=tester+multseq[tester]; i++)
1698
+ {
1699
+ multseq[i]=1;
1700
+ }
1701
+ }
1702
+ //--- Ende T.Keilen --- 06.05.02
1703
+ return(multseq);
1704
+ }
1705
+ //---------------------------- mehrere Zweige --------------------------------
1706
+ else {
1707
+ list HNEs=#;
1708
+ int anzahl=size(HNEs);
1709
+ int maxlength=0;
1710
+ int bisher;
1711
+ intvec schnitt,ones;
1712
+ ones[anzahl]=0;
1713
+ ones=ones+1; // = 1,1,...,1
1714
+ for (i=1; i<anzahl; i++) {
1715
+ schnitt[i]=separateHNE(HNEs[i],HNEs[i+1]);
1716
+ j=size(multsequence(HNEs[i]));
1717
+ maxlength=maxlength*(j < maxlength) + j*(j >= maxlength);
1718
+ maxlength=maxlength*(schnitt[i]+1 < maxlength)
1719
+ + (schnitt[i]+1)*(schnitt[i]+1 >= maxlength);
1720
+ }
1721
+ j=size(multsequence(HNEs[anzahl]));
1722
+ maxlength=maxlength*(j < maxlength) + j*(j >= maxlength);
1723
+
1724
+ //-------------- Konstruktion der ersten zu berechnenden Matrix ---------------
1725
+ intmat allmults[maxlength][anzahl];
1726
+ for (i=1; i<=maxlength; i++) { allmults[i,1..anzahl]=ones[1..anzahl]; }
1727
+ for (i=1; i<=anzahl; i++) {
1728
+ ones=multsequence(HNEs[i]);
1729
+ allmults[1..size(ones),i]=ones[1..size(ones)];
1730
+ }
1731
+ //---------------------- Konstruktion der zweiten Matrix ----------------------
1732
+ intmat separate[maxlength][anzahl];
1733
+ for (i=1; i<=maxlength; i++) {
1734
+ k=1;
1735
+ bisher=0;
1736
+ if (anzahl==1) { separate[i,1]=1; }
1737
+ for (j=1; j<anzahl; j++) {
1738
+ if (schnitt[j]<i) {
1739
+ separate[i,k]=j-bisher;
1740
+ bisher=j;
1741
+ k++;
1742
+ }
1743
+ separate[i,k]=anzahl-bisher;
1744
+ }
1745
+ }
1746
+ return(list(allmults,separate));
1747
+ }
1748
+ }
1749
+ example
1750
+ {
1751
+ "EXAMPLE:"; echo = 2;
1752
+ ring r=0,(x,y),dp;
1753
+ list Hne=hnexpansion((x6-y10)*(x+y2-y3)*(x+y2+y3));
1754
+ multsequence(Hne[1])," | ",multsequence(Hne[2])," | ",
1755
+ multsequence(Hne[3])," | ",multsequence(Hne[4]);
1756
+ multsequence(Hne);
1757
+ // The meaning of the entries of the 2nd matrix is as follows:
1758
+ displayMultsequence(Hne);
1759
+ }
1760
+ ///////////////////////////////////////////////////////////////////////////////
1761
+
1762
+ proc displayMultsequence
1763
+ "USAGE: displayMultsequence(INPUT); INPUT list or poly
1764
+ ASSUME: @code{INPUT} is a bivariate polynomial, or the output of
1765
+ @code{develop(f)}, resp. of @code{extdevelop(develop(f),n)}, or (one
1766
+ entry of) the list of HN data computed by @code{hnexpansion(f[,\"ess\"])},
1767
+ or the output of @code{hnexpansion(f)}.
1768
+ RETURN: nothing
1769
+ DISPLAY: the sequence of multiplicities:
1770
+ @format
1771
+ - if @code{INPUT=develop(f)} or @code{INPUT=extdevelop(develop(f),n)} or @code{INPUT=hne[i]}:
1772
+ @code{a , b , c , ....... , 1}
1773
+ - if @code{INPUT=f} or @code{INPUT=hnexpansion(f)} or @code{INPUT=hne}:
1774
+ @code{[(a_1, .... , b_1 , .... , c_1)],}
1775
+ @code{[(a_2, ... ), ... , (... , c_2)],}
1776
+ @code{ ........................................ ,}
1777
+ @code{[(a_n),(b_n), ....., (c_n)]}
1778
+ with:
1779
+ @code{a_1 , ... , a_n} the sequence of multiplicities of the 1st branch,
1780
+ @code{[...]} the multiplicities of the j-th transform of all branches,
1781
+ @code{(...)} indicating branches meeting in an infinitely near point.
1782
+ @end format
1783
+ NOTE: The Same restrictions as in @code{multsequence} apply for the input.@*
1784
+ In case the Hamburger-Noether expansion of the curve f is needed
1785
+ for other purposes as well it is better to calculate this first
1786
+ with the aid of @code{hnexpansion} and use it as input instead of
1787
+ the polynomial itself.
1788
+ SEE ALSO: multsequence, develop, hnexpansion, separateHNE
1789
+ EXAMPLE: example displayMultsequence; shows an example
1790
+ "
1791
+ {
1792
+ //---- INPUT = poly, or HNEring --------------------
1793
+ if (typeof(#[1])=="poly") {
1794
+ list L=hnexpansion(#[1]);
1795
+ if (typeof(L[1])=="ring") {
1796
+ def HNring = L[1]; setring HNring;
1797
+ displayMultsequence(hne);
1798
+ return();
1799
+ }
1800
+ else {
1801
+ displayMultsequence(L);
1802
+ return();
1803
+ }
1804
+ }
1805
+ if (typeof(#[1])=="ring") {
1806
+ def HNring = #[1]; setring HNring;
1807
+ displayMultsequence(hne);
1808
+ return();
1809
+ }
1810
+
1811
+ //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: --
1812
+ #=stripHNE(#);
1813
+ //----------------- Multiplizitaetensequenz eines Zweiges --------------------
1814
+ if (typeof(#[1])=="matrix") {
1815
+ if (#[3]==-1) {
1816
+ "An error has occurred in develop, so there is no HNE.";
1817
+ }
1818
+ else {
1819
+ "The sequence of multiplicities is ",multsequence(#);
1820
+ }}
1821
+ //---------------------------- mehrere Zweige --------------------------------
1822
+ else {
1823
+ list multips=multsequence(#);
1824
+ int i,j,k,l;
1825
+ string output;
1826
+ for (i=1; i<=nrows(multips[1]); i++) {
1827
+ output="[";
1828
+ k=1;
1829
+ for (l=1; k<=ncols(multips[1]); l++) {
1830
+ output=output+"(";
1831
+ for (j=1; j<=multips[2][i,l]; j++) {
1832
+ output=output+string(multips[1][i,k]);
1833
+ k++;
1834
+ if (j<multips[2][i,l]) { output=output+","; }
1835
+ }
1836
+ output=output+")";
1837
+ if ((k-1) < ncols(multips[1])) { output=output+","; }
1838
+ }
1839
+ output=output+"]";
1840
+ if (i<nrows(multips[1])) { output=output+","; }
1841
+ output;
1842
+ }
1843
+ }
1844
+ }
1845
+ example
1846
+ {
1847
+ "EXAMPLE:"; echo = 2;
1848
+ ring r=0,(x,y),dp;
1849
+ // Example 1: Input = output of develop
1850
+ displayMultsequence(develop(x3-y5));
1851
+
1852
+ // Example 2: Input = bivariate polynomial
1853
+ displayMultsequence((x6-y10)*(x+y2-y3)*(x+y2+y3));
1854
+ }
1855
+
1856
+ ///////////////////////////////////////////////////////////////////////////////
1857
+
1858
+ proc separateHNE (list hn1,list hn2)
1859
+ "USAGE: separateHNE(hne1,hne2); hne1, hne2 lists
1860
+ ASSUME: hne1, hne2 are HNEs (=output of
1861
+ @code{develop(f)}, @code{extdevelop(develop(f),n)}, or
1862
+ one entry in the list @code{hne} in the ring created by
1863
+ @code{hnexpansion(f[,\"ess\"])}.
1864
+ RETURN: number of quadratic transformations needed to separate both curves
1865
+ (branches).
1866
+ SEE ALSO: develop, hnexpansion, multsequence, displayMultsequence
1867
+ EXAMPLE: example separateHNE; shows an example
1868
+ "
1869
+ {
1870
+ int i,j,s,unterschied,separated;
1871
+ matrix a1=hn1[1];
1872
+ matrix a2=hn2[1];
1873
+ intvec h1=hn1[2];
1874
+ intvec h2=hn2[2];
1875
+ if (hn1[3]!=hn2[3]) {
1876
+ //-- die jeweils erste Zeile von hn1,hn2 gehoert zu verschiedenen Parametern -
1877
+ //---------------- d.h. beide Kurven schneiden sich transversal --------------
1878
+ separated=1;
1879
+ }
1880
+ else {
1881
+ //--------- die jeweils erste Zeile gehoert zum gleichen Parameter -----------
1882
+ unterschied=0;
1883
+ for (s=1; (h1[s]==h2[s]) && (s<size(h1)) && (s<size(h2))
1884
+ && (unterschied==0); s++) {
1885
+ for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]); i++) {;}
1886
+ if (i<=h1[s]) {
1887
+ unterschied=1;
1888
+ s--; // um s++ am Schleifenende wieder auszugleichen
1889
+ }
1890
+ }
1891
+ if (unterschied==0) {
1892
+ if ((s<size(h1)) && (s<size(h2))) {
1893
+ for (i=1; (a1[s,i]==a2[s,i]) && (i<=h1[s]) && (i<=h2[s]); i++) {;}
1894
+ }
1895
+ else {
1896
+ //-------------- Sonderfall: Unterschied in letzter Zeile suchen -------------
1897
+ // Beachte: Es koennen undefinierte Stellen auftreten, bei abbrechender HNE
1898
+ // muss die Ende-Markierung weg, h_[r] ist unendlich, die Matrix muss mit
1899
+ // Nullen fortgesetzt gedacht werden
1900
+ //----------------------------------------------------------------------------
1901
+ if (ncols(a1)>ncols(a2)) { j=ncols(a1); }
1902
+ else { j=ncols(a2); }
1903
+ unterschied=0;
1904
+ if ((h1[s]>0) && (s==size(h1))) {
1905
+ a1[s,h1[s]+1]=0;
1906
+ if (ncols(a1)<=ncols(a2)) { unterschied=1; }
1907
+ }
1908
+ if ((h2[s]>0) && (s==size(h2))) {
1909
+ a2[s,h2[s]+1]=0;
1910
+ if (ncols(a2)<=ncols(a1)) { unterschied=1; }
1911
+ }
1912
+ if (unterschied==1) { // mind. eine HNE war endlich
1913
+ matrix ma1[1][j]=a1[s,1..ncols(a1)]; // und bedarf der Fortsetzung
1914
+ matrix ma2[1][j]=a2[s,1..ncols(a2)]; // mit Nullen
1915
+ }
1916
+ else {
1917
+ if (ncols(a1)>ncols(a2)) { j=ncols(a2); }
1918
+ else { j=ncols(a1); }
1919
+ matrix ma1[1][j]=a1[s,1..j]; // Beschr. auf vergleichbaren
1920
+ matrix ma2[1][j]=a2[s,1..j]; // Teil (der evtl. y's enth.)
1921
+ }
1922
+ for (i=1; (ma1[1,i]==ma2[1,i]) && (i<j) && (ma1[1,i]!=var(2)); i++) {;}
1923
+ if (ma1[1,i]==ma2[1,i]) {
1924
+ "//** The two HNE's are identical!";
1925
+ "//** You have either tried to compare a branch with itself,";
1926
+ "//** or the two branches have been developed separately.";
1927
+ "// In the latter case use 'extdevelop' to extend the HNE's until",
1928
+ "they differ.";
1929
+ return(-1);
1930
+ }
1931
+ if ((ma1[1,i]==var(2)) || (ma2[1,i]==var(2))) {
1932
+ "//** The two HNE's are (so far) identical. This is because they",
1933
+ "have been";
1934
+ "//** computed separately. I need more data; use 'extdevelop' to",
1935
+ "extend them,";
1936
+ if (ma1[1,i]==var(2)) {"//** at least the first one.";}
1937
+ else {"//** at least the second one.";}
1938
+ return(-1);
1939
+ }
1940
+ }
1941
+ }
1942
+ separated=i;
1943
+ for (j=1; j<s; j++) { separated=separated+h1[j]; }
1944
+ }
1945
+ return(separated);
1946
+ }
1947
+ example
1948
+ { "EXAMPLE:"; echo = 2;
1949
+ int p=printlevel; printlevel=-1;
1950
+ ring r=0,(x,y),dp;
1951
+ list hne1=develop(x);
1952
+ list hne2=develop(x+y);
1953
+ list hne3=develop(x+y2);
1954
+ separateHNE(hne1,hne2); // two transversal lines
1955
+ separateHNE(hne1,hne3); // one quadratic transform. gives 1st example
1956
+ printlevel=p;
1957
+ }
1958
+ ///////////////////////////////////////////////////////////////////////////////
1959
+
1960
+ proc displayHNE(list ldev,list #)
1961
+ "USAGE: displayHNE(L[,n]); L list, n int
1962
+ ASSUME: L is the output of @code{develop(f)}, or of @code{exdevelop(f,n)},
1963
+ or of @code{hnexpansion(f[,\"ess\"])}, or (one entry in) the list
1964
+ @code{hne} in the ring created by @code{hnexpansion(f[,\"ess\"])}.
1965
+ RETURN: - if only one argument is given and if the input are the HN data
1966
+ of an irreducible plane curve singularity, no return value, but
1967
+ display an ideal HNE of the following form:
1968
+ @example
1969
+ y = []*x^1+[]*x^2 +...+x^<>*z(1)
1970
+ x = []*z(1)^2+...+z(1)^<>*z(2)
1971
+ z(1) = []*z(2)^2+...+z(2)^<>*z(3)
1972
+ ....... ..........................
1973
+ z(r-1) = []*z(r)^2+[]*z(r)^3+......
1974
+ @end example
1975
+ where @code{x},@code{y} are the first 2 variables of the basering.
1976
+ The values of @code{[]} are the coefficients of the Hamburger-Noether
1977
+ matrix, the values of @code{<>} are represented by @code{x} in the
1978
+ HN matrix.@*
1979
+ - if a second argument is given and if the input are the HN data
1980
+ of an irreducible plane curve singularity, return a ring containing
1981
+ an ideal @code{HNE} as described above.@*
1982
+ - if L corresponds to the output of @code{hnexpansion(f)}
1983
+ or to the list of HN data computed by @code{hnexpansion(f[,\"ess\"])},
1984
+ @code{displayHNE(L[,n])} shows the HNE's of all branches of f in the
1985
+ format described above. The optional parameter is then ignored.
1986
+ NOTE: The 1st line of the above ideal (i.e., @code{HNE[1]}) means that
1987
+ @code{y=[]*z(0)^1+...}, the 2nd line (@code{HNE[2]}) means that
1988
+ @code{x=[]*z(1)^2+...}, so you can see which indeterminate
1989
+ corresponds to which line (it's also possible that @code{x} corresponds
1990
+ to the 1st line and @code{y} to the 2nd).
1991
+
1992
+ SEE ALSO: develop, hnexpansion
1993
+ EXAMPLE: example displayHNE; shows an example
1994
+ "
1995
+ {
1996
+ if ((typeof(ldev[1])=="list") || (typeof(ldev[1])=="none")) {
1997
+ for (int i=1; i<=size(ldev); i++) {
1998
+ "// Hamburger-Noether development of branch nr."+string(i)+":";
1999
+ displayHNE(ldev[i]);"";
2000
+ }
2001
+ return();
2002
+ }
2003
+ //--------------------- Initialisierungen und Ringwechsel --------------------
2004
+ matrix m=ldev[1];
2005
+ intvec v=ldev[2];
2006
+ int switch=ldev[3];
2007
+ if (switch==-1) {
2008
+ "An error has occurred throughout the expansion, so there is no HNE.";
2009
+ return(ideal(0));
2010
+ }
2011
+ def altring=basering;
2012
+ /////////////////////////////////////////////////////////
2013
+ // Change by T. Keilen 08.06.2002
2014
+ // ring + ring does not work if one ring is an algebraic extension
2015
+ /*
2016
+ if (parstr(basering)!="") {
2017
+ if (charstr(basering)!=string(char(basering))+","+parstr(basering)) {
2018
+ list l2;
2019
+ for (int zz = 0; zz <= size(v)-1; zz++)
2020
+ {
2021
+ l2[size(l2)+1] = "z("+string(zz)+")";
2022
+ }
2023
+ ring dazu = create_ring(ringlist(basering)[1], l2, "ls", "no_minpoly");
2024
+ }
2025
+ else { ring dazu=char(altring),z(0..size(v)-1),ls; }
2026
+ }
2027
+ else { ring dazu=char(altring),z(0..size(v)-1),ls; }
2028
+ def displayring=dazu+altring;
2029
+ */
2030
+ list l1;
2031
+ for (int zz = 0; zz <= size(v)-1; zz++)
2032
+ {
2033
+ l1[size(l1)+1] = "z("+string(zz)+")";
2034
+ }
2035
+ list l2=ringlist(basering)[2];
2036
+ l1 = l1 + l2;
2037
+ ring displayring = create_ring(ringlist(basering)[1], l1, "(ls("+string(size(v))+"),"+ordstr(basering)+")", "no_minpoly");
2038
+ // End change by T. Keilen
2039
+ //////////////////////////////////////////////////////////////
2040
+ setring displayring;
2041
+ map holematrix=altring,0; // mappt nur die Monome vom Grad Null
2042
+ matrix m=holematrix(m);
2043
+ int i,j;
2044
+
2045
+ // lossen: check the last row for finiteness (06/2004)
2046
+ int rowM=nrows(m);
2047
+ int colM=ncols(m);
2048
+ int undef_bd=v[size(v)];
2049
+ if ( undef_bd<-1 ){
2050
+ for (j=-undef_bd; j<=colM; j++) { m[rowM,j]=0; }
2051
+ }
2052
+
2053
+ //--------------------- Erzeuge Matrix n mit n[i,j]=z(j-1)^i -----------------
2054
+ matrix n[colM][rowM];
2055
+ for (j=1; j<=rowM; j++) {
2056
+ for (i=1; i<=colM; i++) { n[i,j]=z(j-1)^i; }
2057
+ }
2058
+ matrix displaymat=m*n;
2059
+ ideal HNE;
2060
+ for (i=1; i<rowM; i++) { HNE[i]=displaymat[i,i]+z(i)*z(i-1)^v[i]; }
2061
+ HNE[rowM]=displaymat[rowM,rowM];
2062
+
2063
+ // lossen: output modified (06/2004)
2064
+ if (size(#) == 0)
2065
+ {
2066
+ if (switch==0) {
2067
+ HNE=subst(HNE,z(0),var(size(v)+1));
2068
+ }
2069
+ else {
2070
+ HNE=subst(HNE,z(0),var(size(v)+2));
2071
+ }
2072
+
2073
+ for (j=1; j<=ncols(HNE); j++){
2074
+ string stHNE(j)=string(HNE[j]);
2075
+ }
2076
+ if (undef_bd<-1)
2077
+ {
2078
+ stHNE(size(v))=stHNE(size(v))+" + ..... (terms of degree >="
2079
+ +string(-undef_bd)+")";
2080
+ }
2081
+ if (undef_bd==-1)
2082
+ {
2083
+ stHNE(size(v))=stHNE(size(v))+" + ..... (terms of degree >="
2084
+ +string(colM+1)+")";
2085
+ }
2086
+
2087
+ if (switch==0) {
2088
+ stHNE(1) = " "+string(var(size(v)+2))+" = "+stHNE(1);
2089
+ }
2090
+ else {
2091
+ stHNE(1) = " "+string(var(size(v)+1))+" = "+stHNE(1);
2092
+ }
2093
+ stHNE(1);
2094
+ if (ncols(HNE)==1) {return();}
2095
+
2096
+ if (switch==0) {
2097
+ stHNE(2) = " "+string(var(size(v)+1))+" = "+stHNE(2);
2098
+ }
2099
+ else {
2100
+ stHNE(2) = " "+string(var(size(v)+2))+" = "+stHNE(2);
2101
+ }
2102
+ stHNE(2);
2103
+
2104
+ for (j=3; j<=ncols(HNE); j++){
2105
+ stHNE(j)= " "+"z(" +string(j-2)+ ") = "+stHNE(j);
2106
+ stHNE(j);
2107
+ }
2108
+ return();
2109
+ }
2110
+
2111
+ if (rowM<2) { HNE[2]=z(0); }
2112
+
2113
+ if (switch==0) {
2114
+ HNE[1] = HNE[1]-var(size(v)+2);
2115
+ HNE[2] = HNE[2]-var(size(v)+1);
2116
+ }
2117
+ else {
2118
+ HNE[1] = HNE[1]-var(size(v)+1);
2119
+ HNE[2] = HNE[2]-var(size(v)+2);
2120
+ }
2121
+ if (size(#) == 0) {
2122
+ HNE;
2123
+ return();
2124
+ }
2125
+ if (size(#) != 0) {
2126
+ HNE;
2127
+ export(HNE);
2128
+ return(displayring);
2129
+ }
2130
+ }
2131
+ example
2132
+ { "EXAMPLE:"; echo = 2;
2133
+ ring r=0,(x,y),dp;
2134
+ poly f=x3+2xy2+y2;
2135
+ list hn=develop(f);
2136
+ displayHNE(hn);
2137
+ }
2138
+ ///////////////////////////////////////////////////////////////////////////////
2139
+ // procedures for reducible curves //
2140
+ ///////////////////////////////////////////////////////////////////////////////
2141
+
2142
+ // proc newtonhoehne (poly f)
2143
+ // USAGE: newtonhoehne(f); f poly
2144
+ // ASSUME: basering = ...,(x,y),ds or ls
2145
+ // RETURN: list of intvec(x,y) of coordinates of the newtonpolygon of f
2146
+ // NOTE: This proc is only available in versions of Singular that know the
2147
+ // command system("newton",f); f poly
2148
+ // {
2149
+ // intvec nm = getnm(f);
2150
+ // if ((nm[1]>0) && (nm[2]>0)) { f=jet(f,nm[1]*nm[2],nm); }
2151
+ // list erg=system("newton",f);
2152
+ // int i; list Ausgabe;
2153
+ // for (i=1; i<=size(erg); i++) { Ausgabe[i]=leadexp(erg[i]); }
2154
+ // return(Ausgabe);
2155
+ // }
2156
+ ///////////////////////////////////////////////////////////////////////////////
2157
+
2158
+ proc newtonpoly (poly f, int #)
2159
+ "USAGE: newtonpoly(f); f poly
2160
+ ASSUME: basering has exactly two variables; @*
2161
+ f is convenient, that is, f(x,0) != 0 != f(0,y).
2162
+ RETURN: list of intvecs (= coordinates x,y of the Newton polygon of f).
2163
+ NOTE: Procedure uses @code{execute}; this can be avoided by calling
2164
+ @code{newtonpoly(f,1)} if the ordering of the basering is @code{ls}.
2165
+ KEYWORDS: Newton polygon
2166
+ EXAMPLE: example newtonpoly; shows an example
2167
+ "
2168
+ {
2169
+ if (size(#)>=1)
2170
+ {
2171
+ if (typeof(#[1])=="int")
2172
+ {
2173
+ // this is done to avoid the "execute" command for procedures in
2174
+ // hnoether.lib
2175
+ def is_ls=#[1];
2176
+ }
2177
+ }
2178
+ if (defined(is_ls)<=0)
2179
+ {
2180
+ def @Rold=basering;
2181
+ ring @RR = create_ring(ringlist(basering)[1],"("+varstr(basering)+")","ls","no_minpoly");
2182
+ poly f=imap(@Rold,f);
2183
+ }
2184
+ intvec A=(0,ord(subst(f,var(1),0)));
2185
+ intvec B=(ord(subst(f,var(2),0)),0);
2186
+ intvec C,H; list L;
2187
+ int abbruch,i;
2188
+ poly hilf;
2189
+ L[1]=A;
2190
+ f=jet(f,A[2]*B[1]-1,intvec(A[2],B[1]));
2191
+ if (defined(is_ls))
2192
+ {
2193
+ map xytausch=basering,var(2),var(1);
2194
+ }
2195
+ else
2196
+ {
2197
+ map xytausch=@RR,var(2),var(1);
2198
+ }
2199
+ for (i=2; f!=0; i++)
2200
+ {
2201
+ abbruch=0;
2202
+ while (abbruch==0)
2203
+ {
2204
+ C=leadexp(f);
2205
+ if(jet(f,A[2]*C[1]-A[1]*C[2]-1,intvec(A[2]-C[2],C[1]-A[1]))==0)
2206
+ {
2207
+ abbruch=1;
2208
+ }
2209
+ else
2210
+ {
2211
+ f=jet(f,-C[1]-1,intvec(-1,0));
2212
+ }
2213
+ }
2214
+ hilf=jet(f,A[2]*C[1]-A[1]*C[2],intvec(A[2]-C[2],C[1]-A[1]));
2215
+ H=leadexp(xytausch(hilf));
2216
+ A=H[2],H[1];
2217
+ L[i]=A;
2218
+ f=jet(f,A[2]*B[1]-1,intvec(A[2],B[1]-A[1]));
2219
+ }
2220
+ L[i]=B;
2221
+ if (defined(is_ls))
2222
+ {
2223
+ return(L);
2224
+ }
2225
+ else
2226
+ {
2227
+ setring @Rold;
2228
+ return(L);
2229
+ }
2230
+ }
2231
+ example
2232
+ {
2233
+ "EXAMPLE:"; echo = 2;
2234
+ ring r=0,(x,y),ls;
2235
+ poly f=x5+2x3y-x2y2+3xy5+y6-y7;
2236
+ newtonpoly(f);
2237
+ }
2238
+ ///////////////////////////////////////////////////////////////////////////////
2239
+
2240
+ proc is_NND (poly f, list #)
2241
+ "USAGE: is_NND(f[,mu,NP]); f poly, mu int, NP list of intvecs
2242
+ ASSUME: f is convenient, that is, f(x,0) != 0 != f(0,y);@*
2243
+ mu (optional) is Milnor number of f.@*
2244
+ NP (optional) is output of @code{newtonpoly(f)}.
2245
+ RETURN: int: 1 if f is Newton non-degenerate, 0 otherwise.
2246
+ SEE ALSO: newtonpoly
2247
+ KEYWORDS: Newton non-degenerate; Newton polygon
2248
+ EXAMPLE: example is_NND; shows examples
2249
+ "
2250
+ {
2251
+ int i;
2252
+ int i_print=printlevel-voice+2;
2253
+
2254
+ if (size(#)==0)
2255
+ {
2256
+ int mu=milnor(f);
2257
+ list NP=newtonpoly(f);
2258
+ }
2259
+ else
2260
+ {
2261
+ if (typeof(#[1])=="int")
2262
+ {
2263
+ def mu=#[1];
2264
+ def NP=#[2];
2265
+ for (i=1;i<=size(NP);i++)
2266
+ {
2267
+ if (typeof(NP[i])!="intvec")
2268
+ {
2269
+ print("third input cannot be Newton polygon ==> ignored ")
2270
+ NP=newtonpoly(f);
2271
+ i=size(NP)+1;
2272
+ }
2273
+ }
2274
+ }
2275
+ else
2276
+ {
2277
+ print("second input cannot be Milnor number ==> ignored ")
2278
+ int mu=milnor(f);
2279
+ NP=newtonpoly(f);
2280
+ }
2281
+ }
2282
+
2283
+ // computation of the Newton number:
2284
+ int s=size(NP);
2285
+ int nN=-NP[1][2]-NP[s][1]+1;
2286
+ intmat m[2][2];
2287
+ for(i=1;i<=s-1;i++)
2288
+ {
2289
+ m=NP[i+1],NP[i];
2290
+ nN=nN+det(m);
2291
+ }
2292
+
2293
+ if(mu==nN)
2294
+ { // the Newton-polygon is non-degenerate
2295
+ // REFERENCE? (tfuer mehr als 2 Variable gilt nicht, dass mu=nu impliziert,
2296
+ // dass NP nicht ausgeartet ist!, Siehe KOMMENTAR in equising.lib in esIdeal)
2297
+ return(1);
2298
+ }
2299
+ else
2300
+ {
2301
+ return(0);
2302
+ }
2303
+ }
2304
+ example
2305
+ {
2306
+ "EXAMPLE:"; echo = 2;
2307
+ ring r=0,(x,y),ls;
2308
+ poly f=x5+y3;
2309
+ is_NND(f);
2310
+ poly g=(x-y)^5+3xy5+y6-y7;
2311
+ is_NND(g);
2312
+
2313
+ // if already computed, one should give the Minor number and Newton polygon
2314
+ // as second and third input:
2315
+ int mu=milnor(g);
2316
+ list NP=newtonpoly(g);
2317
+ is_NND(g,mu,NP);
2318
+ }
2319
+
2320
+
2321
+ ///////////////////////////////////////////////////////////////////////////////
2322
+
2323
+ proc charPoly(poly f, int M, int N)
2324
+ "USAGE: charPoly(f,M,N); f bivariate poly, M,N int: length and height
2325
+ of Newton polygon of f, which has to be only one line
2326
+ RETURN: the characteristic polynomial of f
2327
+ EXAMPLE: example charPoly; shows an example
2328
+ "
2329
+ {
2330
+ poly charp;
2331
+ int Np=N div gcd(M,N);
2332
+ f=subst(f,var(1),1);
2333
+ for(charp=0; f<>0; f=f-lead(f))
2334
+ { charp=charp+leadcoef(f)*var(2)^(leadexp(f)[2] div Np);}
2335
+ return(charp);
2336
+ }
2337
+ example
2338
+ { "EXAMPLE:"; echo = 2;
2339
+ ring exring=0,(x,y),dp;
2340
+ charPoly(y4+2y3x2-yx6+x8,8,4);
2341
+ charPoly(y6+3y3x2-x4,4,6);
2342
+ }
2343
+ ///////////////////////////////////////////////////////////////////////////////
2344
+
2345
+ proc find_in_list(list L,int p)
2346
+ "USAGE: find_in_list(L,p); L: list of intvec(x,y)
2347
+ (sorted in y: L[1][2]>=L[2][2]), int p >= 0
2348
+ RETURN: int i: L[i][2]=p if existent; otherwise i with L[i][2]<p if existent;
2349
+ otherwise i = size(L)+1;
2350
+ EXAMPLE: example find_in_list; shows an example
2351
+ "
2352
+ {
2353
+ int i;
2354
+ L[size(L)+1]=intvec(0,-1); // falls p nicht in L[.][2] vorkommt
2355
+ for (i=1; L[i][2]>p; i++) {;}
2356
+ return(i);
2357
+ }
2358
+ example
2359
+ { "EXAMPLE:"; echo = 2;
2360
+ list L = intvec(0,4), intvec(1,2), intvec(2,1), intvec(4,0);
2361
+ find_in_list(L,1);
2362
+ L[find_in_list(L,2)];
2363
+ }
2364
+ ///////////////////////////////////////////////////////////////////////////////
2365
+
2366
+ proc get_last_divisor(int M, int N)
2367
+ "USAGE: get_last_divisor(M,N); int M,N
2368
+ RETURN: int Q: M=q1*N+r1, N=q2*r1+r2, ..., ri=Q*r(i+1) (Euclidean alg.)
2369
+ EXAMPLE: example get_last_divisor; shows an example
2370
+ "
2371
+ {
2372
+ int R=M%N; int Q=M div N;
2373
+ while (R!=0) {M=N; N=R; R=M%N; Q=M div N;}
2374
+ return(Q)
2375
+ }
2376
+ example
2377
+ { "EXAMPLE"; echo = 2;
2378
+ ring r=0,(x,y),dp;
2379
+ get_last_divisor(12,10);
2380
+ }
2381
+ ///////////////////////////////////////////////////////////////////////////////
2382
+ proc redleit (poly f,intvec S, intvec E)
2383
+ "USAGE: redleit(f,S,E); f poly, S,E intvec(x,y)
2384
+ S,E are two different points on a line in the Newton diagram of f
2385
+ RETURN: poly g: all monomials of f which lie on or below that line
2386
+ NOTE: The main purpose is that if the line defined by S and E is part of the
2387
+ Newton polygon, the result is the quasihomogeneous leading form of f
2388
+ w.r.t. that line.
2389
+ SEE ALSO: newtonpoly
2390
+ EXAMPLE: example redleit; shows an example
2391
+ "
2392
+ {
2393
+ if (E[1]<S[1]) { intvec H=E; E=S; S=H; } // S,E verkehrt herum eingegeben
2394
+ return(jet(f,E[1]*S[2]-E[2]*S[1],intvec(S[2]-E[2],E[1]-S[1])));
2395
+ }
2396
+ example
2397
+ { "EXAMPLE"; echo = 2;
2398
+ ring exring=0,(x,y),dp;
2399
+ redleit(y6+xy4-2x3y2+x4y+x6,intvec(3,2),intvec(4,1));
2400
+ }
2401
+ ///////////////////////////////////////////////////////////////////////////////
2402
+
2403
+
2404
+ proc extdevelop (list l, int Exaktheit)
2405
+ "USAGE: extdevelop(L,N); list L, int N
2406
+ ASSUME: L is the output of @code{develop(f)}, or of @code{extdevelop(l,n)},
2407
+ or one entry in the list @code{hne} in the ring created by
2408
+ @code{hnexpansion(f[,\"ess\"])}.
2409
+ RETURN: an extension of the Hamburger-Noether development of f as a list
2410
+ in the same format as L has (up to the last entry in the output
2411
+ of @code{develop(f)}).@*
2412
+ Type @code{help develop;}, resp. @code{help hnexpansion;} for more
2413
+ details.
2414
+ NOTE: The new HN-matrix will have at least N columns (if the HNE is not
2415
+ finite). In particular, if f is irreducible then (in most cases)
2416
+ @code{extdevelop(develop(f),N)} will produce the same result as
2417
+ @code{develop(f,N)}.@*
2418
+ If the matrix M of L has n columns then, compared with
2419
+ @code{parametrization(L)}, @code{paramametrize(extdevelop(L,N))} will increase the
2420
+ exactness by at least (N-n) more significant monomials.
2421
+ SEE ALSO: develop, hnexpansion, param
2422
+ EXAMPLE: example extdevelop; shows an example
2423
+ "
2424
+ {
2425
+ //------------ Initialisierungen und Abfangen unzulaessiger Aufrufe ----------
2426
+ matrix m=l[1];
2427
+ intvec v=l[2];
2428
+ int switch=l[3];
2429
+ if (nvars(basering) < 2) {
2430
+ " Sorry. I need two variables in the ring.";
2431
+ return(list(matrix(maxideal(1)[1]),intvec(0),-1,poly(0)));}
2432
+ if (switch==-1) {
2433
+ "An error has occurred in develop, so there is no HNE and no extension.";
2434
+ return(l);
2435
+ }
2436
+ poly f=l[4];
2437
+ if (f==0) {
2438
+ " No extension is possible";
2439
+ return(l);
2440
+ }
2441
+ int Q=v[size(v)];
2442
+ if (Q>0) {
2443
+ " The HNE was already exact";
2444
+ return(l);
2445
+ }
2446
+ else {
2447
+ if (Q==-1) { Q=ncols(m); }
2448
+ else { Q=-Q-1; }
2449
+ }
2450
+ int zeile=nrows(m);
2451
+ int spalten,i,M;
2452
+ ideal lastrow=m[zeile,1..Q];
2453
+ int ringwechsel=(varstr(basering)!="x,y") or (ordstr(basering)!="ls(2),C");
2454
+
2455
+ //------------------------- Ringwechsel, falls noetig ------------------------
2456
+ if (ringwechsel) {
2457
+ def altring = basering;
2458
+ int p = char(basering);
2459
+ //if (charstr(basering)!=string(p))
2460
+ if(hasAlgExtensionCoefficient(basering)
2461
+ or hasTransExtensionCoefficient(basering)
2462
+ or hasGFCoefficient(basering))
2463
+ {
2464
+ string tststr=charstr(basering);
2465
+ tststr=tststr[1..find(tststr,",")-1]; //-> "p^k" bzw. "p"
2466
+ //if (tststr==string(p))
2467
+ if (!hasGFCoefficient(basering))
2468
+ {
2469
+ if (npars(basering)>1) { // ring (p,a,..),...
2470
+ ring extdguenstig = create_ring(ringlist(basering)[1],"(x,y)","ls","no_minpoly");
2471
+ }
2472
+ else { // ring (p,a),...
2473
+ list rl=ringlist(basering);
2474
+ rl[1][1]=p;
2475
+ ring extdguenstig=ring(rl);
2476
+ }
2477
+ }
2478
+ else {
2479
+ ring extdguenstig = create_ring(ringlist(basering)[1],"(x,y)","ls","no_minpoly");
2480
+ }
2481
+ }
2482
+ else { // charstr(basering)== p : no parameter
2483
+ ring extdguenstig=p,(x,y),ls;
2484
+ }
2485
+ export extdguenstig;
2486
+ map hole=altring,x,y;
2487
+ //----- map kann sehr zeitaufwendig sein, daher Vermeidung, wo moeglich: -----
2488
+ if (nvars(altring)==2) { poly f=fetch(altring,f); }
2489
+ else { poly f=hole(f); }
2490
+ ideal a=hole(lastrow);
2491
+ }
2492
+ else { ideal a=lastrow; }
2493
+ list Newton=newtonpoly(f,1);
2494
+ int M1=Newton[size(Newton)-1][1]; // konstant
2495
+ number delt;
2496
+ if (Newton[size(Newton)-1][2]!=1) {
2497
+ " *** The transformed polynomial was not valid!!";}
2498
+ else {
2499
+ //--------------------- Fortsetzung der HNE ----------------------------------
2500
+ while (Q<Exaktheit) {
2501
+ M=ord(subst(f,y,0));
2502
+ Q=M-M1;
2503
+ //------ quasihomogene Leitform ist c*x^M1*y+d*x^(M1+Q) => delta=-d/c: -------
2504
+ delt=-koeff(f,M,0)/koeff(f,M1,1);
2505
+ a[Q]=delt;
2506
+ dbprint(printlevel-voice+2,"a("+string(zeile-1)+","+string(Q)+") = "+string(delt));
2507
+ if (Q<Exaktheit) {
2508
+ f=T1_Transform(f,delt,Q);
2509
+ if (defined(HNDebugOn)) { "transformed polynomial:",f; }
2510
+ if (subst(f,y,0)==0) {
2511
+ dbprint(printlevel-voice+2,"The HNE is finite!");
2512
+ a[Q+1]=x; Exaktheit=Q;
2513
+ f=0; // Speicherersparnis: f nicht mehr gebraucht
2514
+ }
2515
+ }
2516
+ }
2517
+ }
2518
+ //------- Wechsel in alten Ring, Zusammensetzung alte HNE + Erweiterung ------
2519
+ if (ringwechsel) {
2520
+ setring altring;
2521
+ map zurueck=extdguenstig,var(1),var(2);
2522
+ if (nvars(altring)==2) { f=fetch(extdguenstig,f); }
2523
+ else { f=zurueck(f); }
2524
+ lastrow=zurueck(a);
2525
+ }
2526
+ else { lastrow=a; }
2527
+ if (ncols(lastrow)>ncols(m)) { spalten=ncols(lastrow); }
2528
+ else { spalten=ncols(m); }
2529
+ matrix mneu[zeile][spalten];
2530
+ for (i=1; i<nrows(m); i++) {
2531
+ mneu[i,1..ncols(m)]=m[i,1..ncols(m)];
2532
+ }
2533
+ mneu[zeile,1..ncols(lastrow)]=lastrow;
2534
+ if (lastrow[ncols(lastrow)]!=var(1)) {
2535
+ if (ncols(lastrow)==spalten) { v[zeile]=-1; } // keine undefinierten Stellen
2536
+ else {
2537
+ v[zeile]=-Q-1;
2538
+ for (i=ncols(lastrow)+1; i<=spalten; i++) {
2539
+ mneu[zeile,i]=var(2); // fuelle nicht def. Stellen der Matrix auf
2540
+ }}}
2541
+ else { v[zeile]=Q; } // HNE war exakt
2542
+ if (ringwechsel)
2543
+ {
2544
+ kill extdguenstig;
2545
+ }
2546
+
2547
+ return(list(mneu,v,switch,f));
2548
+ }
2549
+ example
2550
+ {
2551
+ "EXAMPLE:"; echo = 2;
2552
+ ring exring=0,(x,y),dp;
2553
+ list Hne=hnexpansion(x14-3y2x11-y3x10-y2x9+3y4x8+y5x7+3y4x6+x5*(-y6+y5)
2554
+ -3y6x3-y7x2+y8);
2555
+ displayHNE(Hne); // HNE of 1st,3rd branch is finite
2556
+ print(extdevelop(Hne[1],5)[1]);
2557
+ list ehne=extdevelop(Hne[2],5);
2558
+ displayHNE(ehne);
2559
+ param(Hne[2]);
2560
+ param(ehne);
2561
+
2562
+ }
2563
+ ///////////////////////////////////////////////////////////////////////////////
2564
+
2565
+ proc stripHNE (list l)
2566
+ "USAGE: stripHNE(L); L list
2567
+ ASSUME: L is the output of @code{develop(f)}, or of
2568
+ @code{extdevelop(develop(f),n)}, or (one entry of) the list
2569
+ @code{hne} in the ring created by @code{hnexpansion(f[,\"ess\"])}.
2570
+ RETURN: list in the same format as L, but all polynomials L[4], resp.
2571
+ L[i][4], are set to zero.
2572
+ NOTE: The purpose of this procedure is to remove huge amounts of data
2573
+ no longer needed. It is useful, if one or more of the polynomials
2574
+ in L consume much memory. It is still possible to compute invariants,
2575
+ parametrizations etc. with the stripped HNE(s), but it is not possible
2576
+ to use @code{extdevelop} with them.
2577
+ SEE ALSO: develop, hnexpansion, extdevelop
2578
+ EXAMPLE: example stripHNE; shows an example
2579
+ "
2580
+ {
2581
+ list h;
2582
+ if (typeof(l[1])=="matrix") { l[4]=poly(0); }
2583
+ else {
2584
+ for (int i=1; i<=size(l); i++) {
2585
+ h=l[i];
2586
+ h[4]=poly(0);
2587
+ l[i]=h;
2588
+ }
2589
+ }
2590
+ return(l);
2591
+ }
2592
+ example
2593
+ {
2594
+ "EXAMPLE:"; echo = 2;
2595
+ ring r=0,(x,y),dp;
2596
+ list Hne=develop(x2+y3+y4);
2597
+ Hne;
2598
+ stripHNE(Hne);
2599
+ }
2600
+ ///////////////////////////////////////////////////////////////////////////////
2601
+ static proc extractHNEs(list HNEs, int transvers)
2602
+ "USAGE: extractHNEs(HNEs,transvers); list HNEs (output from HN),
2603
+ int transvers: 1 if x,y were exchanged, 0 else
2604
+ RETURN: list of Hamburger-Noether-Extensions in the form of hne in hnexpansion
2605
+ NOTE: This procedure is only for internal purpose; examples don't make sense
2606
+ "
2607
+ {
2608
+ int i,maxspalte,hspalte,hnezaehler;
2609
+ list HNEaktu,Ergebnis;
2610
+ for (hnezaehler=1; hnezaehler<=size(HNEs); hnezaehler++) {
2611
+ maxspalte=0;
2612
+ HNEaktu=HNEs[hnezaehler];
2613
+ if (defined(HNDebugOn)) {"To process:";HNEaktu;}
2614
+ if (size(HNEaktu)!=size(HNEaktu[1])+2) {
2615
+ "The ideals and the hqs in HNEs[",hnezaehler,"] don't match!!";
2616
+ HNEs[hnezaehler];
2617
+ }
2618
+ //------------ ermittle maximale Anzahl benoetigter Spalten: ----------------
2619
+ for (i=2; i<size(HNEaktu); i++) {
2620
+ hspalte=ncols(HNEaktu[i]);
2621
+ maxspalte=maxspalte*(hspalte < maxspalte)+hspalte*(hspalte >= maxspalte);
2622
+ }
2623
+ //------------- schreibe Ausgabe fuer hnezaehler-ten Zweig: ------------------
2624
+ matrix ma[size(HNEaktu)-2][maxspalte];
2625
+ for (i=1; i<=(size(HNEaktu)-2); i++) {
2626
+ if (ncols(HNEaktu[i+1]) > 1) {
2627
+ ma[i,1..ncols(HNEaktu[i+1])]=HNEaktu[i+1]; }
2628
+ else { ma[i,1]=HNEaktu[i+1][1];}
2629
+ }
2630
+ Ergebnis[hnezaehler]=list(ma,HNEaktu[1],transvers,HNEaktu[size(HNEaktu)]);
2631
+ kill ma;
2632
+ }
2633
+ return(Ergebnis);
2634
+ }
2635
+ ///////////////////////////////////////////////////////////////////////////////
2636
+
2637
+ proc factorfirst(poly f, int M, int N)
2638
+ "USAGE : factorfirst(f,M,N); f poly, M,N int
2639
+ RETURN: number d such that f=const*(y^(N/e) - d*x^(M/e))^e, where e=gcd(M,N),
2640
+ 0 if such a d does not exist
2641
+ EXAMPLE: example factorfirst; shows an example
2642
+ "
2643
+ {
2644
+ number c = koeff(f,0,N);
2645
+ number delt;
2646
+ int eps,l;
2647
+ int p=char(basering);
2648
+
2649
+ if (c == 0) {"Something has gone wrong! I didn't get N correctly!"; exit;}
2650
+ int e = gcd(M,N);
2651
+
2652
+ if (p==0) { delt = koeff(f,M div e,N - N div e) / (-1*e*c); }
2653
+ else {
2654
+ if (e%p != 0) { delt = koeff(f,M div e,N - N div e) / (-1*e*c); }
2655
+ else {
2656
+ eps = e;
2657
+ for (l = 0; eps%p == 0; l=l+1) { eps=eps div p;}
2658
+ if (defined(HNDebugOn)) {e," -> ",eps,"*",p,"^",l;}
2659
+ delt = koeff(f,(M div e)*p^l,(N div e)*p^l*(eps-1)) / (-1*eps*c);
2660
+
2661
+ if ((!hasZpCoefficient(basering)) and (delt != 0)) {
2662
+ //------ coefficient field is not Z/pZ => (p^l)th root is not identity -------
2663
+ delt=0;
2664
+ if (defined(HNDebugOn)) {
2665
+ "trivial factorization not implemented for",
2666
+ "parameters---I've to use 'factorize'";
2667
+ }
2668
+ }
2669
+ }
2670
+ }
2671
+ if (defined(HNDebugOn)) {"quasihomogeneous leading form:",f," = ",c,
2672
+ "* (y^"+string(N div e),"-",delt,"* x^"+string(M div e)+")^",e," ?";}
2673
+ if (f != c*(var(2)^(N div e) - delt*var(1)^(M div e))^e) {return(0);}
2674
+ else {return(delt);}
2675
+ }
2676
+ example
2677
+ { "EXAMPLE:"; echo = 2;
2678
+ ring exring=7,(x,y),dp;
2679
+ factorfirst(2*(y3-3x4)^5,20,15);
2680
+ factorfirst(x14+y7,14,7);
2681
+ factorfirst(x14+x8y3+y7,14,7);
2682
+ }
2683
+
2684
+ ///////////////////////////////////////////////////////////////////////////
2685
+
2686
+ proc hnexpansion(poly f,list #)
2687
+ "USAGE: hnexpansion(f[,\"ess\"]); f poly
2688
+ ASSUME: f is a bivariate polynomial (in the first 2 ring variables)
2689
+ RETURN: list @code{L}, containing Hamburger-Noether data of @code{f}:
2690
+ If the computation of the HNE required no field extension, @code{L}
2691
+ is a list of lists @code{L[i]} (corresponding to the output of
2692
+ @code{develop}, applied to a branch of @code{f}, but the last entry
2693
+ being omitted):
2694
+ @texinfo
2695
+ @table @asis
2696
+ @item @code{L[i][1]}; matrix:
2697
+ Each row contains the coefficients of the corresponding line of the
2698
+ Hamburger-Noether expansion (HNE) for the i-th branch. The end of
2699
+ the line is marked in the matrix by the first ring variable
2700
+ (usually x).
2701
+ @item @code{L[i][2]}; intvec:
2702
+ indicating the length of lines of the HNE
2703
+ @item @code{L[i][3]}; int:
2704
+ 0 if the 1st ring variable was transversal (with respect to the
2705
+ i-th branch), @*
2706
+ 1 if the variables were changed at the beginning of the
2707
+ computation, @*
2708
+ -1 if an error has occurred.
2709
+ @item @code{L[i][4]}; poly:
2710
+ the transformed equation of the i-th branch to make it possible
2711
+ to extend the Hamburger-Noether data a posteriori without having
2712
+ to do all the previous calculation once again (0 if not needed).
2713
+ @end table
2714
+ @end texinfo
2715
+ If the computation of the HNE required a field extension, the first
2716
+ entry @code{L[1]} of the list is a ring, in which a list @code{hne}
2717
+ of lists (the HN data, as above) and a polynomial @code{f} (image of
2718
+ @code{f} over the new field) are stored.
2719
+ @*
2720
+ If called with an additional input parameter, @code{hnexpansion}
2721
+ computes only one representative for each class of conjugate
2722
+ branches (over the ground field active when calling the procedure).
2723
+ In this case, the returned list @code{L} always has only two
2724
+ entries: @code{L[1]} is either a list of lists (the HN data) or a
2725
+ ring (as above), and @code{L[2]} is an integer vector (the number
2726
+ of branches in the respective conjugacy classes).
2727
+
2728
+ NOTE: If f is known to be irreducible as a power series, @code{develop(f)}
2729
+ could be chosen instead to avoid a change of basering during the
2730
+ computations. @*
2731
+ Increasing @code{printlevel} leads to more and more comments. @*
2732
+ Having defined a variable @code{HNDebugOn} leads to a maximum
2733
+ number of comments.
2734
+
2735
+ SEE ALSO: develop, extdevelop, param, displayHNE
2736
+ EXAMPLE: example hnexpansion; shows an example
2737
+ "
2738
+ {
2739
+ int essential;
2740
+ if (size(#)==1) { essential=1; }
2741
+ int field_ext;
2742
+ def altring=basering;
2743
+
2744
+ //--------- Falls Ring (p^k,a),...: Wechsel in (p,a),... + minpoly -----------
2745
+ if ( hasGFCoefficient(basering) )
2746
+ {
2747
+ string strmip=string(minpoly);
2748
+ string strf=string(f);
2749
+ ring tempr = create_ring("("+string(char(basering))+","+parstr(basering)+")", "("+varstr(basering)+")", "dp");
2750
+ execute("minpoly="+strmip+";");
2751
+ execute("poly f="+strf+";");
2752
+ field_ext=1;
2753
+ def L=pre_HN(f,essential);
2754
+ if (size(L)==0) { return(list()); }
2755
+ def HNEring=L[1];
2756
+ setring HNEring;
2757
+ if ((typeof(hne[1])=="ideal")) { return(list()); }
2758
+ if ((voice==2) && (printlevel > -1)) {
2759
+ "// Attention: The parameter",par(1),"may have changed its meaning!";
2760
+ "// It needs no longer be a generator of the cyclic group of unities!";
2761
+ }
2762
+ dbprint(printlevel-voice+2,
2763
+ "// result: "+string(size(hne))+" branch(es) successfully computed.");
2764
+ }
2765
+ else {
2766
+ def L=pre_HN(f,essential);
2767
+ if (size(L)==0) { return(list()); }
2768
+ if (L[2]==1) { field_ext=1; }
2769
+ intvec hne_conj=L[3];
2770
+ def HNEring=L[1];
2771
+ setring HNEring;
2772
+ if ((typeof(hne[1])=="ideal")) { return(list()); }
2773
+ dbprint(printlevel-voice+2,
2774
+ "// result: "+string(size(hne))+" branch(es) successfully computed.");
2775
+ }
2776
+
2777
+ // ----- Lossen 10/02 : the branches have to be resorted to be able to
2778
+ // ----- display the multsequence in a nice way
2779
+ if (size(hne)>2)
2780
+ {
2781
+ int i,j,k,m;
2782
+ list dummy;
2783
+ int nbsave;
2784
+ int no_br = size(hne);
2785
+ intmat nbhd[no_br][no_br];
2786
+ for (i=1;i<no_br;i++)
2787
+ {
2788
+ for (j=i+1;j<=no_br;j++)
2789
+ {
2790
+ nbhd[i,j]=separateHNE(hne[i],hne[j]);
2791
+ k=i+1;
2792
+ while ( (nbhd[i,k] >= nbhd[i,j]) and (k<j) )
2793
+ {
2794
+ k++;
2795
+ }
2796
+ if (k<j) // branches have to be resorted
2797
+ {
2798
+ dummy=hne[j];
2799
+ nbsave=nbhd[i,j];
2800
+ for (m=k; m<j; m++)
2801
+ {
2802
+ hne[m+1]=hne[m];
2803
+ nbhd[i,m+1]=nbhd[i,m];
2804
+ }
2805
+ hne[k]=dummy;
2806
+ nbhd[i,k]=nbsave;
2807
+ }
2808
+ }
2809
+ }
2810
+ }
2811
+ // -----
2812
+
2813
+ if (field_ext==1) {
2814
+ dbprint(printlevel-voice+3,"
2815
+ // 'hnexpansion' created a list of one ring.
2816
+ // To see the ring and the data stored in the ring, type (if you assigned
2817
+ // the name L to the list):
2818
+ show(L);
2819
+ // To display the computed HN expansion, type
2820
+ def HNring = L[1]; setring HNring; displayHNE(hne); ");
2821
+ if (essential==1) {
2822
+ dbprint(printlevel-voice+3,""+
2823
+ "// As second entry of the returned list L, you obtain an integer vector,
2824
+ // indicating the number of conjugates for each of the computed branches.");
2825
+ return(list(HNEring,hne_conj));
2826
+ }
2827
+ return(list(HNEring));
2828
+ }
2829
+ else { // no change of basering necessary --> map data to original ring
2830
+ setring altring;
2831
+ if ((npars(altring)==1) and (minpoly!=0)) {
2832
+ ring HNhelpring=char(altring),(a,x,y),ls;
2833
+ list hne=imap(HNEring,hne);
2834
+ setring altring;
2835
+ map mmm=HNhelpring,par(1),var(1),var(2);
2836
+ list hne=mmm(hne);
2837
+ kill mmm,HNhelpring;
2838
+ }
2839
+ else {
2840
+ list hne=fetch(HNEring,hne);
2841
+ }
2842
+ kill HNEring;
2843
+ if (essential==1) {
2844
+ dbprint(printlevel-voice+3,""+
2845
+ "// No change of ring necessary, return value is a list:
2846
+ // first entry = list : HN expansion of essential branches.
2847
+ // second entry = intvec: numbers of conjugated branches ");
2848
+ return(list(hne,hne_conj));
2849
+ }
2850
+ else {
2851
+ dbprint(printlevel-voice+3,""+
2852
+ "// No change of ring necessary, return value is HN expansion.");
2853
+ return(hne);
2854
+ }
2855
+ }
2856
+ }
2857
+ example
2858
+ {
2859
+ "EXAMPLE:"; echo = 2;
2860
+ ring r=0,(x,y),dp;
2861
+ // First, an example which requires no field extension:
2862
+ list Hne=hnexpansion(x4-y6);
2863
+ size(Hne); // number of branches
2864
+ displayHNE(Hne); // HN expansion of branches
2865
+ param(Hne[1]); // parametrization of 1st branch
2866
+ param(Hne[2]); // parametrization of 2nd branch
2867
+
2868
+ // An example which requires a field extension:
2869
+ list L=hnexpansion((x4-y6)*(y2+x4));
2870
+ def R=L[1]; setring R; displayHNE(hne);
2871
+ basering;
2872
+ setring r; kill R;
2873
+
2874
+ // Computing only one representative per conjugacy class:
2875
+ L=hnexpansion((x4-y6)*(y2+x4),"ess");
2876
+ def R=L[1]; setring R; displayHNE(hne);
2877
+ L[2]; // number of branches in respective conjugacy classes
2878
+ }
2879
+
2880
+ ///////////////////////////////////////////////////////////////////////////////
2881
+
2882
+ static proc pre_HN (poly f, int essential)
2883
+ "NOTE: This procedure is only for internal use, it is called via
2884
+ hnexpansion
2885
+ RETURN: list: first entry = HNEring (containing list hne, poly f)
2886
+ second entry = 0 if no change of base ring necessary
2887
+ 1 if change of base ring necessary
2888
+ third entry = numbers of conjugates ( if essential = 1 )
2889
+ if some error has occurred, the empty list is returned
2890
+ "
2891
+ {
2892
+ def altring = basering;
2893
+ int p = char(basering);
2894
+ int field_ext;
2895
+ intvec hne_conj;
2896
+
2897
+ //-------------------- Tests auf Zulaessigkeit von basering ------------------
2898
+ if (hasNumericCoeffs(basering)) {
2899
+ " Singular cannot factorize over 'real' as ground field";
2900
+ return(list());
2901
+ }
2902
+ if (nvars(basering)<2) {
2903
+ " A univariate polynomial ring makes no sense !";
2904
+ return(list());
2905
+ }
2906
+ if (nvars(basering)>2) {
2907
+ dbprint(printlevel-voice+2,
2908
+ " Warning: all variables except the first two will be ignored!");
2909
+ }
2910
+ if (hasGFCoefficient(basering))
2911
+ {
2912
+ ERROR(" ring of type (p^k,a) not implemented");
2913
+ //----------------------------------------------------------------------------
2914
+ // weder primitives Element noch factorize noch map "char p^k" -> "char -p"
2915
+ // [(p^k,a)->(p,a) ground field] noch fetch
2916
+ //----------------------------------------------------------------------------
2917
+ }
2918
+ //----------------- Definition eines neuen Ringes: HNEring -------------------
2919
+ string namex=varstr(1); string namey=varstr(2);
2920
+ if ((npars(altring)==0)&&(!hasNumericCoeffs(basering))) { // kein Parameter, nicht 'real'
2921
+ ring HNEring = char(altring),(x,y),ls;
2922
+ map m=altring,x,y;
2923
+ poly f=m(f);
2924
+ export f;
2925
+ kill m;
2926
+ }
2927
+ else {
2928
+ string mipl=string(minpoly);
2929
+ if (mipl=="0") {
2930
+ "// ** WARNING: Algebraic extension of given ground field not possible!";
2931
+ "// ** We try to develop this polynomial, but if the need for a field";
2932
+ "// ** extension occurs during the calculation, we cannot proceed with";
2933
+ "// ** the corresponding branches.";
2934
+ ring HNEring = create_ring(ringlist(basering)[1],"(x,y)","ls","no_minpoly");
2935
+ }
2936
+ else {
2937
+ string pa=parstr(altring);
2938
+ list rl=ringlist(altring);
2939
+ rl=rl[1]; rl[1]=p;
2940
+ ring HNhelpring=ring(rl);
2941
+ execute("poly mipo="+mipl+";"); // Minimalpolynom in Polynom umgewandelt
2942
+ ring HNEring=(p,a),(x,y),ls;
2943
+ map getminpol=HNhelpring,a;
2944
+ mipl=string(getminpol(mipo)); // String umgewandelt mit 'a' als Param.
2945
+ execute("minpoly="+mipl+";"); // "minpoly=poly is not supported"
2946
+ kill HNhelpring; if(defined(getminpol)){ kill getminpol; }
2947
+ }
2948
+ if (nvars(altring)==2) {
2949
+ poly f=fetch(altring,f);
2950
+ export f;
2951
+ }
2952
+ else {
2953
+ if (defined(pa)) { // Parameter hatte vorher anderen Namen als 'a'
2954
+ list rl=ringlist(altring);
2955
+ rl=rl[1]; rl[1]=p;
2956
+ rl[2]=rl[2]+list("x","y");
2957
+ rl[3]=list(list("ls",1:3),list("C",0));
2958
+ ring HNhelpring=ring(rl);
2959
+ poly f=imap(altring,f);
2960
+ setring HNEring;
2961
+ map m=HNhelpring,a,x,y;
2962
+ poly f=m(f);
2963
+ kill HNhelpring;
2964
+ }
2965
+ else {
2966
+ map m=altring,x,y;
2967
+ poly f=m(f);
2968
+ }
2969
+ export f;
2970
+ kill m;
2971
+ }
2972
+ }
2973
+
2974
+ if (defined(HNDebugOn))
2975
+ {"received polynomial: ",f,", with x =",namex,", y =",namey;}
2976
+
2977
+ //----------------------- Variablendefinitionen ------------------------------
2978
+ int Abbruch,i,NullHNEx,NullHNEy;
2979
+ string str;
2980
+ list Newton,hne;
2981
+
2982
+ // --- changed for SINGULAR 3: ---
2983
+ hne=ideal(0);
2984
+ export hne;
2985
+
2986
+ //====================== Tests auf Zulaessigkeit des Polynoms ================
2987
+
2988
+ //-------------------------- Test, ob Einheit oder Null ----------------------
2989
+ if (subst(subst(f,x,0),y,0)!=0) {
2990
+ dbprint(printlevel+1,
2991
+ "The given polynomial is a unit in the power series ring!");
2992
+ setring altring; kill HNEring;
2993
+ return(list()); // there are no HNEs
2994
+ }
2995
+ if (f==0) {
2996
+ dbprint(printlevel+1,"The given polynomial is zero!");
2997
+ setring altring; kill HNEring;
2998
+ return(list()); // there are no HNEs
2999
+ }
3000
+
3001
+ //----------------------- Test auf Quadratfreiheit --------------------------
3002
+
3003
+ if (hasQQCoefficient(basering)) {
3004
+
3005
+ //-------- Fall basering==0,... : Wechsel in Ring mit char >0 ----------------
3006
+ // weil squarefree eine Standardbasis berechnen muss (verwendet Syzygien)
3007
+ // -- wenn f in diesem Ring quadratfrei ist, dann erst recht im Ring HNEring
3008
+ //----------------------------------------------------------------------------
3009
+ int testerg=(polytest(f)==0);
3010
+ ring zweitring = 32003,(x,y),dp;
3011
+
3012
+ map polyhinueber=HNEring,x,y; // fetch geht nicht
3013
+ poly f=polyhinueber(f);
3014
+ poly test_sqr=squarefree(f);
3015
+ if (test_sqr != f) {
3016
+ if (printlevel>0) {
3017
+ "Most probably the given polynomial is not squarefree. But the test was";
3018
+ "made in characteristic 32003 and not 0 to improve speed. You can";
3019
+ "(r) redo the test in char 0 (but this may take some time)";
3020
+ "(c) continue the development, if you're sure that the polynomial IS",
3021
+ "squarefree";
3022
+ if (testerg==1) {
3023
+ "(s) continue the development with a squarefree factor (*)";}
3024
+ "(q) or just quit the algorithm (default action)";
3025
+ "";"Please enter the letter of your choice:";
3026
+ str=read("")[1]; // reads one character
3027
+ }
3028
+ else { str="r"; } // printlevel <= 0: non-interactive behaviour
3029
+ setring HNEring;
3030
+ map polyhinueber=zweitring,x,y;
3031
+ if (str=="r") {
3032
+ poly test_sqr=squarefree(f);
3033
+ if (test_sqr != f) {
3034
+ if (printlevel>0) { "The given polynomial is in fact not squarefree."; }
3035
+ else { "The given polynomial is not squarefree!"; }
3036
+ "I'll continue with the radical.";
3037
+ f=test_sqr;
3038
+ }
3039
+ else {
3040
+ dbprint(printlevel,
3041
+ "everything is ok -- the polynomial is squarefree in characteristic 0");
3042
+ }
3043
+ }
3044
+ else {
3045
+ if ((str=="s") and (testerg==1)) {
3046
+ "(*)attention: it could be that the factor is only one in char 32003!";
3047
+ f=polyhinueber(test_sqr);
3048
+ }
3049
+ else {
3050
+ if (str<>"c") {
3051
+ setring altring;
3052
+ kill HNEring;kill zweitring;
3053
+ return(list());}
3054
+ else { "if the algorithm doesn't terminate, you were wrong...";}
3055
+ }}
3056
+ kill zweitring;
3057
+ if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
3058
+ }
3059
+ else {
3060
+ setring HNEring;
3061
+ kill zweitring;
3062
+ }
3063
+ }
3064
+ //------------------ Fall Char > 0 oder Ring hat Parameter -------------------
3065
+ else {
3066
+ poly test_sqr=squarefree(f);
3067
+ if (test_sqr != f) {
3068
+ if (printlevel>0) {
3069
+ if (test_sqr == 1) {
3070
+ "The given polynomial is of the form g^"+string(p)+",";
3071
+ "therefore not squarefree. You can:";
3072
+ " (q) quit the algorithm (recommended) or";
3073
+ " (f) continue with the full radical (using a factorization of the";
3074
+ " pure power part; this could take much time)";
3075
+ "";"Please enter the letter of your choice:";
3076
+ str=read("")[1];
3077
+ if (str<>"f") { str="q"; }
3078
+ }
3079
+ else {
3080
+ "The given polynomial is not squarefree.";
3081
+ if (p != 0)
3082
+ {
3083
+ " You can:";
3084
+ " (c) continue with a squarefree divisor (but factors of the form g^"
3085
+ +string(p);
3086
+ " are lost; this is recommended, takes no extra time)";
3087
+ " (f) continue with the full radical (using a factorization of the";
3088
+ " pure power part; this could take some time)";
3089
+ " (q) quit the algorithm";
3090
+ "";"Please enter the letter of your choice:";
3091
+ str=read("")[1];
3092
+ if ((str<>"f") && (str<>"q")) { str="c"; }
3093
+ }
3094
+ else { "I'll continue with the radical."; str="c"; }
3095
+ } // endelse (test_sqr!=1)
3096
+ }
3097
+ else {
3098
+ "//** Error: The given polynomial is not squarefree!";
3099
+ "//** Since the global variable 'printlevel' has the value",printlevel,
3100
+ "we stop here.";
3101
+ "// Either call me again with a squarefree polynomial f or assign";
3102
+ " printlevel=1;";
3103
+ "// before calling me with a non-squarefree f.";
3104
+ "// If printlevel > 0, I present some possibilities how to proceed.";
3105
+ str="q";
3106
+ }
3107
+ if (str=="q") {
3108
+ setring altring;kill HNEring;
3109
+ return(list());
3110
+ }
3111
+ if (str=="c") { f=test_sqr; }
3112
+ if (str=="f") { f=allsquarefree(f,test_sqr); }
3113
+ }
3114
+ if (defined(HNDebugOn)) {"I continue with the polynomial",f; }
3115
+
3116
+ }
3117
+ //====================== Ende Test auf Quadratfreiheit =======================
3118
+ if (subst(subst(f,x,0),y,0)!=0) {
3119
+ "The polynomial is a unit in the power series ring. No HNE computed.";
3120
+ setring altring;kill HNEring;
3121
+ return(list());
3122
+ }
3123
+ //---------------------- Test, ob f teilbar durch x oder y -------------------
3124
+ if (subst(f,y,0)==0) {
3125
+ f=f/y; NullHNEy=1; } // y=0 is a solution
3126
+ if (subst(f,x,0)==0) {
3127
+ f=f/x; NullHNEx=1; } // x=0 is a solution
3128
+
3129
+ Newton=newtonpoly(f,1);
3130
+ i=1; Abbruch=0;
3131
+ //----------------------------------------------------------------------------
3132
+ // finde Eckpkt. des Newtonpolys, der den Teil abgrenzt, fuer den x transvers:
3133
+ // Annahme: Newton ist sortiert, s.d. Newton[1]=Punkt auf der y-Achse,
3134
+ // Newton[letzt]=Punkt auf der x-Achse
3135
+ //----------------------------------------------------------------------------
3136
+ while ((i<size(Newton)) and (Abbruch==0)) {
3137
+ if ((Newton[i+1][1]-Newton[i][1])>=(Newton[i][2]-Newton[i+1][2]))
3138
+ {Abbruch=1;}
3139
+ else {i=i+1;}
3140
+ }
3141
+ int grenze1=Newton[i][2];
3142
+ int grenze2=Newton[i][1];
3143
+ //----------------------------------------------------------------------------
3144
+ // Stelle Ring bereit zur Uebertragung der Daten im Fall einer Koerperer-
3145
+ // weiterung. Definiere Objekte, die spaeter uebertragen werden.
3146
+ // Binde die Listen (azeilen,...) an den Ring (um sie nicht zu ueberschreiben
3147
+ // bei Def. in einem anderen Ring).
3148
+ //----------------------------------------------------------------------------
3149
+ ring HNE_noparam = char(altring),(a,x,y),ls;
3150
+ poly f;
3151
+ list azeilen=ideal(0);
3152
+ list HNEs=ideal(0);
3153
+ list aneu=ideal(0);
3154
+ list faktoren=ideal(0);
3155
+
3156
+ ideal deltais;
3157
+ poly delt;
3158
+
3159
+ //----- hier steht die Anzahl bisher benoetigter Ringerweiterungen drin: -----
3160
+ int EXTHNEnumber=0;
3161
+
3162
+ list EXTHNEring;
3163
+ list HNE_RingDATA;
3164
+ int number_of_letztring;
3165
+ setring HNEring;
3166
+ number_of_letztring=0;
3167
+
3168
+ // ================= Die eigentliche Berechnung der HNE: =====================
3169
+
3170
+ // ------- Berechne HNE von allen Zweigen, fuer die x transversal ist: -------
3171
+ if (defined(HNDebugOn))
3172
+ {"1st step: Treat Newton polygon until height",grenze1;}
3173
+ if (grenze1>0) {
3174
+ if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
3175
+ HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring,
3176
+ number_of_letztring);
3177
+
3178
+ list hilflist=HN(HNE_RingDATA,f,grenze1,1,essential,0,hne_conj,1);
3179
+ kill HNEring, HNE_noparam;
3180
+ if (EXTHNEnumber>0) { kill EXTHNEring(1..EXTHNEnumber);}
3181
+ def HNEring = hilflist[1][1];
3182
+ def HNE_noparam = hilflist[1][2];
3183
+ EXTHNEnumber = hilflist[1][3];
3184
+ for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=hilflist[1][4][i]; }
3185
+ if (hilflist[2]==0) { setring HNEring; number_of_letztring=0; }
3186
+ else { setring EXTHNEring(hilflist[2]);}
3187
+ if (hilflist[3]==1){field_ext=1;}
3188
+ hne_conj=hilflist[5];
3189
+
3190
+ if (number_of_letztring != hilflist[2])
3191
+ { // Ringwechsel in Prozedur HN
3192
+ map hole=HNE_noparam,transfproc,x,y;
3193
+ setring HNE_noparam;
3194
+ if (not(defined(f))) {poly f;}
3195
+ f=imap(HNEring,f);
3196
+ setring EXTHNEring(EXTHNEnumber);
3197
+ if (not(defined(f))) {poly f; f=hole(f); export f;}
3198
+ else {f=hole(f);}
3199
+ }
3200
+ number_of_letztring = hilflist[2];
3201
+ kill hilflist;
3202
+ }
3203
+
3204
+ if (NullHNEy==1) {
3205
+ if ((typeof(hne[1])=="ideal")) { hne=list(); }
3206
+ hne=hne+list(list(matrix(ideal(0,x)),intvec(1),int(0),poly(0)));
3207
+ if (hne_conj==0) { hne_conj=1; }
3208
+ else { hne_conj = hne_conj, 1; }
3209
+ }
3210
+ // --------------- Berechne HNE von allen verbliebenen Zweigen: --------------
3211
+ if (defined(HNDebugOn))
3212
+ {"2nd step: Treat Newton polygon until height",grenze2;}
3213
+ if (grenze2>0) {
3214
+
3215
+ if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
3216
+
3217
+ if (essential==1) { number_of_letztring=0; }
3218
+ if (number_of_letztring==0) { setring HNEring; }
3219
+ else { setring EXTHNEring(number_of_letztring); }
3220
+ map xytausch=basering,y,x;
3221
+
3222
+ HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring,
3223
+ number_of_letztring);
3224
+ list hilflist=HN(HNE_RingDATA,xytausch(f),grenze2,1,essential,1,hne_conj,1);
3225
+ kill HNEring, HNE_noparam;
3226
+ if (EXTHNEnumber>0){ kill EXTHNEring(1..EXTHNEnumber); }
3227
+ def HNEring = hilflist[1][1];
3228
+ def HNE_noparam = hilflist[1][2];
3229
+ EXTHNEnumber = hilflist[1][3];
3230
+ for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=hilflist[1][4][i]; }
3231
+ if (hilflist[2]==0) { setring HNEring; number_of_letztring=0; }
3232
+ else { setring EXTHNEring(hilflist[2]);
3233
+ number_of_letztring=hilflist[2]; }
3234
+ if (hilflist[3]==1){field_ext=1;}
3235
+ hne_conj=hilflist[5];
3236
+ kill hilflist;
3237
+ }
3238
+ if (NullHNEx==1) {
3239
+ if ((typeof(hne[1])=="ideal")) { hne=list(); }
3240
+ hne=hne+list(list(matrix(ideal(0,x)),intvec(1),int(1),poly(0)));
3241
+ if (hne_conj==0) { hne_conj=1; }
3242
+ else { hne_conj = hne_conj, 1; }
3243
+ }
3244
+
3245
+
3246
+ // --- aufraeumen ---
3247
+ if (defined(HNEakut)){
3248
+ kill HNEakut,faktoren,deltais,transformiert,teiler,leitf;
3249
+ }
3250
+ if (defined(hilflist)) {kill hilflist;}
3251
+ if (defined(erg)) {kill erg;}
3252
+ if (defined(delt)) {kill delt;}
3253
+ if (defined(azeilen)) { kill azeilen;}
3254
+ if (defined(aneu)) { kill aneu;}
3255
+ if (defined(transfproc)) { kill transfproc;}
3256
+ if (defined(transf)) { kill transf;}
3257
+ if (not(defined(f))) { poly f = imap(HNEring,f); export f; }
3258
+
3259
+ return(list(basering,field_ext,hne_conj));
3260
+ }
3261
+
3262
+ //////////////////////////////////////////////////////////////////////////////
3263
+ proc essdevelop (poly f)
3264
+ "USAGE: essdevelop(f); f poly
3265
+ NOTE: command is obsolete, use hnexpansion(f,\"ess\") instead.
3266
+ SEE ALSO: hnexpansion, develop, extdevelop, param
3267
+ "
3268
+ {
3269
+ printlevel=printlevel+1;
3270
+ list Ergebnis=hnexpansion(f,1);
3271
+ printlevel=printlevel-1;
3272
+ return(Ergebnis);
3273
+ }
3274
+
3275
+ ///////////////////////////////////////////////////////////////////////////////
3276
+ static proc HN (list HNE_RingDATA,poly fneu,int grenze,def Aufruf_Ebene,
3277
+ def essential,def getauscht,intvec hne_conj,int conj_factor)
3278
+ "NOTE: This procedure is only for internal use, it is called via pre_HN
3279
+ RETURN: list: first entry = list of HNErings,
3280
+ second entry = number of new base ring (0 for HNEring,
3281
+ -1 for HNE_noparam,
3282
+ i for EXTHNEring(i))
3283
+ third entry = 0 if no field extension necessary
3284
+ 1 if field extension necessary
3285
+ forth entry = HNEs (only if no change of basering)
3286
+ "
3287
+ {
3288
+ //---------- Variablendefinitionen fuer den unverzweigten Teil: --------------
3289
+ if (defined(HNDebugOn)) {"procedure HN",Aufruf_Ebene;}
3290
+ int Abbruch,ende,i,j,k,e,M,N,Q,R,zeiger,zeile,zeilevorher,dd,ii;
3291
+ intvec hqs;
3292
+ int field_ext;
3293
+ int ring_changed, hneshift;
3294
+ intvec conjugates,conj2,conj1;
3295
+
3296
+ list EXTHNEring;
3297
+ def HNEring = HNE_RingDATA[1];
3298
+ def HNE_noparam = HNE_RingDATA[2];
3299
+ int EXTHNEnumber = HNE_RingDATA[3];
3300
+ for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=HNE_RingDATA[4][i]; }
3301
+ int number_of_letztring = HNE_RingDATA[5];
3302
+ if (defined(basering))
3303
+ {
3304
+ if (number_of_letztring==0) { kill HNEring; def HNEring=basering; }
3305
+ else { kill EXTHNEring(number_of_letztring);
3306
+ def EXTHNEring(number_of_letztring)=basering; }
3307
+ }
3308
+ else
3309
+ {
3310
+ if ( number_of_letztring==0) { setring HNEring; }
3311
+ else { setring EXTHNEring(number_of_letztring); }
3312
+ }
3313
+ if (not(defined(hne))) {list hne;}
3314
+ poly fvorher;
3315
+ list erg=ideal(0); list HNEs=ideal(0); // um die Listen an den Ring zu binden
3316
+
3317
+ //-------------------- Bedeutung von Abbruch: --------------------------------
3318
+ //------- 0:keine Verzweigung | 1:Verzweigung,nicht fertig | 2:fertig --------
3319
+ //
3320
+ // Struktur von HNEs : Liste von Listen L (fuer jeden Zweig) der Form
3321
+ // L[1]=intvec (hqs), L[2],L[3],... ideal (die Zeilen (0,1,...) der HNE)
3322
+ // L[letztes]=poly (transformiertes f)
3323
+ //----------------------------------------------------------------------------
3324
+ list Newton;
3325
+ number delt;
3326
+ int p = char(basering); // Ringcharakteristik
3327
+ list azeilen=ideal(0);
3328
+
3329
+ ideal hilfid; intvec hilfvec;
3330
+
3331
+ // ======================= der unverzweigte Teil: ============================
3332
+ while (Abbruch==0) {
3333
+ Newton=newtonpoly(fneu,1);
3334
+ zeiger=find_in_list(Newton,grenze);
3335
+ if (Newton[zeiger][2] != grenze)
3336
+ {"Didn't find an edge in the Newton polygon!";}
3337
+ if (zeiger==size(Newton)-1) {
3338
+ if (defined(HNDebugOn)) {"only one relevant side in Newton polygon";}
3339
+ M=Newton[zeiger+1][1]-Newton[zeiger][1];
3340
+ N=Newton[zeiger][2]-Newton[zeiger+1][2];
3341
+ R = M%N;
3342
+ Q = M div N;
3343
+
3344
+ //-------- 1. Versuch: ist der quasihomogene Leitterm reine Potenz ? ------
3345
+ // (dann geht alles wie im irreduziblen Fall)
3346
+ //-------------------------------------------------------------------------
3347
+ e = gcd(M,N);
3348
+ delt=factorfirst(redleit(fneu,Newton[zeiger],Newton[zeiger+1])
3349
+ /x^Newton[zeiger][1],M,N);
3350
+ if (delt==0) {
3351
+ if (defined(HNDebugOn)) {" The given polynomial is reducible !";}
3352
+ Abbruch=1;
3353
+ }
3354
+ if (Abbruch==0) {
3355
+ //----------- fneu,zeile retten fuer den Spezialfall (###): -------------
3356
+ fvorher=fneu;zeilevorher=zeile;
3357
+ if (R==0) {
3358
+ //-------- transformiere fneu mit T1, wenn kein Abbruch nachher: ------
3359
+ if (N>1) { fneu = T1_Transform(fneu,delt,M div e); }
3360
+ else { ende=1; }
3361
+ if (defined(HNDebugOn)) {"a("+string(zeile)+","+string(Q)+") =",delt;}
3362
+ azeilen[zeile+1][Q]=delt;
3363
+ }
3364
+ else {
3365
+ //------------- R > 0 : transformiere fneu mit T2 ---------------------
3366
+ erg=T2_Transform(fneu,delt,M,N,referencepoly(Newton));
3367
+ fneu=erg[1];delt=erg[2];
3368
+ //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: ----
3369
+ while (R!=0) {
3370
+ if (defined(HNDebugOn)) { "h("+string(zeile)+") =",Q; }
3371
+ hqs[zeile+1]=Q; // denn zeile beginnt mit dem Wert 0
3372
+ //--------------- markiere das Zeilenende der HNE: -------------------
3373
+ azeilen[zeile+1][Q+1]=x;
3374
+ zeile=zeile+1;
3375
+ //-------- Bereitstellung von Speicherplatz fuer eine neue Zeile: ----
3376
+ azeilen[zeile+1]=ideal(0);
3377
+ M=N; N=R; R=M%N; Q=M div N;
3378
+ }
3379
+ if (defined(HNDebugOn)) {"a("+string(zeile)+","+string(Q)+") =",delt;}
3380
+ azeilen[zeile+1][Q]=delt;
3381
+ }
3382
+ if (defined(HNDebugOn)) {"transformed polynomial: ",fneu;}
3383
+ grenze=e;
3384
+ //----------------------- teste Abbruchbedingungen: ---------------------
3385
+ if (subst(fneu,y,0)==0) { // <==> y|fneu
3386
+ dbprint(printlevel-voice+3,"finite HNE of one branch found");
3387
+ // voice abzufragen macht bei rekursiven procs keinen Sinn
3388
+ azeilen[zeile+1][Q+1]=x;
3389
+ //----- Q wird nur in hqs eingetragen, wenn der Spezialfall nicht
3390
+ // eintritt (siehe unten) -----
3391
+ Abbruch=2;
3392
+ if (grenze>1) {
3393
+ if (jet(fneu,1,intvec(0,1))==0) {
3394
+ //- jet(...)=alle Monome von fneu, die nicht durch y2 teilbar sind -
3395
+ "THE TEST FOR SQUAREFREENESS WAS BAD!!";
3396
+ " The polynomial was NOT squarefree!!!";}
3397
+ else {
3398
+ //----------------------- Spezialfall (###): -----------------------
3399
+ // Wir haben das Problem, dass die HNE eines Zweiges hier abbricht,
3400
+ // aber ein anderer Zweig bis hierher genau die gleiche HNE hat, die
3401
+ // noch weiter geht
3402
+ // Loesung: mache Transform. rueckgaengig und behandle fneu im
3403
+ // Verzweigungsteil
3404
+ //------------------------------------------------------------------
3405
+ Abbruch=1;
3406
+ fneu=fvorher;zeile=zeilevorher;grenze=Newton[zeiger][2];
3407
+ }}
3408
+ else {fneu=0;} // fneu nicht mehr gebraucht - spare Speicher
3409
+ if (Abbruch==2) { hqs[zeile+1]=Q; }
3410
+ } // Spezialfall nicht eingetreten
3411
+ else {
3412
+ if (ende==1) {
3413
+ dbprint(printlevel-voice+2,"HNE of one branch found");
3414
+ Abbruch=2; hqs[zeile+1]=-Q-1;}
3415
+ }
3416
+ } // end(if Abbruch==0)
3417
+ } // end(if zeiger...)
3418
+ else { Abbruch=1;}
3419
+ } // end(while Abbruch==0)
3420
+
3421
+ // ===================== der Teil bei Verzweigung: ===========================
3422
+ if (Abbruch==1) {
3423
+ //---------- Variablendefinitionen fuer den verzweigten Teil: ---------------
3424
+ poly leitf,teiler,transformiert;
3425
+ list aneu=ideal(0);
3426
+ list faktoren;
3427
+ ideal deltais;
3428
+ list HNEakut=ideal(0);
3429
+ intvec eis;
3430
+ int zaehler,hnezaehler,zl,zl1,M1,N1,R1,Q1,needext;
3431
+ int numberofRingchanges,lastRingnumber,ringischanged,flag;
3432
+ string letztringname;
3433
+
3434
+ zeiger=find_in_list(Newton,grenze);
3435
+ if (defined(HNDebugOn)) {
3436
+ "Branching part reached---Newton polygon :",Newton;
3437
+ "relevant part until height",grenze,", from",Newton[zeiger],"on";
3438
+ }
3439
+ azeilen=list(hqs)+azeilen; // hat jetzt Struktur von HNEs: hqs in der 1.Zeile
3440
+
3441
+ //======= Schleife fuer jede zu betrachtende Seite des Newtonpolygons: ======
3442
+ for(i=zeiger; i<size(Newton); i++) {
3443
+ if ((essential==1) and (EXTHNEnumber>number_of_letztring)) {
3444
+ // ----- setze ring zurueck fuer neue Kante -----
3445
+ // ---- (damit konjugierte Zweige erkennbar) -----
3446
+ hneshift=hneshift+hnezaehler;
3447
+ hnezaehler=0;
3448
+ ring_changed=0;
3449
+ def SaveRing = EXTHNEring(EXTHNEnumber);
3450
+ setring SaveRing;
3451
+ if (not(defined(HNEs))) { // HN wurde zum 2.Mal von pre_HN aufgerufen
3452
+ list HNEs=ideal(0);
3453
+ }
3454
+ for (k=number_of_letztring+1; k<=EXTHNEnumber; k++) { kill EXTHNEring(k);}
3455
+ EXTHNEnumber=number_of_letztring;
3456
+ if (EXTHNEnumber==0) { setring HNEring; }
3457
+ else { setring EXTHNEring(EXTHNEnumber); }
3458
+ if (not(defined(HNEs))) { list HNEs; }
3459
+ HNEs=ideal(0);
3460
+ deltais=0;
3461
+ delt=0;
3462
+ if (defined(zerlege)) { kill zerlege; }
3463
+ }
3464
+
3465
+ if (defined(HNDebugOn)) { "we consider side",Newton[i],Newton[i+1]; }
3466
+ M=Newton[i+1][1]-Newton[i][1];
3467
+ N=Newton[i][2]-Newton[i+1][2];
3468
+ R = M%N;
3469
+ Q = M div N;
3470
+ e=gcd(M,N);
3471
+ needext=1;
3472
+ letztringname=nameof(basering);
3473
+ lastRingnumber=EXTHNEnumber;
3474
+ faktoren=list(ideal(charPoly(redleit(fneu,Newton[i],Newton[i+1])
3475
+ /(x^Newton[i][1]*y^Newton[i+1][2]),M,N) ),
3476
+ intvec(1)); // = (zu faktoriserendes Poly, 1)
3477
+ conjugates=conj_factor;
3478
+
3479
+ //-- wechsle so lange in Ringerweiterungen, bis Leitform vollstaendig
3480
+ // in Linearfaktoren zerfaellt -----
3481
+ for (numberofRingchanges=1; needext==1; numberofRingchanges++) {
3482
+ leitf=redleit(fneu,Newton[i],Newton[i+1])/
3483
+ (x^Newton[i][1]*y^Newton[i+1][2]);
3484
+ delt=factorfirst(leitf,M,N);
3485
+ needext=0;
3486
+ if (delt==0) {
3487
+ //---------- Sonderbehandlung: faktorisiere einige Polynome ueber Q(a): --
3488
+ if ((char(basering)==0) and (hasAlgExtensionCoefficient(basering)) and (essential==0)) {
3489
+ // ====================================================
3490
+ // neu CL: 06.10.05
3491
+ poly CHPOLY=charPoly(leitf,M,N);
3492
+ poly tstpoly;
3493
+ if (defined(faktoren)!=0) {
3494
+ // Test, damit kein Fehler eingebaut (vermutlich nicht notwendig)
3495
+ tstpoly = faktoren[1][1]^faktoren[2][1];
3496
+ for (k=2; k<=size(faktoren[1]); k++) {
3497
+ tstpoly = tstpoly * faktoren[1][k]^faktoren[2][k];
3498
+ }
3499
+ tstpoly = CHPOLY-tstpoly*(CHPOLY/tstpoly);
3500
+ kill CHPOLY;
3501
+ }
3502
+ if ((numberofRingchanges>1) and (defined(faktoren)!=0) and (tstpoly==0)) {
3503
+ def L_help=factorlist(faktoren,conjugates);
3504
+ faktoren=L_help[1];
3505
+ conjugates=L_help[2];
3506
+ kill L_help;
3507
+ }
3508
+ else {
3509
+ faktoren=factorize(charPoly(leitf,M,N));
3510
+ conjugates=conj_factor;
3511
+ for (k=2;k<=size(faktoren[2]);k++) {conjugates=conjugates,conj_factor;}
3512
+ }
3513
+ kill tstpoly;
3514
+ // Ende neu (vorher nur else Fall)
3515
+ // ====================================================
3516
+ }
3517
+ else {
3518
+ //------------------ faktorisiere das charakt. Polynom: ----------------
3519
+ if ((numberofRingchanges==1) or (essential==0)) {
3520
+ def L_help=factorlist(faktoren,conjugates);
3521
+ faktoren=L_help[1];
3522
+ conjugates=L_help[2];
3523
+ kill L_help;
3524
+ }
3525
+ else { // eliminiere alle konjugierten Nullstellen bis auf eine:
3526
+ ideal hilf_id;
3527
+ for (zaehler=1; zaehler<=size(faktoren[1]); zaehler++) {
3528
+ hilf_id=factorize(faktoren[1][zaehler],1);
3529
+ if (size(hilf_id)>1) {
3530
+ poly fac=hilf_id[1];
3531
+ dd=deg(fac);
3532
+ // Zur Sicherheit:
3533
+ if (deg(fac)==0) { fac=hilf_id[2]; }
3534
+ for (k=2;k<=size(hilf_id);k++) {
3535
+ dd=dd+deg(hilf_id[k]);
3536
+ if (deg(hilf_id[k])<deg(fac)) { fac=hilf_id[k]; }
3537
+ }
3538
+ faktoren[1][zaehler]=fac;
3539
+ kill fac;
3540
+ if (conjugates[zaehler]==conj_factor) {
3541
+ // number of conjugates not yet determined for this factor
3542
+ conjugates[zaehler]=conjugates[zaehler]*dd;
3543
+ }
3544
+ }
3545
+ else {
3546
+ faktoren[1][zaehler]=hilf_id[1];
3547
+ }
3548
+ }
3549
+ }
3550
+ }
3551
+
3552
+ zaehler=1; eis=0;
3553
+ for (j=1; j<=size(faktoren[2]); j++) {
3554
+ teiler=faktoren[1][j];
3555
+ if (teiler/y != 0) { // sonst war's eine Konstante --> wegwerfen!
3556
+ if (defined(HNDebugOn)) {"factor of leading form found:",teiler;}
3557
+ if (teiler/y2 == 0) { // --> Faktor hat die Form cy+d
3558
+ deltais[zaehler]=-subst(teiler,y,0)/koeff(teiler,0,1); //=-d/c
3559
+ eis[zaehler]=faktoren[2][j];
3560
+ conj2[zaehler]=conjugates[j];
3561
+ zaehler++;
3562
+ }
3563
+ else {
3564
+ dbprint(printlevel-voice+2,
3565
+ " Change of basering (field extension) necessary!");
3566
+ if (defined(HNDebugOn)) { teiler,"is not yet properly factorized!"; }
3567
+ if (needext==0) { poly zerlege=teiler; }
3568
+ needext=1;
3569
+ field_ext=1;
3570
+ }
3571
+ }
3572
+ } // end(for j)
3573
+ }
3574
+ else { deltais=ideal(delt); eis=e; conj2=conj_factor; }
3575
+ if (defined(HNDebugOn)) {"roots of char. poly:";deltais;
3576
+ "with multiplicities:",eis;}
3577
+ if (needext==1) {
3578
+ //--------------------- fuehre den Ringwechsel aus: ---------------------
3579
+ ringischanged=1;
3580
+ if ((size(parstr(basering))>0) && string(minpoly)=="0") {
3581
+ " ** We've had bad luck! The HNE cannot be calculated completely!";
3582
+ // HNE in transzendenter Erweiterung fehlgeschlagen
3583
+ kill zerlege;
3584
+ ringischanged=0; break; // weiter mit gefundenen Faktoren
3585
+ }
3586
+ if (parstr(basering)=="") {
3587
+ EXTHNEnumber++;
3588
+ def EXTHNEring(EXTHNEnumber) = splitring(zerlege);
3589
+ setring EXTHNEring(EXTHNEnumber);
3590
+
3591
+ poly transf=0;
3592
+ poly transfproc=0;
3593
+ ring_changed=1;
3594
+ export transfproc;
3595
+ }
3596
+ else {
3597
+ if (numberofRingchanges>1) { // ein Ringwechsel hat nicht gereicht
3598
+ def helpring = splitring(zerlege,list(transf,transfproc,faktoren));
3599
+ kill EXTHNEring(EXTHNEnumber);
3600
+ def EXTHNEring(EXTHNEnumber)=helpring;
3601
+ setring EXTHNEring(EXTHNEnumber);
3602
+ kill helpring;
3603
+
3604
+ poly transf=erg[1];
3605
+ poly transfproc=erg[2];
3606
+ ring_changed=1;
3607
+ list faktoren=erg[3];
3608
+ export transfproc;
3609
+ kill erg;
3610
+ }
3611
+ else {
3612
+ if (ring_changed==1) { // in dieser proc geschah schon Ringwechsel
3613
+ EXTHNEnumber++;
3614
+ def EXTHNEring(EXTHNEnumber) = splitring(zerlege,list(a,transfproc));
3615
+ setring EXTHNEring(EXTHNEnumber);
3616
+ poly transf=erg[1];
3617
+ poly transfproc=erg[2];
3618
+ export transfproc;
3619
+ kill erg;
3620
+ }
3621
+ else { // parameter war vorher da
3622
+ EXTHNEnumber++;
3623
+ def EXTHNEring(EXTHNEnumber) = splitring(zerlege,a);
3624
+ setring EXTHNEring(EXTHNEnumber);
3625
+ poly transf=erg[1];
3626
+ poly transfproc=transf;
3627
+ ring_changed=1;
3628
+ export transfproc;
3629
+ kill erg;
3630
+ }}
3631
+ }
3632
+ //-----------------------------------------------------------------------
3633
+ // transf enthaelt jetzt den alten Parameter des Ringes, der aktiv war
3634
+ // vor Beginn der Schleife (evtl. also ueber mehrere Ringwechsel
3635
+ // weitergereicht),
3636
+ // transfproc enthaelt den alten Parameter des Ringes, der aktiv war zu
3637
+ // Beginn der Prozedur, und der an die aufrufende Prozedur zurueckgegeben
3638
+ // werden muss
3639
+ // transf ist Null, falls der alte Ring keinen Parameter hatte,
3640
+ // das gleiche gilt fuer transfproc
3641
+ //-----------------------------------------------------------------------
3642
+
3643
+ //---- Neudef. von Variablen, Uebertragung bisher errechneter Daten: ----
3644
+ poly leitf,teiler,transformiert;
3645
+ list aneu=ideal(0);
3646
+ ideal deltais;
3647
+ number delt;
3648
+ setring HNE_noparam;
3649
+ if (defined(letztring)) { kill letztring; }
3650
+ if (EXTHNEnumber>1) { def letztring=EXTHNEring(EXTHNEnumber-1); }
3651
+ else { def letztring=HNEring; }
3652
+ if (not defined(fneu)) {poly fneu;}
3653
+ fneu=imap(letztring,fneu);
3654
+ if (not defined(f)) {poly f;}
3655
+ f=imap(letztring,f);
3656
+ if (not defined(hne)) {list hne;}
3657
+ hne=imap(letztring,hne);
3658
+
3659
+ if (not defined(faktoren)) {list faktoren; }
3660
+ faktoren=imap(letztring,faktoren);
3661
+
3662
+ if (not(defined(azeilen))){list azeilen,HNEs;}
3663
+ azeilen=imap(letztring,azeilen);
3664
+ HNEs=imap(letztring,HNEs);
3665
+
3666
+ setring EXTHNEring(EXTHNEnumber);
3667
+ if (not(defined(hole))) { map hole; }
3668
+ hole=HNE_noparam,transf,x,y;
3669
+ poly fneu=hole(fneu);
3670
+ if (not defined(faktoren)) {
3671
+ list faktoren;
3672
+ faktoren=hole(faktoren);
3673
+ }
3674
+ if (not(defined(f)))
3675
+ {
3676
+ poly f=hole(f);
3677
+ list hne=hole(hne);
3678
+ export f,hne;
3679
+ }
3680
+ }
3681
+ } // end (while needext==1) bzw. for (numberofRingchanges)
3682
+
3683
+ if (eis==0) { i++; continue; }
3684
+ if (ringischanged==1) {
3685
+ list erg,HNEakut; // dienen nur zum Sp. von Zwi.erg.
3686
+
3687
+ ideal hilfid;
3688
+ erg=ideal(0); HNEakut=erg;
3689
+
3690
+ hole=HNE_noparam,transf,x,y;
3691
+ setring HNE_noparam;
3692
+ if (not(defined(azeilen))){list azeilen,HNEs;}
3693
+ azeilen=imap(letztring,azeilen);
3694
+ HNEs=imap(letztring,HNEs);
3695
+
3696
+ setring EXTHNEring(EXTHNEnumber);
3697
+ list azeilen=hole(azeilen);
3698
+ list HNEs=hole(HNEs);
3699
+ kill letztring;
3700
+ ringischanged=0;
3701
+ }
3702
+
3703
+ //============ Schleife fuer jeden gefundenen Faktor der Leitform: =========
3704
+ for (j=1; j<=size(eis); j++) {
3705
+ //---- Mache Transformation T1 oder T2, trage Daten in HNEs ein,
3706
+ // falls HNE abbricht: ----
3707
+
3708
+ //------------------------ Fall R==0: -------------------------------------
3709
+ if (R==0) {
3710
+ transformiert = T1_Transform(fneu,number(deltais[j]),M div e);
3711
+ if (defined(HNDebugOn)) {
3712
+ "a("+string(zeile)+","+string(Q)+") =",deltais[j];
3713
+ "transformed polynomial: ",transformiert;
3714
+ }
3715
+ if (subst(transformiert,y,0)==0) {
3716
+ dbprint(printlevel-voice+3,"finite HNE found");
3717
+ hnezaehler++;
3718
+ //-------- trage deltais[j],x ein in letzte Zeile, fertig: -------------
3719
+ HNEakut=azeilen+list(poly(0)); // =HNEs[hnezaehler];
3720
+ hilfid=HNEakut[zeile+2]; hilfid[Q]=deltais[j]; hilfid[Q+1]=x;
3721
+ HNEakut[zeile+2]=hilfid;
3722
+ HNEakut[1][zeile+1]=Q; // aktualisiere Vektor mit den hqs
3723
+ HNEs[hnezaehler]=HNEakut;
3724
+ conj1[hneshift+hnezaehler]=conj2[j];
3725
+ if (eis[j]>1) {
3726
+ transformiert=transformiert/y;
3727
+ if (subst(transformiert,y,0)==0){"THE TEST FOR SQUAREFREENESS WAS BAD!"
3728
+ +"! The polynomial was NOT squarefree!!!";}
3729
+ else {
3730
+ //--- Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden --
3731
+ eis[j]=eis[j]-1;
3732
+ }
3733
+ }
3734
+ }
3735
+ }
3736
+ else {
3737
+ //------------------------ Fall R <> 0: ---------------------------------
3738
+ erg=T2_Transform(fneu,number(deltais[j]),M,N,referencepoly(Newton));
3739
+ transformiert=erg[1];delt=erg[2];
3740
+ if (defined(HNDebugOn)) {"transformed polynomial: ",transformiert;}
3741
+ if (subst(transformiert,y,0)==0) {
3742
+ dbprint(printlevel-voice+3,"finite HNE found");
3743
+ hnezaehler++;
3744
+ //---------------- trage endliche HNE in HNEs ein: ---------------------
3745
+ HNEakut=azeilen; // dupliziere den gemeins. Anfang der HNE's
3746
+ zl=2; // (kommt schliesslich nach HNEs[hnezaehler])
3747
+ //----------------------------------------------------------------------
3748
+ // Werte von: zeile: aktuelle Zeilennummer der HNE (gemeinsamer Teil)
3749
+ // zl : die HNE spaltet auf; zeile+zl ist der Index fuer die
3750
+ // Zeile des aktuellen Zweigs; (zeile+zl-2) ist die
3751
+ // tatsaechl. Zeilennr. (bei 0 angefangen) der HNE
3752
+ // ([1] <- intvec(hqs), [2] <- 0. Zeile usw.)
3753
+ //----------------------------------------------------------------------
3754
+
3755
+ //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: -----
3756
+ M1=M;N1=N;R1=R;Q1=M1 div N1;
3757
+ while (R1!=0) {
3758
+ if (defined(HNDebugOn)) { "h("+string(zeile+zl-2)+") =",Q1; }
3759
+ HNEakut[1][zeile+zl-1]=Q1;
3760
+ HNEakut[zeile+zl][Q1+1]=x;
3761
+ // markiere das Zeilenende der HNE
3762
+ zl=zl+1;
3763
+ //----- Bereitstellung von Speicherplatz fuer eine neue Zeile: --------
3764
+ HNEakut[zeile+zl]=ideal(0);
3765
+
3766
+ M1=N1; N1=R1; R1=M1%N1; Q1=M1 div N1;
3767
+ }
3768
+ if (defined(HNDebugOn)) {
3769
+ "a("+string(zeile+zl-2)+","+string(Q1)+") =",delt;
3770
+ }
3771
+ HNEakut[zeile+zl][Q1] =delt;
3772
+ HNEakut[zeile+zl][Q1+1]=x;
3773
+ HNEakut[1][zeile+zl-1] =Q1; // aktualisiere Vektor mit hqs
3774
+ HNEakut[zeile+zl+1]=poly(0);
3775
+ HNEs[hnezaehler]=HNEakut;
3776
+ conj1[hneshift+hnezaehler]=conj2[j];
3777
+
3778
+ //-------------------- Ende der Eintragungen in HNEs -------------------
3779
+
3780
+ if (eis[j]>1) {
3781
+ transformiert=transformiert/y;
3782
+ if (subst(transformiert,y,0)==0){"THE TEST FOR SQUAREFREENESS WAS BAD!"
3783
+ +" The polynomial was NOT squarefree!!!";}
3784
+ else {
3785
+ //--- Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden --
3786
+ eis[j]=eis[j]-1;
3787
+ }}
3788
+ } // endif (subst()==0)
3789
+ } // endelse (R<>0)
3790
+
3791
+ //========== Falls HNE nicht abbricht: Rekursiver Aufruf von HN: ==========
3792
+ //------------------- Berechne HNE von transformiert ----------------------
3793
+ if (subst(transformiert,y,0)!=0) {
3794
+ lastRingnumber=EXTHNEnumber;
3795
+
3796
+ if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
3797
+ HNE_RingDATA = list( HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring,
3798
+ lastRingnumber);
3799
+ if (defined(HNerg)) {kill HNerg;}
3800
+ list HNerg=HN(HNE_RingDATA,transformiert,eis[j],Aufruf_Ebene+1,
3801
+ essential,getauscht,hne_conj,conj2[j]);
3802
+ HNE_RingDATA = HNerg[1];
3803
+ if (conj1==0) { conj1=HNerg[5]; }
3804
+ else { conj1 = conj1,HNerg[5]; }
3805
+
3806
+ if (HNerg[3]==1) { field_ext=1; }
3807
+ if (HNerg[2]==lastRingnumber) { // kein Ringwechsel in HN aufgetreten
3808
+ if (not(defined(aneu))) { list aneu; }
3809
+ aneu = HNerg[4];
3810
+ }
3811
+ else { // Ringwechsel aufgetreten
3812
+ if (defined(HNDebugOn))
3813
+ {" ring change in HN(",Aufruf_Ebene+1,") detected";}
3814
+ EXTHNEnumber = HNerg[1][3];
3815
+ for (ii=lastRingnumber+1; ii<=EXTHNEnumber; ii++) {
3816
+ def EXTHNEring(ii)=HNerg[1][4][ii];
3817
+ }
3818
+ if (HNerg[2]==0) { setring HNEring; }
3819
+ else { setring EXTHNEring(HNerg[2]); }
3820
+ def tempRing=HNerg[4];
3821
+ def aneu=imap(tempRing,HNEs);
3822
+ kill tempRing;
3823
+
3824
+ //--- stelle lokale Variablen im neuen Ring wieder her, und rette
3825
+ // gegebenenfalls ihren Inhalt: ----
3826
+ list erg,faktoren,HNEakut;
3827
+ ideal hilfid;
3828
+ erg=ideal(0); faktoren=erg; HNEakut=erg;
3829
+ poly leitf,teiler,transformiert;
3830
+ map hole=HNE_noparam,transfproc,x,y;
3831
+ setring HNE_noparam;
3832
+ if (lastRingnumber>0) { def letztring=EXTHNEring(lastRingnumber); }
3833
+ else { def letztring=HNEring; }
3834
+ if (not defined(HNEs)) {list HNEs;}
3835
+ HNEs=imap(letztring,HNEs);
3836
+ if (not defined(azeilen)) {list azeilen;}
3837
+ azeilen=imap(letztring,azeilen);
3838
+ if (not defined(deltais)) {ideal deltais;}
3839
+ deltais=imap(letztring,deltais);
3840
+ if (not defined(delt)) {poly delt;}
3841
+ delt=imap(letztring,delt);
3842
+ if (not defined(fneu)) {poly fneu;}
3843
+ fneu=imap(letztring,fneu);
3844
+ if (not defined(f)) {poly f;}
3845
+ f=imap(letztring,f);
3846
+ if (not defined(hne)) {list hne;}
3847
+ hne=imap(letztring,hne);
3848
+
3849
+ setring EXTHNEring(EXTHNEnumber);
3850
+ list HNEs=hole(HNEs);
3851
+ list azeilen=hole(azeilen);
3852
+ ideal deltais=hole(deltais);
3853
+ number delt=number(hole(delt));
3854
+ poly fneu=hole(fneu);
3855
+ if (not(defined(f)))
3856
+ {
3857
+ poly f=hole(f);
3858
+ list hne=hole(hne);
3859
+ export f,hne;
3860
+ }
3861
+ }
3862
+
3863
+ //========== Verknuepfe bisherige HNE mit von HN gelieferten HNEs: ======
3864
+ if (R==0) {
3865
+ HNEs,hnezaehler=constructHNEs(HNEs,hnezaehler,aneu,azeilen,zeile,
3866
+ deltais,Q,j);
3867
+ kill aneu;
3868
+ }
3869
+ else {
3870
+ for (zaehler=1; zaehler<=size(aneu); zaehler++) {
3871
+ hnezaehler++;
3872
+ HNEakut=azeilen; // dupliziere den gemeinsamen Anfang der HNE's
3873
+ zl=2; // (kommt schliesslich nach HNEs[hnezaehler])
3874
+ //------------ Trage Beitrag dieser Transformation T2 ein: -------------
3875
+ //------ Zur Bedeutung von zeile, zl: siehe Kommentar weiter oben ------
3876
+
3877
+ //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: -----
3878
+ M1=M;N1=N;R1=R;Q1=M1 div N1;
3879
+ while (R1!=0) {
3880
+ if (defined(HNDebugOn)) { "h("+string(zeile+zl-2)+") =",Q1; }
3881
+ HNEakut[1][zeile+zl-1]=Q1;
3882
+ HNEakut[zeile+zl][Q1+1]=x; // Markierung des Zeilenendes der HNE
3883
+ zl=zl+1;
3884
+ //----- Bereitstellung von Speicherplatz fuer eine neue Zeile: --------
3885
+ HNEakut[zeile+zl]=ideal(0);
3886
+ M1=N1; N1=R1; R1=M1%N1; Q1=M1 div N1;
3887
+ }
3888
+ if (defined(HNDebugOn)) {
3889
+ "a("+string(zeile+zl-2)+","+string(Q1)+") =",delt;
3890
+ }
3891
+ HNEakut[zeile+zl][Q1]=delt;
3892
+
3893
+ //-- Daten aus T2_Transform sind eingetragen; haenge Daten von HN an: --
3894
+ hilfid=HNEakut[zeile+zl];
3895
+ for (zl1=Q1+1; zl1<=ncols(aneu[zaehler][2]); zl1++) {
3896
+ hilfid[zl1]=aneu[zaehler][2][zl1];
3897
+ }
3898
+ HNEakut[zeile+zl]=hilfid;
3899
+ // ------ vorher HNEs[.][zeile+zl]<-aneu[.][2],
3900
+ // jetzt [zeile+zl+1] <- [3] usw.: --------
3901
+ for (zl1=3; zl1<=size(aneu[zaehler]); zl1++) {
3902
+ HNEakut[zeile+zl+zl1-2]=aneu[zaehler][zl1];
3903
+ }
3904
+ //--- setze hqs zusammen: HNEs[hnezaehler][1]=HNEs[..][1],aneu[..][1] --
3905
+ hilfvec=HNEakut[1],aneu[zaehler][1];
3906
+ HNEakut[1]=hilfvec;
3907
+ //-------- weil nicht geht: liste[1]=liste[1],aneu[zaehler][1] ---------
3908
+ HNEs[hnezaehler]=HNEakut;
3909
+ } // end(for zaehler)
3910
+ kill aneu;
3911
+ } // endelse (R<>0)
3912
+ } // endif (subst()!=0) (weiteres Aufblasen mit HN)
3913
+
3914
+ } // end(for j) (Behandlung der einzelnen delta_i)
3915
+
3916
+
3917
+ // ------------------------- new for essdevelop ----------------------------
3918
+ if ((essential==1) and (defined(SaveRing))) {
3919
+ // ----- uebertrage Daten in gemeinsame Koerpererweiterung ---------------
3920
+ if (EXTHNEnumber>number_of_letztring) {
3921
+ // ----- fuer aktuelle Kante war Koerpererweiterung erforderlich -------
3922
+ EXTHNEnumber++;
3923
+ string @miniPol_EXTHNEring(EXTHNEnumber-1) = string(minpoly);
3924
+ setring SaveRing;
3925
+ string @miniPol_SaveRing = string(minpoly);
3926
+ setring HNE_noparam;
3927
+ if (not(defined(a_x))){ map a_x,a_y; poly mp_save, mp_new; }
3928
+ execute("mp_save= " + @miniPol_SaveRing + ";");
3929
+ execute("mp_new = " + @miniPol_EXTHNEring(EXTHNEnumber-1) + ";" );;
3930
+ if (mp_save==mp_new) { // Sonderfall: wieder gleicher Ring
3931
+ def EXTHNEring(EXTHNEnumber)=SaveRing;
3932
+ setring EXTHNEring(EXTHNEnumber);
3933
+ if (not(defined(f))) {poly f; f=hole(f); export f;}
3934
+ list dummyL=imap(EXTHNEring(EXTHNEnumber-1),HNEs);
3935
+ if (not(defined(HNEs))) { def HNEs=list(); }
3936
+ if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
3937
+ HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
3938
+ kill dummyL,SaveRing;
3939
+ }
3940
+ else { // verschiedene Ringe
3941
+ a_x=HNE_noparam,x,0,0;
3942
+ a_y=HNE_noparam,y,0,0;
3943
+ mp_save=a_x(mp_save); // minpoly aus SaveRing mit a --> x
3944
+ mp_new=a_y(mp_new); // minpoly aus SaveRing mit a --> y
3945
+ setring SaveRing;
3946
+ poly mp_new=imap(HNE_noparam,mp_new);
3947
+ list Lfac=factorize(mp_new,1);
3948
+ poly fac=Lfac[1][1];
3949
+ for (k=2;k<=size(Lfac[1]);k++) {
3950
+ if (deg(Lfac[1][k])<deg(fac)) { fac=Lfac[1][k]; }
3951
+ }
3952
+
3953
+ if (deg(fac)==1) { // keine Erweiterung noetig
3954
+ def EXTHNEring(EXTHNEnumber)=SaveRing;
3955
+ setring HNE_noparam;
3956
+ HNEs=imap(EXTHNEring(EXTHNEnumber-1),HNEs);
3957
+ setring EXTHNEring(EXTHNEnumber);
3958
+ if (not(defined(f))) {poly f; f=hole(f); export f;}
3959
+ map phi=HNE_noparam,-subst(fac,y,0)/koeff(fac,0,1),x,y;
3960
+ list dummyL=phi(HNEs);
3961
+ if (not(defined(HNEs))) { def HNEs=list(); }
3962
+ if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
3963
+ HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
3964
+ kill dummyL,phi,SaveRing;
3965
+ }
3966
+ else { // Koerpererweiterung noetig
3967
+ def EXTHNEring(EXTHNEnumber) = splitring(fac,list(a,transfproc));
3968
+ setring EXTHNEring(EXTHNEnumber);
3969
+ poly transf=erg[1]; // image of parameter from SaveRing
3970
+ poly transfproc=erg[2];
3971
+ poly transb=erg[3]; // image of parameter from EXTHNEring(..)
3972
+ export transfproc;
3973
+ kill erg;
3974
+ setring HNE_noparam;
3975
+ if (not(defined(HNEs1))) { list HNEs1=ideal(0); }
3976
+ HNEs1=imap(EXTHNEring(EXTHNEnumber-1),HNEs);
3977
+ if (not(defined(hne))) { list hne=ideal(0); }
3978
+ hne=imap(SaveRing,hne);
3979
+ HNEs=imap(SaveRing,HNEs);
3980
+ setring EXTHNEring(EXTHNEnumber);
3981
+ map hole=HNE_noparam,transf,x,y;
3982
+ poly fneu=hole(fneu);
3983
+ poly f=hole(f);
3984
+ map phi=HNE_noparam,transb,x,y;
3985
+ list HNEs=hole(HNEs);
3986
+ list hne=hole(hne);
3987
+ export f,hne;
3988
+ if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
3989
+ list dummyL=phi(HNEs1);
3990
+ HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
3991
+ kill dummyL,phi,SaveRing;
3992
+ }
3993
+ }
3994
+ }
3995
+ else { // nur bei letzter Kante muss was getan werden
3996
+ if (i==size(Newton)-1) {
3997
+ EXTHNEnumber++;
3998
+ if (number_of_letztring==0) { def letztring=HNEring; }
3999
+ else { def letztring=EXTHNEring(EXTHNEnumber); }
4000
+ if (minpoly==0) {
4001
+ def EXTHNEring(EXTHNEnumber)=SaveRing;
4002
+ setring EXTHNEring(EXTHNEnumber);
4003
+ if (not(defined(f))) {poly f; f=hole(f); export f;}
4004
+ if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
4005
+ list dummyL=imap(letztring,HNEs);
4006
+ HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
4007
+ kill dummyL,letztring,SaveRing;
4008
+ }
4009
+ else { // muessen Daten nach SaveRing uebertragen;
4010
+ setring HNE_noparam;
4011
+ if (not(defined(HNEs))) { list HNEs; }
4012
+ HNEs=imap(letztring,HNEs);
4013
+ def EXTHNEring(EXTHNEnumber)=SaveRing;
4014
+ setring EXTHNEring(EXTHNEnumber);
4015
+ if (not(defined(hole))) { map hole; }
4016
+ hole=HNE_noparam,transfproc,x,y;
4017
+ list dummyL=hole(HNEs);
4018
+ if (not(defined(HNEs))) { def HNEs=list(); }
4019
+ if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();}
4020
+ HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)];
4021
+ kill dummyL, letztring,SaveRing;
4022
+ }
4023
+ }
4024
+ }
4025
+ }
4026
+ // -----------------end of new part (loop for essential=1) ----------------
4027
+ } // end (Loop uber Kanten)
4028
+ if (defined(SaveRing)) { kill SaveRing; }
4029
+ }
4030
+ else {
4031
+ HNEs[1]=list(hqs)+azeilen+list(fneu); // fneu ist transform. Polynom oder Null
4032
+ conj1[1]=conj_factor;
4033
+ }
4034
+
4035
+ if (Aufruf_Ebene == 1)
4036
+ {
4037
+ if ((number_of_letztring!=EXTHNEnumber) and (not(defined(hne))))
4038
+ {
4039
+ //----- falls Zweige in transz. Erw. berechnet werden konnten ---------
4040
+ if (defined(transfproc))
4041
+ { // --- Ringwechsel hat stattgefunden ---
4042
+ if (defined(HNDebugOn)) {" ring change in HN(",1,") detected";}
4043
+ if (not(defined(hole))) { map hole; }
4044
+ hole=HNE_noparam,transfproc,x,y;
4045
+ setring HNE_noparam;
4046
+ f=imap(HNEring,f);
4047
+ if (number_of_letztring==0) { def letztring=HNEring; }
4048
+ else { def letztring=EXTHNEring(EXTHNEnumber); }
4049
+ if (not(defined(hne))) { list hne; }
4050
+ hne=imap(letztring,hne);
4051
+ setring EXTHNEring(EXTHNEnumber);
4052
+ if (not(defined(f))) { poly f=hole(f); export f; }
4053
+ list hne=hole(hne);
4054
+ export hne;
4055
+ }
4056
+ }
4057
+ if (size(HNEs)>0) {
4058
+ if ((size(HNEs)>1) or (typeof(HNEs[1])!="ideal") or (size(HNEs[1])>0)) {
4059
+ if ((typeof(hne[1])=="ideal")) { hne=list(); }
4060
+ hne=hne+extractHNEs(HNEs,getauscht);
4061
+ if (hne_conj==0) { hne_conj=conj1; }
4062
+ else { hne_conj = hne_conj, conj1; }
4063
+ }
4064
+ }
4065
+ }
4066
+ else
4067
+ { // HN wurde rekursiv aufgerufen
4068
+ if (number_of_letztring!=EXTHNEnumber)
4069
+ { // Ringwechsel hatte stattgefunden
4070
+ string mipl_alt = string(minpoly);
4071
+ ring tempRing = create_ring(ringlist(basering)[1],"("+varstr(basering)+")","("+ordstr(basering)+")","no_minpoly");
4072
+ execute("minpoly="+ mipl_alt +";");
4073
+ list HNEs=imap(EXTHNEring(EXTHNEnumber),HNEs);
4074
+ export HNEs;
4075
+ if (defined(HNDebugOn)) {" ! tempRing defined ! ";}
4076
+ }
4077
+ if (conj1!=0) { hne_conj=conj1; }
4078
+ else { hne_conj=conj_factor; }
4079
+ }
4080
+ if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); }
4081
+ HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring);
4082
+ if (number_of_letztring==EXTHNEnumber) {
4083
+ return(list(HNE_RingDATA,EXTHNEnumber,field_ext,HNEs,hne_conj));
4084
+ }
4085
+ else {
4086
+ if (defined(tempRing)) {
4087
+ return(list(HNE_RingDATA,EXTHNEnumber,field_ext,tempRing,hne_conj));
4088
+ }
4089
+ return(list(HNE_RingDATA,EXTHNEnumber,field_ext,0,hne_conj));
4090
+ }
4091
+ }
4092
+
4093
+ ///////////////////////////////////////////////////////////////////////////////
4094
+
4095
+ static proc constructHNEs (list HNEs,int hnezaehler,list aneu,list azeilen,
4096
+ int zeile,ideal deltais,int Q,int j)
4097
+ "NOTE: This procedure is only for internal use, it is called via HN"
4098
+ {
4099
+ int zaehler,zl;
4100
+ ideal hilfid;
4101
+ list hilflist;
4102
+ intvec hilfvec;
4103
+ for (zaehler=1; zaehler<=size(aneu); zaehler++) {
4104
+ hnezaehler++;
4105
+ // HNEs[hnezaehler]=azeilen; // dupliziere gemeins. Anfang
4106
+ //----------------------- trage neu berechnete Daten ein ---------------------
4107
+ hilfid=azeilen[zeile+2];
4108
+ hilfid[Q]=deltais[j];
4109
+ for (zl=Q+1; zl<=ncols(aneu[zaehler][2]); zl++) {
4110
+ hilfid[zl]=aneu[zaehler][2][zl];
4111
+ }
4112
+ hilflist=azeilen; hilflist[zeile+2]=hilfid;
4113
+ //------------------ haenge uebrige Zeilen von aneu[] an: --------------------
4114
+ for (zl=3; zl<=size(aneu[zaehler]); zl++) {
4115
+ hilflist[zeile+zl]=aneu[zaehler][zl];
4116
+ }
4117
+ //--- setze die hqs zusammen: HNEs[hnezaehler][1]=HNEs[..][1],aneu[..][1] ----
4118
+ if (hilflist[1]==0) { hilflist[1]=aneu[zaehler][1]; }
4119
+ else { hilfvec=hilflist[1],aneu[zaehler][1]; hilflist[1]=hilfvec; }
4120
+ HNEs[hnezaehler]=hilflist;
4121
+ }
4122
+ return(HNEs,hnezaehler);
4123
+ }
4124
+ ///////////////////////////////////////////////////////////////////////////////
4125
+
4126
+ proc referencepoly (list newton)
4127
+ "USAGE: referencepoly(newton);
4128
+ newton is list of intvec(x,y) which represents points in the Newton
4129
+ diagram (e.g. output of the proc newtonpoly)
4130
+ RETURN: a polynomial which has newton as Newton diagram
4131
+ SEE ALSO: newtonpoly
4132
+ EXAMPLE: example referencepoly; shows an example
4133
+ "
4134
+ {
4135
+ poly f;
4136
+ for (int i=1; i<=size(newton); i++) {
4137
+ f=f+var(1)^newton[i][1]*var(2)^newton[i][2];
4138
+ }
4139
+ return(f);
4140
+ }
4141
+ example
4142
+ { "EXAMPLE:"; echo = 2;
4143
+ ring exring=0,(x,y),ds;
4144
+ referencepoly(list(intvec(0,4),intvec(2,3),intvec(5,1),intvec(7,0)));
4145
+ }
4146
+ ///////////////////////////////////////////////////////////////////////////////
4147
+
4148
+ proc factorlist (list L, list #)
4149
+ "USAGE: factorlist(L); L a list in the format of 'factorize'
4150
+ RETURN: the nonconstant irreducible factors of
4151
+ L[1][1]^L[2][1] * L[1][2]^L[2][2] *...* L[1][size(L[1])]^...
4152
+ with multiplicities (same format as factorize)
4153
+ SEE ALSO: factorize
4154
+ EXAMPLE: example factorlist; shows an example
4155
+ "
4156
+ {
4157
+ int k;
4158
+ if ((size(#)>=1) and ((typeof(#[1])=="intvec") or (typeof(#[1])=="int"))) {
4159
+ int with_conj = 1; intvec C = #[1];
4160
+ }
4161
+ else {
4162
+ int with_conj = 0; intvec C = L[2];
4163
+ }
4164
+ // eine Sortierung der Faktoren eruebrigt sich, weil keine zwei versch.
4165
+ // red.Fakt. einen gleichen irred. Fakt. haben koennen (I.3.27 Diplarb.)
4166
+ int i,gross;
4167
+ list faktoren,hilf;
4168
+ intvec conjugates;
4169
+ ideal hil1,hil2;
4170
+ intvec v,w,hilf_conj;
4171
+ for (i=1; (L[1][i] == jet(L[1][i],0)) && (i<size(L[1])); i++) {;}
4172
+ if (L[1][i] != jet(L[1][i],0)) {
4173
+ hilf=factorize(L[1][i]);
4174
+ // Achtung!!! factorize(..,2) wirft entgegen der Beschreibung nicht nur
4175
+ // konstante Faktoren raus, sondern alle Einheiten in der LOKALISIERUNG nach
4176
+ // der Monomordnung!!! Im Beispiel unten verschwindet der Faktor x+y+1, wenn
4177
+ // man ds statt dp als Ordnung nimmt!
4178
+ hilf_conj=C[i];
4179
+ for (k=2;k<=size(hilf[2]);k++){ hilf_conj=hilf_conj,C[i]; }
4180
+ hilf[2]=hilf[2]*L[2][i];
4181
+ hil1=hilf[1];
4182
+ gross=size(hil1);
4183
+ if (gross>1) {
4184
+ v=hilf[2];
4185
+ faktoren=list(ideal(hil1[2..gross]),intvec(v[2..gross]));
4186
+ conjugates=intvec(hilf_conj[2..gross]);
4187
+ }
4188
+ else { faktoren=hilf; conjugates=hilf_conj; }
4189
+ }
4190
+ else {
4191
+ faktoren=L;
4192
+ conjugates=C;
4193
+ }
4194
+
4195
+ for (i++; i<=size(L[2]); i++) {
4196
+ //------------------------- linearer Term -- irreduzibel ---------------------
4197
+ if (L[1][i] == jet(L[1][i],1)) {
4198
+ if (L[1][i] != jet(L[1][i],0)) { // konst. Faktoren eliminieren
4199
+ hil1=faktoren[1];
4200
+ hil1[size(hil1)+1]=L[1][i];
4201
+ faktoren[1]=hil1;
4202
+ v=faktoren[2],L[2][i];
4203
+ conjugates=conjugates,C[i];
4204
+ faktoren[2]=v;
4205
+ }
4206
+ }
4207
+ //----------------------- nichtlinearer Term -- faktorisiere -----------------
4208
+ else {
4209
+ hilf=factorize(L[1][i]);
4210
+ hilf_conj=C[i];
4211
+ for (k=2;k<=size(hilf[2]);k++){ hilf_conj=hilf_conj,C[i]; }
4212
+ hilf[2]=hilf[2]*L[2][i];
4213
+ hil1=faktoren[1];
4214
+ hil2=hilf[1];
4215
+ gross=size(hil2);
4216
+ // hil2[1] ist konstant, wird weggelassen:
4217
+ hil1[(size(hil1)+1)..(size(hil1)+gross-1)]=hil2[2..gross];
4218
+ // ideal+ideal does not work due to simplification;
4219
+ // ideal,ideal not allowed
4220
+ faktoren[1]=hil1;
4221
+ w=hilf[2];
4222
+ v=faktoren[2],w[2..gross];
4223
+ conjugates=conjugates,hilf_conj[2..gross];
4224
+ faktoren[2]=v;
4225
+ }
4226
+ }
4227
+ if (with_conj==0) { return(faktoren); }
4228
+ else { return(list(faktoren,conjugates)); } // for essential development
4229
+ }
4230
+ example
4231
+ { "EXAMPLE:"; echo = 2;
4232
+ ring exring=0,(x,y),ds;
4233
+ list L=list(ideal(x,(x-y)^2*(x+y+1),x+y),intvec(2,2,1));
4234
+ L;
4235
+ factorlist(L);
4236
+ }
4237
+
4238
+ ///////////////////////////////////////////////////////////////////////////////
4239
+
4240
+ proc delta
4241
+ "USAGE: delta(INPUT); INPUT a polynomial defining an isolated plane curve
4242
+ singularity at 0, or the Hamburger-Noether expansion thereof, i.e.
4243
+ the output of @code{develop(f)}, or the output of @code{hnexpansion(f)},
4244
+ or the list of HN data computed by @code{hnexpansion(f)}.
4245
+ RETURN: int, the delta invariant of the singularity at 0, that is, the vector
4246
+ space dimension of R~/R, (R~ the normalization of the local ring of
4247
+ the singularity).
4248
+ NOTE: In case the Hamburger-Noether expansion of the curve f is needed
4249
+ for other purposes as well it is better to calculate this first
4250
+ with the aid of @code{hnexpansion} and use it as input instead of
4251
+ the polynomial itself.
4252
+ SEE ALSO: deltaLoc, invariants
4253
+ KEYWORDS: delta invariant
4254
+ EXAMPLE: example delta; shows an example
4255
+ "
4256
+ {
4257
+ if (typeof(#[1])=="poly") { // INPUT = polynomial defining the singularity
4258
+ list L=hnexpansion(#[1]);
4259
+ if (typeof(L[1])=="ring") {
4260
+ def altring = basering;
4261
+ def HNring = L[1]; setring HNring;
4262
+ return(delta(hne));
4263
+ }
4264
+ else {
4265
+ return(delta(L));
4266
+ }
4267
+ }
4268
+ if (typeof(#[1])=="ring") { // INPUT = HNEring of curve
4269
+ def HNring = #[1]; setring HNring;
4270
+ return(delta(hne));
4271
+ }
4272
+ if (typeof(#[1])=="matrix")
4273
+ { // INPUT = hne of an irreducible curve
4274
+ return(invariants(#)[5] div 2);
4275
+ }
4276
+ else
4277
+ { // INPUT = hne of a reducible curve
4278
+ list INV=invariants(#);
4279
+ return(INV[size(INV)][3]);
4280
+ }
4281
+ }
4282
+ example
4283
+ { "EXAMPLE:"; echo = 2;
4284
+ ring r = 32003,(x,y),ds;
4285
+ poly f = x25+x24-4x23-1x22y+4x22+8x21y-2x21-12x20y-4x19y2+4x20+10x19y
4286
+ +12x18y2-24x18y-20x17y2-4x16y3+x18+60x16y2+20x15y3-9x16y
4287
+ -80x14y3-10x13y4+36x14y2+60x12y4+2x11y5-84x12y3-24x10y5
4288
+ +126x10y4+4x8y6-126x8y5+84x6y6-36x4y7+9x2y8-1y9;
4289
+ delta(f);
4290
+ }
4291
+
4292
+ ///////////////////////////////////////////////////////////////////////////////