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,2542 @@
1
+ ////////////////////////////////////////////////////////////////////////////////
2
+ version="version alexpoly.lib 4.1.2.0 Feb_2019 "; // $Id: 9bf3d0af4d76716129d798028d1fc7c9d443697d $
3
+ category="Singularities";
4
+ info="
5
+ LIBRARY: alexpoly.lib Resolution Graph and Alexander Polynomial
6
+ AUTHOR: Fernando Hernando Carrillo, hernando@agt.uva.es
7
+ Thomas Keilen, keilen@mathematik.uni-kl.de
8
+
9
+ OVERVIEW:
10
+ A library for computing the resolution graph of a plane curve singularity f,
11
+ the total multiplicities of the total transforms of the branches of f along
12
+ the exceptional divisors of a minimal good resolution of f, the Alexander
13
+ polynomial of f, and the zeta function of its monodromy operator.
14
+
15
+ PROCEDURES:
16
+ resolutiongraph(f); resolution graph f
17
+ totalmultiplicities(f); resolution graph, total multiplicities and strict multiplicities of f
18
+ alexanderpolynomial(f); Alexander polynomial of f
19
+ semigroup(f); calculates generators for the semigroup of f
20
+ proximitymatrix(f); calculates the proximity matrix of f
21
+ multseq2charexp(v); converts multiplicity sequence to characteristic exponents
22
+ charexp2multseq(v); converts characteristic exponents to multiplicity sequence
23
+ charexp2generators(v); converts characteristic exponents to generators of the semigroup
24
+ charexp2inter(c,e); converts contact matrix and charact. exp. to intersection matrix
25
+ charexp2conductor(v); converts characteristic exponents to conductor
26
+ charexp2poly(v,a); calculates a polynomial f with characteristic exponents v
27
+ tau_es2(f); equisingular Tjurina number of f
28
+
29
+ KEYWORDS: Hamburger-Noether expansion; Puiseux expansion; curve singularities;
30
+ topological invariants; Alexander polynomial; resolution graph;
31
+ total multiplicities; equisingular Tjurina number
32
+ ";
33
+
34
+ ///////////////////////////////////////////////////////////////////////////////////////////
35
+ LIB "hnoether.lib";
36
+ LIB "ring.lib";
37
+ ///////////////////////////////////////////////////////////////////////////////////////////
38
+
39
+ proc resolutiongraph (def INPUT,list #)
40
+ "USAGE: resolutiongraph(INPUT); INPUT poly or list
41
+ ASSUME: INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
42
+ or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
43
+ the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
44
+ @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
45
+ the contact matrix and a list of integer vectors with the characteristic exponents
46
+ of the branches of a plane curve singularity, or an integer vector containing the
47
+ characteristic exponents of an irreducible plane curve singularity.
48
+ RETURN: intmat, the incidence matrix of the resolution graph of the plane curve
49
+ defined by INPUT, where the entries on the diagonal are the weights of the
50
+ vertices of the graph and a negative entry corresponds to the strict transform
51
+ of a branch of the curve.
52
+ NOTE: In case the Hamburger-Noether expansion of the curve f is needed
53
+ for other purposes as well it is better to calculate this first
54
+ with the aid of @code{hnexpansion} and use it as input instead of
55
+ the polynomial itself.
56
+ @*
57
+ If you are not sure whether the INPUT polynomial is reduced or not, use
58
+ @code{squarefree(INPUT)} as input instead.
59
+ SEE ALSO: develop, hnexpansion, totalmultiplicities, alexanderpolynomial
60
+ EXAMPLE: example resolutiongraph; shows an example
61
+ "
62
+ {
63
+ return(totalmultiplicities(INPUT,#)[1]);
64
+ }
65
+ example
66
+ {
67
+ "EXAMPLE:";
68
+ echo=2;
69
+ ring r=0,(x,y),ls;
70
+ poly f1=(y2-x3)^2-4x5y-x7;
71
+ poly f2=y2-x3;
72
+ poly f3=y3-x2;
73
+ resolutiongraph(f1*f2*f3);
74
+ }
75
+
76
+ proc totalmultiplicities (def INPUT, list #)
77
+ "USAGE: totalmultiplicities(INPUT); INPUT poly or list
78
+ ASSUME: INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
79
+ or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
80
+ the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
81
+ @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
82
+ the contact matrix and a list of integer vectors with the characteristic exponents
83
+ of the branches of a plane curve singularity, or an integer vector containing the
84
+ characteristic exponents of an irreducible plane curve singularity.
85
+ RETURN: list @code{L} of three integer matrices. @code{L[1]} is the incidence matrix of
86
+ the resolution graph of the plane curve defined by INPUT, where the entries on the
87
+ diagonal are the weights of the vertices of the graph and a negative entry corresponds
88
+ to the strict transform of a branch of the curve. @code{L[2]} is an integer matrix,
89
+ which has for each vertex in the graph a row and for each branch of the curve a column.
90
+ The entry in position [i,j] contains the total multiplicity of the j-th branch (i.e. the
91
+ branch with weight -j in @code{L[1]}) along the exceptional divisor corresponding
92
+ to the i-th row in @code{L[1]}. In particular, the i-th row contains
93
+ the total multiplicities of the branches of the plane curve (defined by INPUT) along
94
+ the exceptional divisor which corresponds to the i-th row in the incidence matrix
95
+ @code{L[1]}. @code{L[3]} is an integer matrix which contains the (strict) multiplicities
96
+ of the branches of the curve along the exceptional divisors in the same way as @code{L[2]}
97
+ contains the total multiplicities.
98
+ NOTE: The total multiplicity of a branch along an exceptional divisor is the multiplicity
99
+ with which this exceptional divisor occurs in the total transform of this branch
100
+ under the resolution corresponding to the resolution graph.
101
+ @*
102
+ In case the Hamburger-Noether expansion of the curve f is needed
103
+ for other purposes as well it is better to calculate this first
104
+ with the aid of @code{hnexpansion} and use it as input instead of
105
+ the polynomial itself.
106
+ @*
107
+ If you are not sure whether the INPUT polynomial is reduced or not, use
108
+ @code{squarefree(INPUT)} as input instead.
109
+ SEE ALSO: develop, hnexpansion, alexanderpolynomial, resolutiongraph
110
+ EXAMPLE: example totalmultiplicities; shows an example
111
+ "
112
+ {
113
+ ///////////////////////////////////////////////////////////////////////////////////////////////
114
+ /// The algorithm described in [JP] DeJong, Pfister, Local Analytic Geometry, Vieweg 2000,
115
+ /// is used for the implementation -- the missing case is included by appropriate sorting.
116
+ ///////////////////////////////////////////////////////////////////////////////////////////////
117
+ /// If # is empty, then an additional sorting of the branches will be made, so that
118
+ /// the branches can be split with split_graph in order to get the graphs of the curves
119
+ /// separated on the first exceptional divisor. Otherwise split_graph should not be applied!
120
+ ///////////////////////////////////////////////////////////////////////////////////////////////
121
+ /// If #[1]="tau", then totalmultiplicities is called for the use in tau_es2 - thus it returns
122
+ /// the prolonged resolutiongraphs of the branches, their multiplicity sequences and their
123
+ /// contact matrix - sorted appropriately.
124
+ ///////////////////////////////////////////////////////////////////////////////////////////////
125
+ int i,j,s,e,ii;
126
+ intmat helpmati,helpmatii;
127
+ intvec helpvec;
128
+ int inputispoly=0;
129
+ /////////////////////////////////////////////////////////////////////////////////
130
+ // Decide, which kind of input we have, and define the contact matrix
131
+ /////////////////////////////////////////////////////////////////////////////////
132
+ // Input: a polynomial defining a plane curve singularity.
133
+ //////////////////////////////////////////////////////////////////////////////
134
+ if (typeof(INPUT)=="poly")
135
+ {
136
+ /*
137
+ poly f=squarefree(INPUT);
138
+ if ( deg(f)!=deg(INPUT) )
139
+ {
140
+ dbprint(printlevel-voice+4,"// input polynomial was not reduced");
141
+ dbprint(printlevel-voice+4,"// we continue with its reduction");
142
+ }
143
+ list I@N@V=invariants(f);
144
+ */
145
+ list I@N@V=invariants(INPUT);
146
+ inputispoly=1;
147
+ }
148
+ else
149
+ {
150
+ ///////////////////////////////////////////////////////////////////////////////////
151
+ // Input: the vector of characteristic exponents of an irreducible plane curve
152
+ ///////////////////////////////////////////////////////////////////////////////////
153
+ if (typeof(INPUT)=="intvec")
154
+ {
155
+ list charexp;
156
+ charexp[1]=INPUT;
157
+ intmat contact[1][1]=0;
158
+ }
159
+ else
160
+ {
161
+ if (typeof(INPUT)=="list")
162
+ {
163
+ /////////////////////////////////////////////////////////////////////////////////
164
+ // Input: intersection-matrix and characteristic exponents.
165
+ //////////////////////////////////////////////////////////////////////////////
166
+ if (typeof(INPUT[1])=="intmat")
167
+ {
168
+ intmat contact=INPUT[1];
169
+ list charexp=INPUT[2];
170
+ }
171
+ else
172
+ {
173
+ /////////////////////////////////////////////////////////////////////////////////
174
+ // Input: output of hnexpansion or hne in the ring created by hnexpansion
175
+ //////////////////////////////////////////////////////////////////////////////
176
+ if ((typeof(INPUT[1])=="ring") or (typeof(INPUT[1])=="list"))
177
+ {
178
+ list I@N@V=invariants(INPUT);
179
+ }
180
+ else
181
+ {
182
+ ////////////////////////////////////////////////////////////////////////////////////
183
+ // Input: output of reddevelop or extdevelop -- irreducible plane curve singularity
184
+ ////////////////////////////////////////////////////////////////////////////////////
185
+ if (typeof(INPUT[1])=="matrix")
186
+ {
187
+ list charexp=invariants(INPUT)[1];
188
+ intmat contact[1][1]=0;
189
+ }
190
+ else
191
+ {
192
+ ERROR("The input is invalid!");
193
+ }
194
+ }
195
+ }
196
+ }
197
+ else
198
+ {
199
+ ERROR("The input is invalid!");
200
+ }
201
+ }
202
+ }
203
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
204
+ // If the input was a polynomial or a HN-Expansion, then calculate the contact matrix and char.exponents.
205
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
206
+ if (defined(I@N@V))
207
+ {
208
+ intmat contact=I@N@V[size(I@N@V)][1]; // contact numbers
209
+ list charexp; // characteristic exponents
210
+ for (i=1;i<=size(I@N@V)-1;i++)
211
+ {
212
+ charexp[i]=I@N@V[i][1];
213
+ }
214
+ }
215
+ //////////////////////////////////////////////////////////////////////////////
216
+ // Find the maximal contact numbers of the branches
217
+ //////////////////////////////////////////////////////////////////////////////
218
+ int r=ncols(contact); // number of branches
219
+ intvec maxcontact; // maximal contactnumber of branch i with other branches
220
+ for (i=1;i<=r;i++)
221
+ {
222
+ maxcontact[i]=max_in_intvec(intvec(contact[i,1..r]));
223
+ }
224
+ ///////////////////////////////////////////////////////////////////////////////
225
+ // Define the graphs of the branches and prolong them if necessary.
226
+ ///////////////////////////////////////////////////////////////////////////////
227
+ intmat gr,gr_red,grp; // a subgraph, a reduced subgraph, a prolonged subgraph
228
+ int omega; // point of highest weight in subgraph
229
+ list graphs; // contains the subgraphs of the C_i
230
+ list totmult; // contains the total multiplicities of the subgraphs
231
+ list multipl; // contains the multiplicities of the subgraphs
232
+ list gr_tm; // takes a single subgraph and tot.mult.
233
+ intvec tm,mt; // total multiplicities and multiplicities
234
+ for (i=1;i<=r;i++)
235
+ {
236
+ gr_tm=irred_resgraph_totmult(charexp[i]); // graph, total multipl. and multipl. of the ith branch
237
+ gr=gr_tm[1]; // the graph of the ith branch
238
+ tm=gr_tm[2]; // the total multiplicities of the ith branch
239
+ mt=gr_tm[3]; // the multiplicities of the ith branch
240
+ omega=nrows(gr)-1; // maximal weight in the graph of the ith branch
241
+ // If the maximal contact of the ith branch with some other branch is larger
242
+ // than the maximal weight omega, then the graph has to be polonged.
243
+ if (omega<maxcontact[i])
244
+ {
245
+ grp=intmat(intvec(0),maxcontact[i]+1,maxcontact[i]+1);
246
+ // save the graph without the point of the strict transform
247
+ if (omega>=1) // otherwise the graph consists only of the strict transform
248
+ {
249
+ grp[1..omega,1..omega]=gr[1..omega,1..omega];
250
+ }
251
+ // add the points of multiplicity 1 up to weight maxcontact[i] and the strict transform
252
+ // and connect them
253
+ for (j=omega+1;j<=maxcontact[i]+1;j++)
254
+ {
255
+ // adding the vertex to the graph and adding the total multiplicities
256
+ if (j<=maxcontact[i])
257
+ {
258
+ grp[j,j]=j;
259
+ if (j>1)
260
+ {
261
+ tm[j]=tm[j-1]+1;
262
+ mt[j]=1;
263
+ }
264
+ else // then there is no previous point in the graph
265
+ {
266
+ tm[j]=1;
267
+ mt[j]=1;
268
+ }
269
+ }
270
+ // connecting the vertex with the previous part of the graph
271
+ if (j>1) // otherwise there is nothing to connect to
272
+ {
273
+ grp[j-1,j]=1;
274
+ grp[j,j-1]=1;
275
+ }
276
+ }
277
+ gr=grp; // replace the subgraph by the prolonged subgraph
278
+ }
279
+ gr[nrows(gr),ncols(gr)]=-i; // give the strict transform in the ith branch weight -i
280
+ graphs[i]=gr;
281
+ totmult[i]=tm;
282
+ multipl[i]=mt;
283
+ }
284
+ ///////////////////////////////////////////////////////////////////////////////
285
+ // Check, if the procedure is called from inside tau_es2.
286
+ int check_tau;
287
+ if (size(#)==1)
288
+ {
289
+ if (#[1]=="tau")
290
+ {
291
+ check_tau=1;
292
+ }
293
+ }
294
+ /////////////////////////////////////////////////////////////////////////////////
295
+ // The procedure tau_es2 expects the branches to be ordered according to their
296
+ // contact during the resolution process.
297
+ /////////////////////////////////////////////////////////////////////////////////
298
+ if ((size(#)==0) or (check_tau==1))
299
+ {
300
+ list SORT;
301
+ for (i=1;i<=ncols(contact)-2;i++)
302
+ {
303
+ SORT=sort_branches(contact,graphs,totmult,multipl,i,ncols(contact));
304
+ contact=SORT[1];
305
+ graphs=SORT[2];
306
+ totmult=SORT[3];
307
+ multipl=SORT[4];
308
+ }
309
+ }
310
+ ///////////////////////////////////////////////////////////////////////////////////
311
+ /// If the procedure is called from inside tau_es2, the output will be the prolonged
312
+ /// resolutiongraphs of the branches, their multiplicity sequences and their contact matrix.
313
+ if (check_tau==1)
314
+ {
315
+ return(list(graphs,multipl,contact));
316
+ }
317
+ /////////////////////////////////////////////////////////////////////////////////////
318
+ // Sort the branches in such a way, that in the blowing up procedure whenever two branches
319
+ // C_i and C_j have contact k (i.e. after k steps they are separated) and one of the following
320
+ // situations occurs:
321
+ // A) some exceptional divisor E_l (l<k) still intersects C_i after k steps of blowing up
322
+ // and no such E_l intersects C_j
323
+ // OR
324
+ // B) some exceptional divisor E_l (l<k-1) still intersects C_i after k steps of blowing up
325
+ // and another one (necessarily E_k-1) intersects C_j,
326
+ // THEN: i<j!
327
+ /////////////////////////////////////////////////////////////////////////////////////////
328
+ // This means in the algorithm for glueing graphs together described in [JP] p.217-19
329
+ // the Case 3 never occurs -- and Case 1 only occurs, if it is unavoidable, that is when
330
+ // C_1 there meets an E_l with l<k.
331
+ // (Otherwise we say that (C_i,C_j) has "bad contact".)
332
+ ////////////////////////////////////////////////////////////////////////////////////////
333
+ // We can detect this by looking at the graphs of C_i and C_j. If E_l stays together with
334
+ // C_i and not with C_j in the k-th step of blowing up, then in the graph of C_i
335
+ // k and l are NOT connected, while in the graph of C_j they are!
336
+ //////////////////////////////////////////////////////////////////////////////////////////
337
+ // Note also, that for a fixed pair (i,j) this situation can only occur for ONE l (in Case A: l<k
338
+ // and possibly l=k-1; in Case B: l<k-1).
339
+ //////////////////////////////////////////////////////////////////////////////////////////
340
+ // Our algorithm now works as follows. Start with i=1 and j=2.
341
+ // While (i<r=number of branches) do as follows: Check C_i with C_j.
342
+ // If a bad contact (C_i,C_j) occurs, then MOVE C_j to the position of C_i (and move all C_t
343
+ // with t>=i, t!=j one position further). Else do nothing particular.
344
+ // Then, if j<r set j=j+1. Else set j=i+2 and i=i+1. End of While.
345
+ // To see that this works we note that if (C_i,C_j) has bad contact for some j>i, then
346
+ // (C_j,C_t) does NOT have bad contact for t=i+1,...,j-1. For this we consider the 3 cases:
347
+ // 1) contact(C_t,C_j)=contact(C_i,C_j)=k: E_l stays with C_j in k-th step and C_t and C_j
348
+ // separate there, so (C_t,C_j) has bad contact
349
+ // and hence (C_j,C_t) does NOT have bad contact
350
+ // 2) contact(C_t,C_j)>contact(C_i,C_j)=k: CANNOT HAPPEN - C_i had no bad contact with C_t,
351
+ // hence E_l did not stay with C_t in the k-th step;
352
+ // however, E_l stays with C_j there, so C_t and C_j
353
+ // cannot have a contact higher than k
354
+ // 3) contact(C_t,C_j)<contact(C_i,C_j)=k: when C_t and C_j separate, C_j and C_i are still
355
+ // together; and since (C_i,C_t) did not have bad
356
+ // contact also (C_j,C_t) cannot have bad contact.
357
+ // This ensures that when we do the moving of the graphs, we do NOT create any new bad contacts.
358
+ //////////////////////////////////////////////////////////////////////////////
359
+ i=1;
360
+ j=2;
361
+ intvec connections_i,connections_j;
362
+ int n_i,n_j;
363
+ int bad_contact;
364
+ list newpos; // when reordering the branches, here we save the new order of the old branches
365
+ for (ii=1;ii<=r;ii++)
366
+ {
367
+ newpos[ii]=ii;
368
+ }
369
+ while (i<r)
370
+ {
371
+ // Test graphs[i] with graphs[j] for bad contact.
372
+ connections_i=find_lower_connection_points(graphs[i],contact[i,j]);
373
+ if (connections_i[1]==0) // no connection point of lower weight there
374
+ {
375
+ n_i=0;
376
+ }
377
+ else
378
+ {
379
+ n_i=size(connections_i);
380
+ }
381
+ connections_j=find_lower_connection_points(graphs[j],contact[i,j]);
382
+ if (connections_j[1]==0) // no connection point of lower weight there
383
+ {
384
+ n_j=0;
385
+ }
386
+ else
387
+ {
388
+ n_j=size(connections_j);
389
+ }
390
+ bad_contact=0;
391
+ ii=1;
392
+ // The points of weight k=contact(C_i,C_j) in C_i and C_j are connected to n_i respectively
393
+ // n_j points of weight less than k, where n_i and n_j might take values among 0, 1 and 2.
394
+ // n_j=2: Then E_k is intersected by E_k-1 and E_l (l<k-1) in the k-th step, however
395
+ // C_j does not stay with anyone of those, so (C_i,C_j) does not have bad contact.
396
+ // n_i=0: Then C_i stays with E_k-1 and there is no E_l with l<k-1 in the k-th step,
397
+ // hence (C_i,C_j) does not have bad contact.
398
+ // n_i=1, n_j=0: Analogously, then C_j stays with E_k-1 and there is no E_l (l<k-1). This means
399
+ // (C_i,C_j) has bad contact.
400
+ // n_i=1, n_j=1: EITHER there is no E_l (l<k-1) and C_i and C_j both separate from E_k-1
401
+ // in the k-th step of blowing up (hence (C_i,C_j) does not have bad contact).
402
+ // OR there is an E_l (l<k-1) with which one stays and the other one stays
403
+ // with E_k-1 (bad contact, if E_l stays with C_j; good contact otherwise).
404
+ // n_i=2, E_k is intersected by E_k-1 and E_l in the k-th step and C_i does not
405
+ // stay together with any of those.
406
+ // n_j=0: This CANNOT occur, since then C_j would have to stay together with E_l
407
+ // and E_k-1, which is impossible.
408
+ // n_j=1: Then C_j stays together with either E_l or with E_k-1, however both cases
409
+ // imply that (C_i,C_j) has bad contact
410
+ // ALTERNATIVE CONSIDERATION FOR DISTINGUISHING THE CASES:
411
+ // n_i<n_j : C_i stays with "more" E's than C_j does (only one is possible of course!),
412
+ // hence (C_i,C_j) does not have bad contact.
413
+ // n_i>n_j : C_i stays with "less" E's than C_j does (i.e. with none) hence (C_i,C_j) has bad contact.
414
+ // n_i=n_j=0 : Not possible, since then both would stay with E_k-1.
415
+ // n_i=n_j=2 : Both separate from E_k-1 as well as from some E_l (l<k) - hence NO bad contact.
416
+ // n_i=n_j=1 : One stays with E_k-1 and one with E_l (l<k). Bad contact, if C_j stays with E_l,
417
+ // i.e. if in the graph of C_i the point k is connected to l, and no bad contact otherwise.
418
+ if ((n_i>n_j) or ((n_i==1) and (n_j==1) and (connections_i[1]<contact[i,j]-1)))
419
+ {
420
+ bad_contact=1;
421
+ // Move the graph (etc.) of C_j into the position i.
422
+ newpos=insert(newpos,newpos[j],i-1);
423
+ newpos=delete(newpos,j+1);
424
+ // BE AWARE: after this reordering the graphs do not have the correct weight for the
425
+ // strict transform any more; this will be adjusted further down
426
+ graphs=insert(graphs,graphs[j],i-1);
427
+ graphs=delete(graphs,j+1);
428
+ totmult=insert(totmult,totmult[j],i-1);
429
+ totmult=delete(totmult,j+1);
430
+ multipl=insert(multipl,multipl[j],i-1);
431
+ multipl=delete(multipl,j+1);
432
+ contact=move_row_col(contact,i,j);
433
+ }
434
+ if (j<r) // There are still some C_j against which C_i has to be tested.
435
+ {
436
+ j++;
437
+ }
438
+ else // Now C_i has been tested against all C_j, and we may continue with C_i+1.
439
+ {
440
+ j=i+2;
441
+ i=i+1;
442
+ }
443
+ }
444
+ // Here we adjust the weights of the strict transforms in the graphs!!!
445
+ for (i=1;i<=size(graphs);i++)
446
+ {
447
+ graphs[i][nrows(graphs[i]),ncols(graphs[i])]=-i;
448
+ }
449
+ /////////////////////////////////////////////////////////////////////////////////////
450
+ // Glue the graphs together.
451
+ //////////////////////////////////////////////////////////////////////////////
452
+ ///////////////////////////////////////////////////////////////////////////////////
453
+ intmat rgraph=graphs[1]; // keeps the resolution graph
454
+ intmat rtm=intmat(totmult[1],nrows(rgraph),1); // keeps the tot.mult. at the vertices of the graph as rows
455
+ intmat rmt=intmat(multipl[1],nrows(rgraph),1); // keeps the mult. at the vertices of the graph as rows
456
+ intvec stricttransforms=0,ncols(rgraph); // keeps the position of the ith strict
457
+ // transform in rgraph at position i+1 !!!
458
+ intvec k,kp,p,q,o; // highest contact numbers, num. of branch with hgt contact, separation points
459
+ int maxc,maxcp;
460
+ for (i=2;i<=r;i++)
461
+ {
462
+ //////////////////////////////////////////////////////////////////////////////////
463
+ // Find j<i minimal s.t. contact[i,j] is maximal.
464
+ maxcp=i;
465
+ for (j=1;j<i;j++)
466
+ {
467
+ if (contact[i,j]>contact[i,maxcp]){maxcp=j;}
468
+ }
469
+ kp[i]=maxcp; // the j such that C_i has its maximal contact to C_j
470
+ k[i]=contact[i,maxcp]; // the maximal contact of C_i with C_1,...,C_i-1
471
+ ///////////////////////////////////////////////////////////////////////////////////
472
+ // Find in the graph of C_1,...,C_i-1 the points p of wgt k and q of wgt k-1
473
+ // connected to C_maxcp.
474
+ // Since non of C_j for j<maxcp has contact k with C_i, the point p lies in
475
+ // the remaining part of the graph of C_maxcp.
476
+ s=rgraph[stricttransforms[maxcp]+1,stricttransforms[maxcp]+1];
477
+ p[i]=stricttransforms[maxcp]+1+k[i]-s; // pt. to which reduced subgraph of C_i is glued
478
+ // If s<k[i], then q also lies in this part, otherwise it lies in the remaining part
479
+ // of the graph of the C_j to which C_maxcp is connected, i.e. j=kp[maxcp], since
480
+ // the contact of C_i and of C_maxcp to this C_j is strictly less than k.
481
+ // If s=k[i]=1, then p=1 and there is no q! We may thus set q=0.
482
+ if ((s<k[i]) or ((s==k[i]) and (s==1))) // i.e. q is on the same subgraph as p, or q does not exist
483
+ {
484
+ q[i]=p[i]-1;
485
+ }
486
+ else // i.e. q is on the subgraph to which the subgraph of p has been glued
487
+ {
488
+ s=rgraph[stricttransforms[kp[maxcp]]+1,stricttransforms[kp[maxcp]]+1];
489
+ q[i]=stricttransforms[kp[maxcp]]+k[i]-s;
490
+ }
491
+ //////////////////////////////////////////////////////////////////////////////////////
492
+ // Reduce the graph of C_i and add it to the graph of C_1,...,C_i-1.
493
+ gr=graphs[i];
494
+ s=nrows(rgraph);
495
+ // Delete in the graph of C_i everything of weight <=k.
496
+ gr_red=intmat(intvec(gr[k[i]+1..nrows(gr),k[i]+1..ncols(gr)]),nrows(gr)-k[i],ncols(gr)-k[i]);
497
+ // Add this part to the graph of C_1,...,C_i-1.
498
+ rgraph=addmat(rgraph,gr_red);
499
+ /////////////////////////////////////////////////////////////////////////////////////
500
+ // Connect the two parts of the graph.
501
+ /////////////////////////////////////////////////////////////////////////////////////
502
+ // Connect the points connected to the point of wgt k in the graph of C_i to p[i].
503
+ for (j=k[i]+1;j<=ncols(gr);j++)
504
+ {
505
+ if(gr[k[i],j]==1)
506
+ {
507
+ rgraph[s+j-k[i],p[i]]=1;
508
+ rgraph[p[i],s+j-k[i]]=1;
509
+ }
510
+ }
511
+ // If pt. of wgt k is not connected to pt of wgt k-1 in graph of C_i, then points
512
+ // connected to the one of wgt k-1 have to be connected to q[i].
513
+ if (k[i]>1)
514
+ {
515
+ if (gr[k[i],k[i]-1]!=1)
516
+ {
517
+ for (j=k[i]+1;j<=ncols(gr);j++)
518
+ {
519
+ if(gr[k[i]-1,j]==1)
520
+ {
521
+ rgraph[s+j-k[i],q[i]]=1;
522
+ rgraph[q[i],s+j-k[i]]=1;
523
+ }
524
+ }
525
+ // Cut the connection from p[i] to q[i].
526
+ rgraph[p[i],q[i]]=0;
527
+ rgraph[q[i],p[i]]=0;
528
+ }
529
+ }
530
+ stricttransforms[i+1]=ncols(rgraph);
531
+ ////////////////////////////////////////////////////////////////////////////////
532
+ // Adjust the total multiplicities
533
+ ////////////////////////////////////////////////////////////////////////////////
534
+ // Add the total multiplicities for the added subgraph to rtm
535
+ tm=totmult[i];
536
+ mt=multipl[i];
537
+ if (k[i]<size(tm)) // if the reduced subgraph of C_i has more than one point
538
+ {
539
+ rtm=addmat(rtm,intmat(intvec(tm[k[i]+1..size(tm)]),nrows(gr_red),1));
540
+ rmt=addmat(rmt,intmat(intvec(mt[k[i]+1..size(mt)]),nrows(gr_red),1));
541
+ }
542
+ else // if the reduced subgraph of C_i consists only of the strict transform
543
+ {
544
+ rtm=addmat(rtm,0);
545
+ rmt=addmat(rmt,0);
546
+ }
547
+ // Adjust the total multiplicities at the places where the subgraph has been glued.
548
+ e=k[i]; // the highest weight of a point that has not yet been assigned its tot. mult.
549
+ while(e>=1)
550
+ {
551
+ s=stricttransforms[maxcp]+1; // Line in the graph of the start. pt. of the subgraph of C_maxcp.
552
+ for (j=rgraph[s,s];j<=e;j++) // Adjust the multiplicities.
553
+ {
554
+ rtm[s+j-rgraph[s,s],i]=tm[j];
555
+ rmt[s+j-rgraph[s,s],i]=mt[j];
556
+ }
557
+ maxcp=kp[maxcp]; // To which subgraph has the subgraph of C_maxcp been glued?
558
+ e=rgraph[s,s]-1; // What is the highest weight of a pt. that has not yet been assigned its tot.mult.?
559
+ }
560
+ e=nrows(rtm); // Number of rows in the matrix of totalmultiplicities.
561
+ // The total multiplicities of the C_s for s=1,...,i-1 along the exceptional divisors
562
+ // which are introduced after the strict transform of C_s has separated (i.e. the entries
563
+ // in rows stricttransform[i]+1,...,stricttransform[i+1]-1 in the s-th column of the matrix
564
+ // of total multiplicities still have to be calculated.
565
+ for (s=1;s<i;s++)
566
+ {
567
+ rtm[1..e,s]=adjust_tot_mult(intvec(rtm[1..e,i]),intvec(rtm[1..e,s]),intvec(rmt[1..e,i]),intvec(rmt[1..e,s]),p,q,stricttransforms,i);
568
+ }
569
+ // The total multiplicities of the C_i along the exceptional divisors
570
+ // which are introduced for the sake of C_s, s=1,...,i-1, after the strict transform
571
+ // of C_i has separated (i.e. the entries in rows stricttransform[s]+1,...,stricttransform[s+1]-1
572
+ // in the i-th column of the matrix of total multiplicities still have to be calculated.
573
+ for (s=1;s<i;s++)
574
+ {
575
+ rtm[1..e,i]=adjust_tot_mult(intvec(rtm[1..e,s]),intvec(rtm[1..e,i]),intvec(rmt[1..e,s]),intvec(rmt[1..e,i]),p,q,stricttransforms,s);
576
+ }
577
+ }
578
+ if (inputispoly==1) // if the input was a polynomial the ordering of the branches is fine
579
+ {
580
+ list result=rgraph,rtm,rmt;
581
+ return(result);
582
+ }
583
+ else // reorder the branches according to the ordering of the input
584
+ {
585
+ // reordered total multiplicities, multiplicities and resolution graph
586
+ intmat rtmro[nrows(rtm)][ncols(rtm)];
587
+ intmat rmtro[nrows(rmt)][ncols(rmt)];
588
+ intmat rgraphro=rgraph;
589
+ for (i=1;i<=r;i++)
590
+ {
591
+ rtmro[1..nrows(rtm),newpos[i]]=rtm[1..nrows(rtm),i];
592
+ rmtro[1..nrows(rmt),newpos[i]]=rmt[1..nrows(rmt),i];
593
+ for (j=1;j<=nrows(rgraph);j++)
594
+ {
595
+ if (rgraph[j,j]==-i)
596
+ {
597
+ rgraphro[j,j]=-newpos[i];
598
+ }
599
+ }
600
+ }
601
+ list result=rgraphro,rtmro,rmtro;
602
+ return(result);
603
+ }
604
+ }
605
+ example
606
+ {
607
+ "EXAMPLE:";
608
+ echo=2;
609
+ ring r=0,(x,y),ls;
610
+ poly f1=(y2-x3)^2-4x5y-x7;
611
+ poly f2=y2-x3;
612
+ poly f3=y3-x2;
613
+ totalmultiplicities(f1*f2*f3);
614
+ }
615
+
616
+
617
+
618
+ proc alexanderpolynomial (def INPUT)
619
+ "USAGE: alexanderpolynomial(INPUT); INPUT poly or list
620
+ ASSUME: INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
621
+ or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
622
+ the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
623
+ @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
624
+ the contact matrix and a list of integer vectors with the characteristic exponents
625
+ of the branches of a plane curve singularity, or an integer vector containing the
626
+ characteristic exponents of an irreducible plane curve singularity.
627
+ CREATE: a ring with variables t, t(1), ..., t(r) (where r is the number of branches of
628
+ the plane curve singularity f defined by INPUT) and ordering ls over the
629
+ ground field of the basering. @*
630
+ Moreover, the ring contains the Alexander polynomial of f in variables t(1), ..., t(r)
631
+ (@code{alexpoly}), the zeta function of the monodromy operator of f in the variable t
632
+ (@code{zeta_monodromy}), and a list containing the factors of the Alexander
633
+ polynomial with multiplicities (@code{alexfactors}).
634
+ RETURN: a list, say @code{ALEX}, where @code{ALEX[1]} is the created ring
635
+ NOTE: to use the ring type: @code{def ALEXring=ALEX[i]; setring ALEXring;}.
636
+ @*
637
+ Alternatively you may use the procedure sethnering and type: sethnering(ALEX,\"ALEXring\");
638
+ @*
639
+ To access the Alexander polynomial resp. the zeta function resp. the
640
+ factors of the Alexander polynomial type: @code{alexpoly} resp. @code{zeta_monodromy}
641
+ resp. @code{alexfactors}.@*
642
+ In case the Hamburger-Noether expansion of the curve f is needed
643
+ for other purposes as well it is better to calculate this first
644
+ with the aid of @code{hnexpansion} and use it as input instead of
645
+ the polynomial itself.
646
+ @*
647
+ If you are not sure whether the INPUT polynomial is reduced or not, use
648
+ @code{squarefree(INPUT)} as input instead.
649
+ SEE ALSO: resolutiongraph, totalmultiplicities
650
+ EXAMPLE: example alexanderpolynomial; shows an example
651
+ "
652
+ {
653
+ // Get the resolution graph and the total multiplicities.
654
+ list gr_tm=totalmultiplicities(INPUT);
655
+ intmat gr=gr_tm[1];
656
+ intmat tm=gr_tm[2];
657
+ int r=ncols(tm);
658
+ int e=ncols(gr);
659
+ // Define the Ring for the Alexander Polynomial and the Zeta Function of the Monodromy.
660
+ list l2 = "t";
661
+ for (int ii = 1; ii <= r; ii++)
662
+ {
663
+ l2[ii+1] = "t("+string(ii)+")";
664
+ }
665
+ ring ALEXring = create_ring(ring_list(basering)[1], l2, "dp", "no_minpoly");
666
+ poly hilfspoly=1;
667
+ poly alexnumerator=1; // numerator of the Alexander polynomial
668
+ poly alexdenominator=1; // denominator of the Alexander polynomial
669
+ list alexfactors; // the factors of the Alexanderpolynomial with multiplicities
670
+ list alexfactor;
671
+ int chi=2;
672
+ int i,j,k;
673
+ int s=1;
674
+ // Consider every vertex of the resolution graph.
675
+ for (i=1;i<=e;i++)
676
+ {
677
+ if (gr[i,i]>0) // If it belongs to an exceptional curve.
678
+ {
679
+ for (j=1;j<=e;j++) // Calculate the Euler characteristic of the smooth locus of the exc. curve.
680
+ {
681
+ if ((gr[i,j]==1) and (i!=j))
682
+ {
683
+ chi=chi-1;
684
+ }
685
+ }
686
+ if (chi!=0) // If the Euler characteristik is not zero, then it gives a factor in the AP.
687
+ {
688
+ for (k=1;k<=r;k++)
689
+ {
690
+ hilfspoly=hilfspoly*t(k)^tm[i,k];
691
+ }
692
+ hilfspoly=1-hilfspoly;
693
+ if (chi<0) // ... either in the numerator ...
694
+ {
695
+ alexnumerator=alexnumerator * hilfspoly^-chi;
696
+ }
697
+ else // ... or in the denominator.
698
+ {
699
+ alexdenominator=alexdenominator * hilfspoly^chi;
700
+ }
701
+ alexfactor=hilfspoly,-chi;
702
+ alexfactors[s]=alexfactor;
703
+ s++;
704
+ }
705
+ chi=2;
706
+ hilfspoly=1;
707
+ }
708
+ }
709
+ // Calculate the Alexander Polynomial.
710
+ if (ncols(tm)==1) // If we have only one branch, then the numerator has to be multiplied by 1-t.
711
+ {
712
+ alexnumerator=alexnumerator*(1-t(1));
713
+ alexfactor=1-t(1),1;
714
+ alexfactors[size(alexfactors)+1]=alexfactor;
715
+ }
716
+ poly alexpoly=alexnumerator / alexdenominator;
717
+ // Calculate the Zeta Function of the Monodromy Operator.
718
+ poly zeta_monodromy=alexpoly;
719
+ for (i=1;i<=r;i++)
720
+ {
721
+ zeta_monodromy=subst(zeta_monodromy,t(i),t);
722
+ }
723
+ export zeta_monodromy;
724
+ export alexnumerator;
725
+ export alexdenominator;
726
+ export alexfactors;
727
+ export alexpoly;
728
+ list ALEX=ALEXring;
729
+ return(ALEX);
730
+ }
731
+ example
732
+ {
733
+ "EXAMPLE:";
734
+ echo=2;
735
+ ring r=0,(x,y),ls;
736
+ poly f1=(y2-x3)^2-4x5y-x7;
737
+ poly f2=y2-x3;
738
+ poly f3=y3-x2;
739
+ list ALEX=alexanderpolynomial(f1*f2*f3);
740
+ def ALEXring=ALEX[1];
741
+ setring ALEXring;
742
+ alexfactors;
743
+ alexpoly;
744
+ zeta_monodromy;
745
+ }
746
+
747
+ proc semigroup (def INPUT)
748
+ "USAGE: semigroup(INPUT); INPUT poly or list
749
+ ASSUME: INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
750
+ or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
751
+ the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
752
+ @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
753
+ the contact matrix and a list of integer vectors with the characteristic exponents
754
+ of the branches of a plane curve singularity, or an integer vector containing
755
+ the characteristic exponents of an irreducible plane curve singularity.
756
+ RETURN: a list with three entries. The first and the second are lists @code{v_1,...,v_s}
757
+ and @code{w_1,...,w_r} respectively of integer vectors such that the semigroup
758
+ of the plane curve defined by the INPUT is generated by the vectors
759
+ @code{v_1,...,v_s,w_1+k*e_1,...,w_r+k*e_r}, where e_i denotes the i-th standard
760
+ basis vector and k runs through all non-negative integers. The third entry is the conductor
761
+ of the plane curve singularity. Note that r is the number of branches of the plane curve
762
+ singularity and integer vectors thus have size r.
763
+ NOTE: If the output is zero this means that the curve has one branch and is regular.
764
+ In the reducible case the set of generators may not be minimal.
765
+ @*
766
+ If you are not sure whether the INPUT polynomial is reduced or not, use
767
+ @code{squarefree(INPUT)} as input instead.
768
+ SEE ALSO: resolutiongraph, totalmultiplicities
769
+ EXAMPLE: example semigroup; shows an example
770
+ "
771
+ {
772
+ ////////////////////////////////////////////////////////////////////////////////////////
773
+ // Uses the algorithm in [CDG99] A. Campillo, F. Delgado, S.M. Gusein-Zade, On the
774
+ // generators of the semigroup of a plane curve singularity,
775
+ // J. London Math. Soc. (2) 60 (1999), 420-430.
776
+ ////////////////////////////////////////////////////////////////////////////////////////
777
+ intvec conductor; // conductor of the singularity
778
+ list charexp; // characteristic exponents of the singularity
779
+ int i,j;
780
+ /////////////////////////////////////////////////////////////////////////////////
781
+ // Decide, which kind of input we have, and define the contact matrix
782
+ /////////////////////////////////////////////////////////////////////////////////
783
+ // Input: a polynomial defining a plane curve singularity.
784
+ //////////////////////////////////////////////////////////////////////////////
785
+ if (typeof(INPUT)=="poly")
786
+ {
787
+ /*
788
+ poly FFF=squarefree(INPUT);
789
+ if ( deg(FFF)!=deg(INPUT) )
790
+ {
791
+ dbprint(printlevel-voice+3,"// input polynomial was not reduced");
792
+ dbprint(printlevel-voice+3,"// we continue with its reduction");
793
+ }
794
+ list I@N@V=invariants(FFF);
795
+ */
796
+ list I@N@V=invariants(INPUT);
797
+ }
798
+ else
799
+ {
800
+ ///////////////////////////////////////////////////////////////////////////////////
801
+ // Input: the vector of characteristic exponents of an irreducible plane curve
802
+ ///////////////////////////////////////////////////////////////////////////////////
803
+ if (typeof(INPUT)=="intvec")
804
+ {
805
+ // Calculate the semigroup and the conductor directly.
806
+ conductor[1]=charexp2conductor(INPUT);
807
+ intvec gener=charexp2generators(INPUT);
808
+ list genera;
809
+ for (i=1;i<=size(gener);i++)
810
+ {
811
+ genera[i]=gener[i];
812
+ }
813
+ return(list(genera,list(),conductor));
814
+ }
815
+ else
816
+ {
817
+ if (typeof(INPUT)=="list")
818
+ {
819
+ /////////////////////////////////////////////////////////////////////////////////
820
+ // Input: intersection-matrix and characteristic exponents.
821
+ //////////////////////////////////////////////////////////////////////////////
822
+ if (typeof(INPUT[1])=="intmat")
823
+ {
824
+ intmat contact=INPUT[1];
825
+ charexp=INPUT[2];
826
+ int n=ncols(contact); // to know how many branches we have
827
+ if (n==1) // Only one branch!
828
+ {
829
+ return(semigroup(charexp[1]));
830
+ }
831
+ intmat intersecmult=charexp2inter(contact,charexp);
832
+ for(i=1;i<=ncols(contact);i++)
833
+ {
834
+ conductor[i]=charexp2conductor(charexp[i]);//list with the characteristic exponents
835
+ }
836
+ }
837
+ else
838
+ {
839
+ /////////////////////////////////////////////////////////////////////////////////
840
+ // Input: output of hnexpansion or hne in the ring created by hnexpansion
841
+ //////////////////////////////////////////////////////////////////////////////
842
+ if ((typeof(INPUT[1])=="ring") or (typeof(INPUT[1])=="list"))
843
+ {
844
+ list I@N@V=invariants(INPUT);
845
+ }
846
+ else
847
+ {
848
+ ////////////////////////////////////////////////////////////////////////////////////
849
+ // Input: output of develop or extdevelop -- irreducible plane curve singularity
850
+ ////////////////////////////////////////////////////////////////////////////////////
851
+ if (typeof(INPUT[1])=="matrix")
852
+ {
853
+ return(semigroup(invariants(INPUT)[1]));
854
+ }
855
+ else
856
+ {
857
+ ERROR("The input is invalid!");
858
+ }
859
+ }
860
+ }
861
+ }
862
+ else
863
+ {
864
+ ERROR("The input is invalid!");
865
+ }
866
+ }
867
+ }
868
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
869
+ // If the input was a poly or an HN-Expansion, then calculate the contact matrix and char.exponents.
870
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
871
+ if (defined(I@N@V))
872
+ {
873
+ int n =size(I@N@V)-1;// number of branches
874
+ // If the singularity is irreducible, then we calculate the semigroup directly.
875
+ if (n==1)
876
+ {
877
+ return(semigroup(I@N@V[1][1]));
878
+ }
879
+ // If the singularity is not irreducible, then we go on.
880
+ intmat contact=I@N@V[size(I@N@V)][1]; // contact matrix
881
+ intmat intersecmult=I@N@V[size(I@N@V)][2]; // intersection multiplicities
882
+ for(i=1;i<=n;i++)
883
+ {
884
+ conductor[i]=I@N@V[i][5];
885
+ charexp[i]=I@N@V[i][1];
886
+ }
887
+ }
888
+ /////////////////////////////////////////////////////////////////////////////////////
889
+ // If we have come so far, the curve is reducible!
890
+ /////////////////////////////////////////////////////////////////////////////////////
891
+ // Compute the conductor of the curve.
892
+ /////////////////////////////////////////////////////////////////////////////////////
893
+ for(i=1;i<=size(conductor);i++)
894
+ {
895
+ for(j=1;j<=size(conductor);j++)
896
+ {
897
+ conductor[i]=conductor[i]+intersecmult[i,j];
898
+ }
899
+ }
900
+ /////////////////////////////////////////////////////////////////////////////////////
901
+ /// The total multiplicity vectors of the exceptional divisors generate the semigroup,
902
+ /// however, this system of generators is not minimal. Theorem 2 in [CDG99] leads
903
+ /// to the following algorithm for minimizing the set of generators.
904
+ /////////////////////////////////////////////////////////////////////////////////////
905
+ list resgr_totmult=totalmultiplicities(list(contact,charexp)); // resolution graph and tot. mult.
906
+ intmat resgr=resgr_totmult[1]; // resolution graph
907
+ intmat totmult=resgr_totmult[2]; // total multiplicities
908
+ list conpts; // ith entry = points to which i is connected and their weights
909
+ intvec series; // ith entry = row in totmult which corresponds to w_i
910
+ intvec deadarc; // Star point and the point connected to the star point of a dead arc.
911
+ list deadarcs; // Saves deadarc for all dead arcs.
912
+ int stop,ctp,ctpstop;
913
+ list ordinary_generators, series_generators; // the v_i and the w_i from the description
914
+ // Find for each branch of the curve all the points in the graph to which it is connected
915
+ // and save the numbers of the corresponding rows in the graph as well as the weight of the point.
916
+ for (i=1;i<=ncols(resgr);i++)
917
+ {
918
+ conpts[i]=find_connection_points(resgr,i);
919
+ }
920
+ //////////////////////////////////////////////////////////////////////////////////
921
+ // Check for each point in the graph, whether it contributes to the semigroup.
922
+ // If it does not contribute to the semigroup, then set the weight of the point
923
+ // to zero, i.e. resgr[i,i]=0. Note that the vertex 1 always contributes!
924
+ //////////////////////////////////////////////////////////////////////////////////
925
+ // Find first all the points corresponding to the branches and the end points of dead arcs.
926
+ // The points to which the branch k is connected contributes to w_k. The end points of
927
+ // dead arcs contribute to the v_i, while the remaining points of the dead arcs are to be removed.
928
+ j=1; // Counter for dead arcs - the star points of dead arcs have to be saved for future use.
929
+ for (i=2;i<=ncols(resgr);i++)
930
+ {
931
+ // The end points of dead arcs and the end points corresponding to the branches are
932
+ // recognized by the fact that they are only connected to one other point.
933
+ if (size(conpts[i][1])==1) // row i in the graph corresponds to an end point
934
+ {
935
+ // For an end point corresponding to a branch k the last point E_alpha(k), to which it is
936
+ // connected, contributes to the generator w_k.
937
+ if (resgr[i,i]<0)
938
+ {
939
+ series[-resgr[i,i]]=conpts[i][1][1]; // Find E_alpha(k), where k=-resgr[i,i]
940
+ ctp=conpts[i][1][1];
941
+ resgr[ctp,ctp]=0; // So E_alph(k) does not contribute to the v_i.
942
+ }
943
+ // For an end point of a dead arc the end point contributes, but all the other points
944
+ // of the dead arc - including the star point = separation pt of the dead arc - do not contribute.
945
+ if (resgr[i,i]>0)
946
+ {
947
+ stop=0; // Stop checks whether the star point of the dead arc has been reached.
948
+ ctp=conpts[i][1][1]; // The point to which the end point is connected.
949
+ // Set the weights of all the other points in the dead arc to zero.
950
+ while ((stop==0) and (ctp!=1)) // If the star point or the vertex 1 has been reached, stop.
951
+ {
952
+ deadarc[2]=i; // i might be the point connected to the star point of the dead arc.
953
+ resgr[ctp,ctp]=0;
954
+ if (size(conpts[ctp][1])==2) // If ctp was an ordinary vertex, we go on.
955
+ {
956
+ deadarc[2]=ctp; // ctp might be the point connected to the star point of the dead arc.
957
+ ctp=conpts[ctp][1][2]; // This is the second point (of higher weight) to which ctp is connected.
958
+ }
959
+ else // If ctp is the star point, we stop.
960
+ {
961
+ deadarc[1]=ctp; // Star point of this dead arc.
962
+ deadarcs[j]=deadarc; // Save the j-th dead arc.
963
+ j++;
964
+ stop=1;
965
+ }
966
+ }
967
+ }
968
+ }
969
+ }
970
+ //////////////////////////////////////////////////////////////////////////////////
971
+ // Points (!=1) which are on the geodesics of every branch don't contribute.
972
+ // (The geodesic of a branch is the shortest connection of the strict transform to 1 in the graph.)
973
+ stop=0; // Checks whether the points on all geodesics have been found.
974
+ ctp=1; // Point (=row in resgr) to be considered.
975
+ int prev_ctp; // Previous point in the graph, to which ctp was connected.
976
+ int dead_arc_ctp; // If ctp is the star pt of a dead arc, this is the connection pt of ctp in the d.a.
977
+ int dastarptcheck; // Checks whether a point is a star point of a dead arc.
978
+ if (size(conpts[1][1])>=2) // The graphs separate already at point 1.
979
+ {
980
+ stop=1;
981
+ }
982
+ else // The graphs do not separate at point 1.
983
+ {
984
+ prev_ctp=1;
985
+ ctp=conpts[1][1][1]; // Next point to be considered.
986
+ }
987
+ // Pass on along the graph until we reach the first point where some branches separate.
988
+ while (stop==0)
989
+ {
990
+ if (size(conpts[ctp][1])==2) // Point ctp is connected to 2 other points, hence is a normal vertex.
991
+ {
992
+ resgr[ctp,ctp]=0; // Point ctp is a normal vertex.
993
+ prev_ctp=ctp; // Save the position of ctp for future use.
994
+ ctp=conpts[ctp][1][2]; // Next point to which ctp is connected.
995
+ }
996
+ if (size(conpts[ctp][1])>3) // More than three points are connected to ctp.
997
+ {
998
+ resgr[ctp,ctp]=0;
999
+ stop=1; // The graphs separate at point ctp.
1000
+ }
1001
+ if (size(conpts[ctp][1])==3) // At ctp a dead arc might depart or some branch(es)!
1002
+ { // If a dead arc departs, then the branches stay together.
1003
+ resgr[ctp,ctp]=0;
1004
+ // Check if a dead arc departs at point ctp (i.e. if ctp is the star point of a dead arc),
1005
+ // then the branches do not separate at ctp.
1006
+ dastarptcheck=0;
1007
+ i=1;
1008
+ while ((i<=size(deadarcs)) and (dastarptcheck==0))
1009
+ {
1010
+ if (ctp==deadarcs[i][1]) // ctp is the star point of a dead arc.
1011
+ {
1012
+ dastarptcheck=1;
1013
+ dead_arc_ctp=deadarcs[i][2]; // The point in the dead arc to which ctp is connected.
1014
+ }
1015
+ i++;
1016
+ }
1017
+ if (dastarptcheck==0) // ctp is not the star point of a dead arc, hence the graphs separate at ctp.
1018
+ {
1019
+ stop=1;
1020
+ }
1021
+ else
1022
+ {
1023
+ // Set ctp to the point connected to ctp which is not in the dead arc and is not prev_ctp.
1024
+ i=1;
1025
+ ctpstop=0;
1026
+ while ((i<=3) and (ctpstop==0))
1027
+ {
1028
+ if ((conpts[ctp][1][i]!=prev_ctp) and (conpts[ctp][1][i]!=dead_arc_ctp))
1029
+ {
1030
+ prev_ctp=ctp;
1031
+ ctp=conpts[ctp][1][i];
1032
+ ctpstop=1;
1033
+ }
1034
+ i++;
1035
+ }
1036
+ }
1037
+ }
1038
+ }
1039
+ /////////////////////////////////////////////////////////////////////////////////////////////
1040
+ // Collect the generators v_j by checking which points in the graph still have
1041
+ // a positive weight! These points contribute their total multiplicity vector as
1042
+ // generator v_j.
1043
+ j=1;
1044
+ for (i=1;i<=ncols(resgr);i++)
1045
+ {
1046
+ if (resgr[i,i]>0)
1047
+ {
1048
+ ordinary_generators[j]=intvec(totmult[i,1..ncols(totmult)]);
1049
+ j++;
1050
+ }
1051
+ }
1052
+ // The "exceptional" generators w_i, for which we have to include w_i+ke_i (for all k)
1053
+ // are the total multiplicity vectors of the points saved in series.
1054
+ for (i=1;i<=ncols(totmult);i++)
1055
+ {
1056
+ series_generators[i]=intvec(totmult[series[i],1..ncols(totmult)]);
1057
+ }
1058
+ return(list(ordinary_generators,series_generators,conductor));
1059
+ }
1060
+ example
1061
+ {
1062
+ "EXAMPLE:";
1063
+ echo=2;
1064
+ ring r=0,(x,y),ls;
1065
+ // Irreducible Case
1066
+ semigroup((x2-y3)^2-4x5y-x7);
1067
+ // In the irreducible case, invariants() also calculates a minimal set of
1068
+ // generators of the semigroup.
1069
+ invariants((x2-y3)^2-4x5y-x7)[1][2];
1070
+ // Reducible Case
1071
+ poly f=(y2-x3)*(y2+x3)*(y4-2x3y2-4x5y+x6-x7);
1072
+ semigroup(f);
1073
+ }
1074
+
1075
+
1076
+
1077
+ proc charexp2generators (intvec charexp)
1078
+ "USAGE: charexp2generators(v), v intvec
1079
+ ASSUME: v contains the characteristic exponents of an irreducible plane
1080
+ curve singularity
1081
+ RETURN: intvec, the minimal set of generators of the semigroup of the plane curve singularity
1082
+ SEE ALSO: invariants, resolutiongraph, totalmultiplicities, alexanderpolynomial
1083
+ KEYWORDS: generators; semigroup; characteristic exponents; topological invariants
1084
+ EXAMPLE: example charexp2generators; shows an example"
1085
+ {
1086
+ int end=size(charexp);
1087
+ // If the singularity is smooth!
1088
+ if (end==1)
1089
+ {
1090
+ return(1);
1091
+ }
1092
+ int i,j;
1093
+ intvec gener;
1094
+ intvec GGT;
1095
+ for (i=1;i<=end;i++)
1096
+ {
1097
+ // Calculate the sequence of gcd's of the characteristic exponents.
1098
+ if (i==1)
1099
+ {
1100
+ GGT[1]=charexp[1];
1101
+ }
1102
+ else
1103
+ {
1104
+ GGT[i]=gcd(GGT[i-1],charexp[i]);
1105
+ }
1106
+ // Calculate the generators.
1107
+ gener[i]=charexp[i];
1108
+ for (j=2;j<=i-1;j++)
1109
+ {
1110
+ gener[i]=gener[i]+((GGT[j-1]-GGT[j]) div GGT[i-1])*charexp[j];
1111
+ }
1112
+ }
1113
+ return(gener);
1114
+ }
1115
+ example
1116
+ {
1117
+ "EXAMPLE:";
1118
+ echo=2;
1119
+ charexp2generators(intvec(28,64,66,77));
1120
+ }
1121
+
1122
+
1123
+ proc charexp2multseq (intvec charexp)
1124
+ "USAGE: charexp2multseq(v), v intvec
1125
+ ASSUME: v contains the characteristic exponents of an irreducible plane
1126
+ curve singularity
1127
+ RETURN: intvec, the multiplicity sequence of the plane curve singularity
1128
+ NOTE: If the curve singularity is smooth, then the multiplicity sequence is empty.
1129
+ This is expressed by returning zero.
1130
+ SEE ALSO: invariants, resolutiongraph, totalmultiplicities, alexanderpolynomial
1131
+ KEYWORDS: characteristic exponents; multiplicity sequence; topological invariants
1132
+ EXAMPLE: example charexp2multseq; shows an example"
1133
+ {
1134
+ int end=size(charexp);
1135
+ // If the singularity is smooth!
1136
+ if (end==1)
1137
+ {
1138
+ return(1); // ERROR: Should be 0, but for the time being, Singular returns 1.
1139
+ }
1140
+ intvec multseq=euclidseq(charexp[2],charexp[1]);
1141
+ for (int i=3;i<=end;i++)
1142
+ {
1143
+ multseq=multseq,euclidseq(charexp[i]-charexp[i-1],multseq[size(multseq)]);
1144
+ }
1145
+ return(multseq);
1146
+ }
1147
+ example
1148
+ {
1149
+ "EXAMPLE:";
1150
+ echo=2;
1151
+ charexp2multseq(intvec(28,64,66,77));
1152
+ }
1153
+
1154
+ proc multseq2charexp(def v) // Procedure written by Fernando.
1155
+ "USAGE: multseq2charexp(v), v intvec
1156
+ ASSUME: The input is an intvec, which contains the mutiplicity sequence
1157
+ of an irreducible plane curve singularity .
1158
+ RETURN: An intvec, which contains the sequence of characteristic
1159
+ exponents of the irreducible plane curve singularity defined by v.
1160
+ EXAMPLE: example multseq2charexp; shows an example.
1161
+ "
1162
+ {
1163
+ /////// Preamble which reduces the input of an intvec to /////////////
1164
+ /////// the originally assumed input of a list of intvecs /////////////
1165
+ /////// and tests the input. /////////////
1166
+ if (typeof(v)=="intvec")
1167
+ {
1168
+ list RESULT=multseq2charexp(list(v));
1169
+ return(RESULT[1]);
1170
+ }
1171
+ if (typeof(v)!="list")
1172
+ {
1173
+ ERROR("Invalid Input!");
1174
+ }
1175
+ if (typeof(v)=="list")
1176
+ {
1177
+ int TESTV;
1178
+ for (int III=1;III<=size(v);III++)
1179
+ {
1180
+ if (typeof(v[III])!="intvec")
1181
+ {
1182
+ TESTV=1;
1183
+ }
1184
+ }
1185
+ if (TESTV==1)
1186
+ {
1187
+ ERROR("Invalid Input!");
1188
+ }
1189
+ }
1190
+ ///////////////////////////////////////////////////////////
1191
+ list L=v;
1192
+ int n =size(L);
1193
+ // ///////////////////////////////////////////////////////
1194
+ // we look the size of each vector
1195
+ intvec mm;
1196
+ for(int j=1;j<=n;j++)
1197
+ {
1198
+ mm[j]=size(L[j]);
1199
+ }
1200
+ // ///////////////////////////////////////////////////////
1201
+ // we define some variables
1202
+ list LL;
1203
+ int temp, temp1,temp2;
1204
+ int ind,r,l,boolean;
1205
+ int old,new;
1206
+ int contador;
1207
+ list EUCLI,EUCLI1;
1208
+ intvec exponent,exponentes1;
1209
+ int new1,old1;
1210
+ int contador1;
1211
+ int a,b,f;
1212
+ //with the for we round each branch.
1213
+ for(int k=1;k<=n;k++)
1214
+ {
1215
+ l=1;
1216
+ old=L[k][l];
1217
+ //if the vertor has more than one element
1218
+ if(mm[k]<>1)
1219
+ {
1220
+ // ///////////////////////////////////////////////////////////////////////////////
1221
+ // the first step is special because is easy to know the two first characteristic exponents
1222
+ new=L[k][l+1];
1223
+ contador=1;
1224
+ while(old==new)//we check how many consecutives elements are equal, starting in the first.
1225
+ {
1226
+ contador=contador+1;
1227
+ old=new;
1228
+ new=L[k][contador+1];
1229
+ }
1230
+ exponent=L[k][l],contador*L[k][l]+L[k][l+contador];// those are the first two characteristic exponents.
1231
+ LL[k]=exponent;// we insert them in the final matrix
1232
+ EUCLI=euclides(LL[k][2],LL[k][1]);// compute the euclides algorithm for the two first characteristic exponents.
1233
+ temp=size(EUCLI[1]);
1234
+ // measure how many elements of the multiplicity sequence belong to the first euclidean algorithm.
1235
+ for(ind=1;ind<=temp;ind=ind+1)
1236
+ {
1237
+ l=l+EUCLI[1][ind];
1238
+ }
1239
+ l=l-1;//this is the number we are looking for.
1240
+ ///////////////////////////////////////////////////////////////
1241
+ r=1;
1242
+ //repeat the same process until the end of the multiplicity sequence.
1243
+ if(mm[k]-1>l)
1244
+ {
1245
+ while( l<mm[k]-1)
1246
+ {
1247
+ r=r+1;
1248
+ old1=L[k][l];
1249
+ new1=L[k][l+1];
1250
+ contador1=0;
1251
+ boolean=1;
1252
+ if(old1==new1)
1253
+ {
1254
+ while(old1==new1 and boolean==1)
1255
+ {
1256
+ contador1=contador1+1;
1257
+ old1=new1;
1258
+ new1=L[k][l+contador1+1];
1259
+ if(size(L[k])<=l+contador1+1)
1260
+ {
1261
+ boolean =0;
1262
+ }
1263
+ }
1264
+ }
1265
+ temp1=size(LL[k]);
1266
+ exponentes1=LL[k],LL[k][temp1]+(contador1*L[k][l])+L[k][contador1+l+1];
1267
+ LL[k]=exponentes1;
1268
+ EUCLI1=euclides(LL[k][temp1+1]-LL[k][temp1],L[k][l]);
1269
+ temp2=size(EUCLI1[1]);
1270
+ for(ind=1;ind<=temp2;ind=ind+1)
1271
+ {
1272
+ l=l+EUCLI1[1][ind];
1273
+ }
1274
+ }
1275
+ }
1276
+ }
1277
+ // if the vector has only one element then the charexp is only 1.
1278
+ else
1279
+ {
1280
+ LL[k]=1;
1281
+ }
1282
+ }
1283
+ return(LL);
1284
+ }
1285
+ example
1286
+ {
1287
+ "EXAMPLE:";echo=2;
1288
+ intvec v=2,1,1;
1289
+ multseq2charexp(v);
1290
+ intvec v1=4,2,2,1,1;
1291
+ multseq2charexp(v1);
1292
+ }
1293
+
1294
+ proc charexp2inter (intmat contact, list charexp)
1295
+ "USAGE: charexp2inter(contact,charexp), contact matrix, charexp list
1296
+ ASSUME: charexp contains the integer vectors of characteristic exponents
1297
+ of the branches of a plane curve singularity, and contact is their
1298
+ contact matrix
1299
+ RETURN: intmat, the matrix intersection multiplicities of the branches
1300
+ SEE ALSO: invariants, resolutiongraph, totalmultiplicities, semigroup
1301
+ KEYWORDS: contact matrix; characteristic exponents; intersection multiplicity; topological invariants
1302
+ EXAMPLE: example charexp2inter; shows an example"
1303
+ {
1304
+ int n=ncols(contact);
1305
+ int i,j,k;
1306
+ list multpl;
1307
+ int max=0;
1308
+ intvec helpvect;
1309
+ intmat inters[n][n];
1310
+ // Calculate the multiplicity sequences of the branches.
1311
+ for (i=1;i<=n;i++)
1312
+ {
1313
+ multpl[i]=charexp2multseq(charexp[i]);
1314
+ // Find the maximal length of a multiplicity sequence.
1315
+ if (max<size(multpl[i]))
1316
+ {
1317
+ max=size(multpl[i]);
1318
+ }
1319
+ }
1320
+ // If the contact of certain branches is higher than the maximal length of the
1321
+ // multiplicity sequence, then max should be the maximal contact!
1322
+ helpvect=max,intvec(contact);
1323
+ max=max_in_intvec(helpvect)[1];
1324
+ // Prolong them by 1s, in order to take care of higher contact.
1325
+ for (i=1;i<=n;i++)
1326
+ {
1327
+ helpvect=multpl[i];
1328
+ for (j=size(multpl[i]+1);j<=max;j++)
1329
+ {
1330
+ helpvect[j]=1;
1331
+ }
1332
+ multpl[i]=helpvect;
1333
+ }
1334
+ // Calculate the intersection numbers of the branches: for two branches f_i and f_j
1335
+ // this is the sum over mult_k(f_i)*mult_k(f_j), where k runs over all infinitely
1336
+ // near points which f_i and f_j share, i.e. from 1 to contact[i,j].
1337
+ for (i=1;i<=n;i++)
1338
+ {
1339
+ for (j=i+1;j<=n;j++)
1340
+ {
1341
+ for (k=1;k<=contact[i,j];k++)
1342
+ {
1343
+ inters[i,j]=inters[i,j]+multpl[i][k]*multpl[j][k];
1344
+ }
1345
+ inters[j,i]=inters[i,j];
1346
+ }
1347
+ }
1348
+ return(inters);
1349
+ }
1350
+ example
1351
+ {
1352
+ "EXAMPLE:";echo=2;
1353
+ ring r=0,(x,y),ds;
1354
+ list INV=invariants((x2-y3)*(x3-y2)*((x2-y3)^2-4x5y-x7));
1355
+ intmat contact=INV[4][1];
1356
+ list charexp=INV[1][1],INV[2][1],INV[3][1];
1357
+ // The intersection matrix is INV[4][2].
1358
+ print(INV[4][2]);
1359
+ // And it is calculated as ...
1360
+ print(charexp2inter(contact,charexp));
1361
+ }
1362
+
1363
+
1364
+ proc charexp2conductor(intvec B) // Procedure written by Fernando
1365
+ "USAGE: charexp2conductor(v), v intvec
1366
+ ASSUME: v contains the characteristic exponents of an irreducible plane
1367
+ curve singularity
1368
+ RETURN: int, the conductor of the plane curve singularity
1369
+ NOTE: If the curve singularity is smooth, the conductor is zero.
1370
+ SEE ALSO: invariants, resolutiongraph, totalmultiplicities, semigroup
1371
+ KEYWORDS: conductor; characteristic exponents; multiplicity sequence; topological invariants
1372
+ EXAMPLE: example charexp2conductor; shows an example"
1373
+ {
1374
+ intvec E;
1375
+ int i,conductor;
1376
+ E[1]=B[1];
1377
+ for(i=2;i<=size(B);i++)
1378
+ {
1379
+ E[i]=gcd(E[i-1],B[i]);
1380
+ }
1381
+ conductor=1-E[1];
1382
+ for(i=2;i<=size(B);i++)
1383
+ {
1384
+ conductor=conductor+(B[i]*(E[i-1]-E[i]));
1385
+ }
1386
+ return(conductor);
1387
+ }
1388
+ example
1389
+ {
1390
+ "EXAMPLE:";
1391
+ echo=2;
1392
+ charexp2conductor(intvec(2,3)); // A1-Singularity
1393
+ charexp2conductor(intvec(28,64,66,77));
1394
+ }
1395
+
1396
+
1397
+ proc charexp2poly(intvec v, vector a) // Procedure written by Fernando.
1398
+ "USAGE: charexp2poly(v,a); intvec v, vector a.
1399
+ ASSUME: v an intvec containing the characterictic exponents of an irreducible plane curve singularity.
1400
+ a a vector containing the coefficients of a parametrization given by x(t)=x^v[1],
1401
+ y(t)=a(1)t^v[2]+...+a[n-1]t^v[n], i.e. the entries of a are of type number.
1402
+ RETURN: A polynomial f in the first two variables of the basering, such that f defines an
1403
+ irreducible plane curve singularity with characteristic exponents v.
1404
+ NOTE: The entries in a should be of type number and the vector v should be the sequence of
1405
+ characteristic exponents of an irreducible plane curve singularity in order to
1406
+ get a sensible result,
1407
+ SEE ALSO: charexp2multseq, multseq2charexp.
1408
+ EXAMPLE: example charexp2poly; shows an example
1409
+ "
1410
+ {
1411
+ int n=size(v);
1412
+ vector expo;
1413
+ int i,j,s;
1414
+ for(i=1;i<=v[1];i++)
1415
+ {
1416
+ expo[i]=0;//initialize to 0.
1417
+ }
1418
+ for(i=2;i<=n;i++)
1419
+ {
1420
+ s=v[i] mod v[1];//calculate the position.
1421
+ expo=expo-a[i-1]*var(1)^((v[i]-s) div v[1])*gen(s+1);//save in expo -var(1) to the power the corresponding
1422
+ //but only in the right positions
1423
+ }
1424
+ matrix M[v[1]][v[1]];
1425
+ //construct the matrix that generates the polynomial
1426
+ for(i=1;i<=v[1];i++)
1427
+ {
1428
+ M[i,i]=var(2)+expo[1];//The diagonal
1429
+ for(j=1;j<=v[1]-i;j++)
1430
+ {
1431
+ M[j,j+i]=expo[i+1];//over diagonal
1432
+ }
1433
+ for(j=1;j<=v[1]-i;j++)
1434
+ {
1435
+ M[j+i,j]=var(1)*expo[1+v[1]-i];//under diagonal
1436
+ }
1437
+ }
1438
+ //the poynomial is the determinant of the matrix
1439
+ poly irredpoly=det(M);
1440
+ return(irredpoly)
1441
+ }
1442
+ example
1443
+ {
1444
+ "EXAMPLE:";echo=2;
1445
+ ring r=0,(x,y),dp;
1446
+ intvec v=8,12,14,17;
1447
+ vector a=[1,1,1];
1448
+ poly f=charexp2poly(v,a);
1449
+ f;
1450
+ invariants(f)[1][1]; // The characteristic exponents of f.
1451
+ }
1452
+
1453
+ proc tau_es2 (def INPUT, list #)
1454
+ "USAGE: tau_es2(INPUT); INPUT poly or list
1455
+ ASSUME: INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
1456
+ or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
1457
+ the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
1458
+ @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
1459
+ the contact matrix and a list of integer vectors with the characteristic exponents
1460
+ of the branches of a plane curve singularity, or an integer vector containing the
1461
+ characteristic exponents of an irreducible plane curve singularity.
1462
+ RETURN: int, the equisingular Tjurina number of f, i. e. the codimension of the mu-constant
1463
+ stratum in the semiuniversal deformation of f, where mu is the Milnor number of f.
1464
+ NOTE: The equisingular Tjurina number is calculated with the aid of a Hamburger-Noether
1465
+ expansion, which is the hard part of the calculation.
1466
+ In case the Hamburger-Noether expansion of the curve f is needed
1467
+ for other purposes as well it is better to calculate this first
1468
+ with the aid of @code{hnexpansion} and use it as input instead of
1469
+ the polynomial itself.
1470
+ @*
1471
+ If you are not sure whether the INPUT polynomial is reduced or not, use
1472
+ @code{squarefree(INPUT)} as input instead.
1473
+ SEE ALSO: tau_es, develop, hnexpansion, totalmultiplicities, equising_lib
1474
+ EXAMPLE: example tau_es2; shows an example
1475
+ "
1476
+ {
1477
+ // If the input is a weighted homogeneous polynomial, then use a direct algorithm to
1478
+ // calculate the equisingular Tjurina number, by calcuclating a K-basis of the
1479
+ // Tjurina algebra and omitting those elements with weighted degree at least the
1480
+ // weighted degree of the polynomial. -- If an additional input # is given (which is
1481
+ // not just the number 1 !!!), the procedure always uses the recursive algorithm.
1482
+ if ((typeof(INPUT)=="poly") and (size(#)==0))
1483
+ {
1484
+ if (qhweight(INPUT)[1]!=0)
1485
+ {
1486
+ /*
1487
+ poly f=squarefree(INPUT);
1488
+ if ( deg(f)!=deg(INPUT) )
1489
+ {
1490
+ dbprint(printlevel-voice+3,"// input polynomial was not reduced");
1491
+ dbprint(printlevel-voice+3,"// we continue with its reduction");
1492
+ }
1493
+ return(tau_es_qh(f));
1494
+ */
1495
+ return(tau_es_qh(INPUT));
1496
+ }
1497
+ }
1498
+ // Else apply the recursive algorithm from Eugenii Shustin, On Manifolds of Singular
1499
+ // Algebraic Curves, Selecta Math. Sov. Vol 10, No. 1 (1991), p. 31.
1500
+ int i,j,k; // Laufvariablen
1501
+ int tau,tau_i; // Variable for es-Tjurina no., multiplicitiy, and es-Tjurina at blow ups
1502
+ intmat contact; // contact matrix
1503
+ list graphs, multipl; // resolution graphs and multiplicity sequences
1504
+ list graphs_ed, multipl_ed; // res.graphs and mult.seq. of one curve on 1st ex. div.
1505
+ intmat contact_ed; // contact matrix of one curve on 1st exceptional divisor
1506
+ int d_i; // correction term
1507
+ intvec connections;
1508
+ intmat graph;
1509
+ intvec multseq;
1510
+ int s,e;
1511
+ int multi; // multiplicity of the curve defined by the input.
1512
+ /////////////////////////////////////////////////////////
1513
+ // Check what type the input is, and act accordingly.
1514
+ if (typeof(INPUT)=="list")
1515
+ {
1516
+ if (size(INPUT)==3)
1517
+ {
1518
+ // If the INPUT is the output of totalmultiplicities(INPUT,"tau")
1519
+ if ((typeof(INPUT[1])=="list") and (typeof(INPUT[2])=="list") and (typeof(INPUT[3])=="intmat"))
1520
+ {
1521
+ graphs=INPUT[1];
1522
+ multipl=INPUT[2];
1523
+ contact=INPUT[3];
1524
+ }
1525
+ // Otherwise call the procedure with the output of totalmultiplicities(INPUT,"tau").
1526
+ else
1527
+ {
1528
+ return(tau_es2(totalmultiplicities(INPUT,"tau")));
1529
+ }
1530
+ }
1531
+ else
1532
+ {
1533
+ return(tau_es2(totalmultiplicities(INPUT,"tau")));
1534
+ }
1535
+ }
1536
+ // Otherwise call the procedure with the output of totalmultiplicities(INPUT,"tau").
1537
+ else
1538
+ {
1539
+ return(tau_es2(totalmultiplicities(INPUT,"tau")));
1540
+ }
1541
+ /// End of checking the input
1542
+ ///////////////////////////////////////////////////////
1543
+ // If the singularity is smooth, the equisingular Tjurina number is zero.
1544
+ if ((ncols(contact)==1) and (multipl[1][1]<=1))
1545
+ {
1546
+ return(0);
1547
+ }
1548
+ // Otherwise calculate the multiplicity of the singularity.
1549
+ for (i=1;i<=size(multipl);i++)
1550
+ {
1551
+ multi=multi+multipl[i][1];
1552
+ }
1553
+ // Find the branches which stay together after blowing up once, and group them together.
1554
+ k=0;
1555
+ intvec curves_on_first_ex_div=k; // If this is 0=i_0,i_1,...i_s=ncols(contact), then the branches
1556
+ while (k<ncols(contact)) // (i_j)+1,...,i_(j+1) stay together after the first blowing up,
1557
+ { // and s is the number of infinitely near points of first order.
1558
+ k=find_last_non_one(intvec(contact[k+1,1..ncols(contact)]),k+2);
1559
+ curves_on_first_ex_div=curves_on_first_ex_div,k;
1560
+ }
1561
+ // And then calculate the equisingular Tjurina numbers in the infinitely near points of
1562
+ // first order plus some correction term (= the number of blow ups needed to separate the
1563
+ // strict transform from the exceptional divisor in the corresponding infinitely near point)
1564
+ // and add them.
1565
+ for (i=1;i<=size(curves_on_first_ex_div)-1;i++)
1566
+ {
1567
+ s=curves_on_first_ex_div[i]+1;
1568
+ e=curves_on_first_ex_div[i+1];
1569
+ graphs_ed=list(graphs[s..e]);
1570
+ multipl_ed=list(multipl[s..e]);
1571
+ contact_ed=intmat_minus_one(intmat(intvec(contact[s..e,s..e]),e-s+1,e-s+1));
1572
+ connections=0;
1573
+ // Adjust the graphs and multiplicity sequences by cutting the first level.
1574
+ // And find in each graph the point to which the point 1 is connected = 1 + number of
1575
+ // blow ups needed to separate the strict transform from the first exceptional divisor.
1576
+ for (j=1;j<=size(graphs_ed);j++)
1577
+ {
1578
+ // Adjust the graphs and find the connection points.
1579
+ graph=graphs_ed[j];
1580
+ connections[j]=find_connection_point(intvec(graph[1,1..ncols(graph)]),1);
1581
+ graph=delete_row(delete_col(graph,1),1);
1582
+ graphs_ed[j]=graph;
1583
+ // Adjust the multiplicity sequences.
1584
+ multseq=multipl_ed[j];
1585
+ if (size(multseq)==1) // If multseq has only one entry, then their is only
1586
+ { // one branch left and it is smooth! So set multipl_ed[j]=1.
1587
+ multipl_ed[j]=intvec(1);
1588
+ }
1589
+ else // Otherwise just cut the first entry.
1590
+ {
1591
+ multipl_ed[j]=intvec(multseq[2..size(multseq)]);
1592
+ }
1593
+ }
1594
+ // Calculate the equisingular Tjurina number of the strict transform at the i-th
1595
+ // intersection point with the first exceptional divisor.
1596
+ tau_i=tau_es2(list(graphs_ed,multipl_ed,contact_ed));
1597
+ // Calculate the number no. of blow ups needed to separate the strict transform of
1598
+ // the curve defined by the input from the first exceptional divisor at their i-th
1599
+ // intersection point.
1600
+ d_i=max_in_intvec(connections)-1;
1601
+ // If d_i is negative, then there was only one branch left and it was smooth, so d_i should be 1.
1602
+ if (d_i<0)
1603
+ {
1604
+ d_i=1;
1605
+ }
1606
+ // If the curve defined by graphs_ed was smooth, then the summand has to be reduced by 1.
1607
+ if (tau_i==0)
1608
+ {
1609
+ tau_i=-1;
1610
+ }
1611
+ tau=tau+tau_i+d_i;
1612
+ }
1613
+ // The equisingular Tjurina number is then calculated by adding the following term.
1614
+ tau=tau+((multi*(multi+1)) div 2)-2;
1615
+ return(tau);
1616
+ }
1617
+ example
1618
+ {
1619
+ "EXAMPLE:";
1620
+ echo=2;
1621
+ ring r=0,(x,y),ls;
1622
+ poly f1=y2-x3;
1623
+ poly f2=(y2-x3)^2-4x5y-x7;
1624
+ poly f3=y3-x2;
1625
+ tau_es2(f1);
1626
+ tau_es2(f2);
1627
+ tau_es2(f1*f2*f3);
1628
+ }
1629
+
1630
+
1631
+ ///////////////////////////////////////////////////////////////////////////////////////////
1632
+ // Static procedures.
1633
+ ///////////////////////////////////////////////////////////////////////////////////////////
1634
+
1635
+ static proc euclidseq(int a,int b)
1636
+ "USAGE: euclidseq(a,b), a,b integers
1637
+ RETURN: intvec, the divisors in the euclidean algorithm with multiplicities
1638
+ KEYWORDS: Euclidean algorithm; multiplicity sequence
1639
+ NOTE : This procedure is for internal use only; it is called by charexp2multseq.
1640
+ "
1641
+ {
1642
+ int i;
1643
+ // multseq saves in each step of the Euclidean algorithm q-times the divisor b
1644
+ intvec multseq;
1645
+ int q=a div b;
1646
+ int r=a mod b;
1647
+ for (i=1;i<=q;i++)
1648
+ {
1649
+ multseq[i]=b;
1650
+ }
1651
+ int s=q; // size of multseq
1652
+ a=b;
1653
+ b=r;
1654
+ while(r<>0)
1655
+ {
1656
+ q=a div b;
1657
+ r=a mod b;
1658
+ for (i=1;i<=q;i++)
1659
+ {
1660
+ multseq[s+i]=b;
1661
+ }
1662
+ s=s+q; // size of multseq
1663
+ a=b;
1664
+ b=r;
1665
+ }
1666
+ return(multseq);
1667
+ }
1668
+
1669
+ static proc puiseuxchainpart (int piij, int muij, intvec multpl, int initial_tm, int end_tm, int j)
1670
+ "USAGE: puiseuxchainpart(piij,muiij,multpl,initial_tm,end_tm,j);
1671
+ RETURN: list L, L[1] incidence matrix of a part of the Puiseux chain, L[2] the total
1672
+ multiplicities of this part of the Puiseux chain.
1673
+ NOTE: This procedure is only for internal use; it is called by puiseuxchain.
1674
+ "
1675
+ {
1676
+ int delta=1;
1677
+ if (j==1){delta=0;} // Delta measures whether j is 1 or not.
1678
+ intvec totalmultiplicity; // Keeps the total multiplicities.
1679
+ intmat pcp[muij][muij]; // Keeps the incidence matrix of the Puiseuxchainpart S_i,j.
1680
+ // Calculate the total multiplicities and the Puiseuxchainpart S_i,j.
1681
+ totalmultiplicity[1]=initial_tm+end_tm+multpl[1];
1682
+ pcp[1,1]=piij+1;
1683
+ for (int k=2;k<=muij;k++)
1684
+ {
1685
+ pcp[k,k]=piij+k;
1686
+ pcp[k-1,k]=1;
1687
+ pcp[k,k-1]=1;
1688
+ totalmultiplicity[k]=totalmultiplicity[k-1]+delta*initial_tm+multpl[k];
1689
+ }
1690
+ list result=pcp,totalmultiplicity;
1691
+ return(result);
1692
+ }
1693
+
1694
+ static proc puiseuxchain (int initial, intvec divseq, intvec multpl, int initial_tm)
1695
+ "USAGE: puiseuxchain(initial,divseq,multpl,initial_tm); int initial, initial_tm, intvec divseq, multpl
1696
+ RETURN: list L, L[1] incidence matrix of a Puiseux chain, L[2] the weight of the point to which the
1697
+ previous Puiseux chain has to be connected, L[3] the sequence of total multiplicities of
1698
+ the points in this Puiseux chain.
1699
+ NOTE: This procedure is only for internal use; it is called by irred_resgraph_totmult.
1700
+ "
1701
+ {
1702
+ int j,k,l,connectpoint;
1703
+ intvec multpli;
1704
+ int pc_tm=initial_tm; // Keeps the total multipl. of the endpoint of P_i-1.
1705
+ int end_tm=0;
1706
+ int start=1;
1707
+ int omega=size(divseq);
1708
+ // Keep the endpoints of the puiseuxchainparts (minus initial) s_i,j in divseq_sum.
1709
+ intvec divseq_sum=divseq[1];
1710
+ for (j=2;j<=omega;j++)
1711
+ {
1712
+ divseq_sum[j]=divseq_sum[j-1]+divseq[j];
1713
+ }
1714
+ // Define the connecting point of the Puiseuxchain P_i-1 with P_i.
1715
+ if (divseq[1]==0)
1716
+ {
1717
+ // If divseq[1]=mu_i,1=0, then the Puiseuxchainpart S_i,1 is empty.
1718
+ // We may start building the Puiseuxchain with part 2, i.e. set start=2.
1719
+ start=2;
1720
+ if (omega>=3)
1721
+ {
1722
+ connectpoint=initial+divseq_sum[2]+1; // startpoint of s_i+1,3
1723
+ }
1724
+ else
1725
+ {
1726
+ connectpoint=initial+divseq_sum[2]; // endpoint of s_i+1,2
1727
+ }
1728
+ }
1729
+ else
1730
+ {
1731
+ connectpoint=initial+1;
1732
+ }
1733
+ // Build the Puiseuxchainparts s_i,j and put them as blocks into pc=P_i.
1734
+ multpli=multpl[initial+1..initial+divseq_sum[start]];
1735
+ list pcp=puiseuxchainpart(initial,divseq[start],multpli,initial_tm,end_tm,start);
1736
+ intmat pc=pcp[1];
1737
+ intvec tm=pcp[2];
1738
+ for (j=start+1;j<=omega;j++)
1739
+ {
1740
+ // Keep the final total multipl. of the puiseuxchainpart S_i,j-2 resp. P_i-1, if S_i,1 empty.
1741
+ if (j>2){end_tm=initial_tm;}
1742
+ // Calculate the endpoint of S_i,j-1.
1743
+ initial=initial+divseq[j-1];
1744
+ // Keep the total multiplicity of the endpoint of S_i,j-1
1745
+ initial_tm=pcp[2][size(pcp[2])];
1746
+ // Build the new puiseuxchainpart S_i,j
1747
+ multpli=multpl[initial+1..initial+divseq[j]];
1748
+ pcp=puiseuxchainpart(initial,divseq[j],multpli,initial_tm,end_tm,j);
1749
+ pc=addmat(pc,pcp[1]);
1750
+ tm=tm,pcp[2];
1751
+ }
1752
+ // Connect the Puiseuxchainparts s_i,j.
1753
+ for (j=start;j<=omega-2;j++)
1754
+ {
1755
+ k=divseq_sum[j]; // endpoint of s_i,j
1756
+ l=divseq_sum[j+1]+1; // startpoint of s_i,j+2
1757
+ pc[k,l]=1; // connecting these
1758
+ pc[l,k]=1;
1759
+ }
1760
+ if (omega>=start+1) // If there are at least two non-empty s_i,j.
1761
+ {
1762
+ k=divseq_sum[omega-1]; // endpoint of s_i,omega-1
1763
+ l=divseq_sum[omega]; // endpoint of s_i,omega
1764
+ pc[k,l]=1; // connecting these
1765
+ pc[l,k]=1;
1766
+ }
1767
+ list ergebnis=pc,connectpoint,tm;
1768
+ return(ergebnis);
1769
+ }
1770
+
1771
+ static proc irred_resgraph_totmult (intvec charexp)
1772
+ "USAGE: irred_resgraph_totmult(charexp); charexp intvec
1773
+ ASSUME: charexp is an integer vector containing the characteristic exponents
1774
+ of an irreducible plane curve singularity
1775
+ RETURN: list L, L[1] is the incidence matrix of the resolution graph of the plane curve
1776
+ singularity defined by INPUT, and L[2] is its sequence of total multiplicities
1777
+ NOTE: This procedure is only for internal use; it is called by resgraph.
1778
+ "
1779
+ {
1780
+ int k,l;
1781
+ intvec multpl=charexp2multseq(charexp); // multiplicity sequence of the singularity
1782
+ // Do first the case where the singularity is actually smooth.
1783
+ if (size(charexp)==1)
1784
+ {
1785
+ intmat resgraph[1][1]=0;
1786
+ intvec tm=1; // there is no exceptional divisor in the resolution - ERROR: should be 0,
1787
+ // but for the time being, Singular returns 1 as multiplicity of smooth curves
1788
+ list result=resgraph,tm,multpl;
1789
+ return(result);
1790
+ }
1791
+ // End of the smooth case
1792
+ int initial_tm=0; // total multipl. of the endpoint of Puiseux chain P_i-1
1793
+ int g=size(charexp);
1794
+ list es=divsequence(charexp[2],charexp[1]); // keeps the lengths of the Puiseuxchainparts s_i,j
1795
+ intvec divseq=es[1];
1796
+ int r=es[2];
1797
+ int initial=0;
1798
+ // Build the Puiseuxchains P_i and put them as blocks into a matrix.
1799
+ list pc=puiseuxchain(initial,divseq,multpl,initial_tm);
1800
+ intmat resgraph=pc[1];
1801
+ intvec endpoints=resgraph[nrows(resgraph),ncols(resgraph)];
1802
+ intvec connectpoints=pc[2];
1803
+ intvec tm=pc[3];
1804
+ for (int i=3;i<=g;i++)
1805
+ {
1806
+ initial_tm=tm[size(tm)];
1807
+ es=divsequence(charexp[i]-charexp[i-1],r);
1808
+ divseq=es[1];
1809
+ r=es[2];
1810
+ initial=endpoints[size(endpoints)];
1811
+ pc=puiseuxchain(initial,divseq,multpl,initial_tm);
1812
+ resgraph=addmat(resgraph,pc[1]);
1813
+ endpoints=endpoints,resgraph[nrows(resgraph),ncols(resgraph)];
1814
+ connectpoints=connectpoints,pc[2];
1815
+ tm=tm,pc[3];
1816
+ }
1817
+ // Adding the * for the strict transform to the Graph.
1818
+ resgraph=addmat(resgraph,0);
1819
+ // The connecting point of the * with the graph.
1820
+ connectpoints=connectpoints,nrows(resgraph);
1821
+ // Connect the P_i with each other and with *.
1822
+ for (i=2;i<=g;i++)
1823
+ {
1824
+ k=endpoints[i-1]; // endpoint of P_i-1
1825
+ l=connectpoints[i]; // conncting point of P_i resp. of *
1826
+ resgraph[k,l]=1; // connecting these
1827
+ resgraph[l,k]=1;
1828
+ }
1829
+ list result=resgraph,tm,multpl; //HIER GEAENDERT!!!!
1830
+ return(result);
1831
+ }
1832
+
1833
+
1834
+ static proc max_in_intvec (intvec v, list #)
1835
+ "USAGE: max_in_intvec(v); v intvec
1836
+ RETURN: int m, maximum of the integers in v
1837
+ USAGE: max_in_intvec(v,1); v intvec
1838
+ RETURN: intvec m, m[1] maximum of the integers in v, m[2] position of the
1839
+ last occurrence of the maximum in v
1840
+ NOTE: This procedure is only for internal use; this procedure is called by
1841
+ totalmultiplicities and semigroup.
1842
+ "
1843
+ {
1844
+ int max=v[1];
1845
+ int maxpos=1;
1846
+ for (int i=2;i<=size(v);i++)
1847
+ {
1848
+ if (v[i]>max)
1849
+ {
1850
+ max=v[i];
1851
+ maxpos=i;
1852
+ }
1853
+ }
1854
+ if (size(#)==0)
1855
+ {
1856
+ return(max);
1857
+ }
1858
+ else
1859
+ {
1860
+ return(intvec(max,maxpos));
1861
+ }
1862
+ }
1863
+
1864
+ static proc addmat (intmat A,intmat B)
1865
+ "USAGE: max_in_intvec(A,B); A, B integer matrices
1866
+ RETURN: intmat C, block matrix with left-upper block A, right-lower block B
1867
+ NOTE: This procedure is only for internal use; this procedure is called several times.
1868
+ "
1869
+ {
1870
+ int nc=ncols(A);
1871
+ int nr=nrows(A);
1872
+ int mc=ncols(B);
1873
+ int mr=nrows(B);
1874
+ int i,j;
1875
+ intmat AB[nr+mr][nc+mc];
1876
+ for (i=1;i<=nr;i++)
1877
+ {
1878
+ for (j=1;j<=nc;j++)
1879
+ {
1880
+ AB[i,j]=A[i,j];
1881
+ }
1882
+ }
1883
+ for (i=1;i<=mr;i++)
1884
+ {
1885
+ for (j=1;j<=mc;j++)
1886
+ {
1887
+ AB[i+nr,j+nc]=B[i,j];
1888
+ }
1889
+ }
1890
+ return(AB);
1891
+ }
1892
+
1893
+ static proc divsequence(int a,int b)
1894
+ "USAGE: divsequence(a,b); a,b integers
1895
+ RETURN: list l, l[1] the multiplicities of the divisors in the Euclidean algorithm
1896
+ and l[2] the last non-zero remainder in the Euclidean algorithm
1897
+ NOTE: This procedure is only for internal use; it is called in irred_res_graph.
1898
+ "
1899
+ {
1900
+ int q=a div b;
1901
+ int r=a mod b;
1902
+ intvec divseq=q;
1903
+ while(r<>0)
1904
+ {
1905
+ a=b;
1906
+ b=r;
1907
+ q=a div b;
1908
+ r=a mod b;
1909
+ divseq = divseq,q;
1910
+ }
1911
+ list result=divseq,b;
1912
+ return(result);
1913
+ }
1914
+
1915
+
1916
+
1917
+ static proc adjust_tot_mult (intvec rtm_fix, intvec rtm_var, intvec rmt_fix, intvec rmt_var, def p, def q, def stricttransforms, int k)
1918
+ "USAGE: adjust_tot_mult(v1,v2,v3,v4,p,q,st,k); v1,...,st intvecs and k an integer
1919
+ RETURN: intvec rtm_var, adjusted total multiplicities
1920
+ NOTE: This procedure is only for internal use; it is called in totalmultiplicities.
1921
+ "
1922
+ {
1923
+ int j,l,store; // Help variables.
1924
+ // Recalculate the entries in rtm_var from stricttransforms[k]+1,...,stricttransforms[k+1]-1.
1925
+ for (j=stricttransforms[k]+1;j<stricttransforms[k+1];j++)
1926
+ {
1927
+ if (rtm_var[j]==0) // If the entry is non-zero, we know that it is already correct.
1928
+ {
1929
+ // Check if the vertex in the fixed part is connected to one or to two vertices of lower weight.
1930
+ if (j==stricttransforms[k]+1) // The vertex of weight 1 less is p[k], to which the subgraph is glued.
1931
+ {
1932
+ store=rtm_fix[j]-rmt_fix[j]-rtm_fix[p[k]];
1933
+ }
1934
+ else // The vertex of weight 1 less belongs to the subgraph.
1935
+ {
1936
+ store=rtm_fix[j]-rmt_fix[j]-rtm_fix[j-1];
1937
+ }
1938
+ // It is connected to two vertices V (which has weight one less) and W.
1939
+ if (store>0)
1940
+ {
1941
+ if (j==stricttransforms[k]+1) // V is p[k] (to which the subgraph was glued) and W is q[k], the
1942
+ { // vertex of weight one less, to which p[k] is connected.
1943
+ rtm_var[j]=rtm_var[p[k]]+rtm_var[q[k]]; // In this case the subgraph separates p[k] and q[k]!
1944
+ }
1945
+ if (j==stricttransforms[k]+2) // V belongs to the subgraph (it is the vertex considered in the
1946
+ { // previous case!), and W is p[k] or q[k]. In this case the subgraph separates p[k] and q[k].
1947
+ if (store==rtm_fix[p[k]]) // If W=p[k], ...
1948
+ {
1949
+ rtm_var[j]=rtm_var[j-1]+rtm_var[p[k]];
1950
+ }
1951
+ else // else W=q[k] ... .
1952
+ {
1953
+ rtm_var[j]=rtm_var[j-1]+rtm_var[q[k]]; // separates p[k] and q[k].
1954
+ }
1955
+ }
1956
+ if (j>stricttransforms[k]+2) // V belongs to the subgraph and W either does as well or is p[k].
1957
+ {
1958
+ l=j-2;
1959
+ while (store<rtm_fix[l]) // Find the second vertex W which is connected to which it is
1960
+ { // connected. It has total multipl. = store!
1961
+ if (l>stricttransforms[k]+1) // If l-1 belongs to the graph, then reduce l.
1962
+ {
1963
+ l=l-1;
1964
+ }
1965
+ else // If l-1 is stricttransform[k], hence isn't in the graph, then reducing l gives p[k].
1966
+ { // If l=p[k] and still store<rtm_fix[l], then j must be connected to q[k]!
1967
+ if (l==stricttransforms[k]+1)
1968
+ {
1969
+ l=p[k];
1970
+ }
1971
+ else
1972
+ {
1973
+ l=q[k];
1974
+ }
1975
+ }
1976
+ }
1977
+ rtm_var[j]=rtm_var[j-1]+rtm_var[l];
1978
+ }
1979
+ }
1980
+ // It is only connected to one vertex V, which then must be the one of weight one less.
1981
+ else
1982
+ {
1983
+ if (j==stricttransforms[k]+1) // V is p[k], the vertex, to which the subgraph was glued.
1984
+ {
1985
+ rtm_var[j]=rtm_var[p[k]];
1986
+ }
1987
+ else
1988
+ {
1989
+ rtm_var[j]=rtm_var[j-1]; // V is belongs already to the subgraph.
1990
+ }
1991
+ }
1992
+ }
1993
+ }
1994
+ return(rtm_var);
1995
+ }
1996
+
1997
+
1998
+ static proc find_connection_point (intvec v, int k)
1999
+ "USAGE: find_connection_point(v,c); where v is an intvec, and k is an integer
2000
+ RETURN: The largest integer i>k, such that v[i]=1, or 0 if no such i exists.
2001
+ NOTE: This procedure is only for internal use; it is called in totalmultiplicities.
2002
+ "
2003
+ {
2004
+ for (int i=size(v)-1;i>=k+1;i--)
2005
+ {
2006
+ if (v[i]==1)
2007
+ {
2008
+ return(i);
2009
+ }
2010
+ }
2011
+ return(0);
2012
+ }
2013
+
2014
+ static proc find_connection_points (intmat resgr, int k)
2015
+ "USAGE: find_connection_points(resgr,k); where resgr is an intmat, and k is an integer
2016
+ RETURN: list of two intvecs ctps and ctpswts, where ctps contains all integers i!=k, such
2017
+ that resgr[k,i]=1, and ctpswts contains for each such i the weight resgr[i,i].
2018
+ NOTE: This procedure is only for internal use; it is called in totalmultiplicities.
2019
+ "
2020
+ {
2021
+ intvec ctps;
2022
+ intvec ctpswts;
2023
+ int j=1;
2024
+ for (int i=1;i<=ncols(resgr);i++)
2025
+ {
2026
+ if ((resgr[k,i]==1) and (i!=k))
2027
+ {
2028
+ ctps[j]=i;
2029
+ ctpswts[j]=resgr[i,i];
2030
+ j++;
2031
+ }
2032
+ }
2033
+ return(list(ctps,ctpswts));
2034
+ }
2035
+
2036
+ static proc find_lower_connection_points (intmat resgr, int k)
2037
+ "USAGE: find_lower_connection_points(resgr,k); where resgr is an intmat, and k is an integer
2038
+ ASSUME: resgr is the resolutiongraph of an IRREDUCIBLE curve singularity and k<ncols(resgr).
2039
+ RETURN: intvec, which contains the weights of points of lower weight than k, to which
2040
+ the point of weight k in resgr is connected, and 0 if no such point exists.
2041
+ NOTE: This procedure is only for internal use; it is called in totalmultiplicities.
2042
+ "
2043
+ {
2044
+ intvec ctps=find_connection_points(resgr,k)[2];
2045
+ intvec lower_ctps;
2046
+ int i=1;
2047
+ while ((ctps[i]<k) and (ctps[i]>0))
2048
+ {
2049
+ lower_ctps[i]=ctps[i];
2050
+ i++;
2051
+ }
2052
+ return(lower_ctps);
2053
+ }
2054
+
2055
+
2056
+ static proc euclides(int a,int b) // Procedure of Fernando.
2057
+ "USAGE: euclides(m,n);where m,n are integers.
2058
+ RETURN: The divisor, the quotients and the remainders of the euclidean algorithm performing for m and n.
2059
+ NOTE: This procedure is only for internal use; it is called in multseq2charexp.
2060
+ "
2061
+ {
2062
+ int c=a div b;//we compute in c the integer division between a and b.
2063
+ int r=a mod b;//in r the remainder of the division between a and b
2064
+ intvec dividendo=c;// we define the intvec of the dividens and we initialize it to c
2065
+ intvec remain=r;// we define the intvec of the remainders and we initialize it to r
2066
+ a=b;//change a to b
2067
+ b=r;// and b to r
2068
+
2069
+ while(r<>0)// while the current remainder is different to 0 we make the same af before
2070
+ {
2071
+ c=a div b;
2072
+ r=a mod b;
2073
+ dividendo =dividendo,c;
2074
+ if(r<>0)
2075
+ {
2076
+ remain=remain,r;
2077
+ }
2078
+ a=b;
2079
+ b=r;
2080
+ }
2081
+ list L=dividendo,remain;//we put in a list all the dividens and all the remainders
2082
+ return(L);// and return the list
2083
+ }
2084
+
2085
+
2086
+
2087
+ static proc tau_es_qh (poly f)
2088
+ "USAGE: tau_es_qh(f), poly f
2089
+ RETURN: int, equisingular Tjurina number
2090
+ NOTE: This procedure is only for internal use; it is called in Tau_es.
2091
+ "
2092
+ {
2093
+ intvec qh=qhweight(f);
2094
+ if (qh[1]==0)
2095
+ {
2096
+ ERROR("Input is not quasi-homogenous.");
2097
+ }
2098
+ else
2099
+ {
2100
+ int d_f = deg(f,qh);
2101
+ list Tj=Tjurina(f,1);
2102
+ ideal tj=Tj[2];
2103
+ int Taues=size(tj);
2104
+ for (int i=1;i<=size(tj);i++)
2105
+ {
2106
+ if (deg(tj[i],qh)>=d_f)
2107
+ {
2108
+ Taues--;
2109
+ }
2110
+ }
2111
+ }
2112
+ return(Taues);
2113
+ }
2114
+
2115
+
2116
+ static proc move_row (intmat M, int i,int j)
2117
+ "USAGE: move_row(M,i,j), intmat M, int i,j
2118
+ RETURN: intmat, the matrix M with j-th row now i-th row and the remaining rows moved accordingly.
2119
+ NOTE: This procedure is only for internal use; it is called in move_row_col.
2120
+ "
2121
+ {
2122
+ if ((i>nrows(M)) or (j>nrows(M)))
2123
+ {
2124
+ ERROR("The matrix has not enough rows.");
2125
+ }
2126
+ if (i==j)
2127
+ {
2128
+ return(M);
2129
+ }
2130
+ if (i>1)
2131
+ {
2132
+ intmat N[nrows(M)+1][ncols(M)]=intvec(M[1..i-1,1..ncols(M)]),intvec(M[j,1..ncols(M)]),intvec(M[i..nrows(M),1..ncols(M)]);
2133
+ }
2134
+ if (i==1)
2135
+ {
2136
+ intmat N[nrows(M)+1][ncols(M)]=intvec(M[j,1..ncols(M)]),intvec(M[i..nrows(M),1..ncols(M)]);
2137
+ }
2138
+ if (i<j)
2139
+ {
2140
+ N=delete_row(N,j+1);
2141
+ }
2142
+ if (i>j)
2143
+ {
2144
+ N=delete_row(N,j);
2145
+ }
2146
+ return(N);
2147
+ }
2148
+
2149
+ static proc move_col (intmat M, int i,int j)
2150
+ "USAGE: move_col(M,i,j), intmat M, int i,j
2151
+ RETURN: intmat, the matrix M with j-th column now i-th column and the remaining columns moved accordingly.
2152
+ NOTE: This procedure is only for internal use; it is called in move_row_col.
2153
+ "
2154
+ {
2155
+ return(transpose(move_row(transpose(M),i,j)));
2156
+ }
2157
+
2158
+ static proc move_row_col (intmat M,int i,int j)
2159
+ "USAGE: move_row(M,i,j), intmat M, int i,j
2160
+ RETURN: intmat, the matrix M with j-th row/column now i-th row/column and the remaining
2161
+ rows and columns moved accordingly.
2162
+ NOTE: This procedure is only for internal use; it is called in totalmultiplicities.
2163
+ "
2164
+ {
2165
+ return(move_col(move_row(M,i,j),i,j));
2166
+ }
2167
+
2168
+
2169
+ static proc delete_row (intmat M,int i)
2170
+ "USAGE: delete_row(M,i); M intmat, i int
2171
+ RETURN: intmat, which is derived from M by removing the ith row
2172
+ NOTE: This procedure is only for internal use; it is called in move_row and tau_es2.
2173
+ "
2174
+ {
2175
+ if ((i!=1) and (i!=nrows(M)))
2176
+ {
2177
+ return(intmat(intvec(M[1..i-1,1..ncols(M)],M[i+1..nrows(M),1..ncols(M)]),nrows(M)-1,ncols(M)));
2178
+ }
2179
+ if (i==1)
2180
+ {
2181
+ return(intmat(intvec(M[2..nrows(M),1..ncols(M)]),nrows(M)-1,ncols(M)));
2182
+ }
2183
+ else
2184
+ {
2185
+ return(intmat(intvec(M[1..nrows(M)-1,1..ncols(M)]),nrows(M)-1,ncols(M)));
2186
+ }
2187
+ }
2188
+
2189
+ static proc delete_col (intmat M, int i)
2190
+ "USAGE: delete_col(M,i); M intmat, i int
2191
+ RETURN: intmat, which is derived from M by removing the ith column
2192
+ NOTE: This procedure is only for internal use; it is called in tau_es.
2193
+ "
2194
+ {
2195
+ return(transpose(delete_row(transpose(M),i)));
2196
+ }
2197
+
2198
+
2199
+
2200
+ static proc sort_branches (intmat contact, list graphs, list totmult, list multpl, int k,int l)
2201
+ "USAGE: sort_branches(K,L,M,N,k,l); K intmat, L,M,N lists, k,l integers
2202
+ ASSUME: K = contact matrix of the branches of a curve, L = their resolutiongraphs,
2203
+ M = their totalmultiplicities, N = their multiplicities
2204
+ RETURN: list LL, LL[1] transformed K, LL[2..4] transformed L,M,N.
2205
+ The procedure sorts the branches from k+1 to l according to descending contact with
2206
+ with the branch k.
2207
+ NOTE: This procedure is only for internal use; it is called in totalmultiplicities.
2208
+ "
2209
+ {
2210
+ intvec max;
2211
+ for (int i=k+1;i<=l;i++)
2212
+ {
2213
+ // Find the last graph max between i and l which has maximal contact with k.
2214
+ max=max_in_intvec(intvec(contact[k,i..l]),1);
2215
+ max[2]=max[2]+i-1;
2216
+ if (i!=max[2]) // If max is not i, then move max to position i!
2217
+ {
2218
+ graphs=insert(graphs,graphs[max[2]],i-1);
2219
+ graphs=delete(graphs,max[2]+1);
2220
+ totmult=insert(totmult,totmult[max[2]],i-1);
2221
+ totmult=delete(totmult,max[2]+1);
2222
+ multpl=insert(multpl,multpl[max[2]],i-1);
2223
+ multpl=delete(multpl,max[2]+1);
2224
+ contact=move_row_col(contact,i,max[2]);
2225
+ }
2226
+ }
2227
+ return(list(contact,graphs,totmult,multpl));
2228
+ }
2229
+
2230
+
2231
+ static proc find_last_non_one (intvec v,int k)
2232
+ "USAGE: find_last_non_one (v,k); intvec v, int k
2233
+ RETURN: int i, the last index i>=k such that v[i]!=1, or k-1 if no such i exists.
2234
+ NOTE: This procedure is only for internal use; it is called in tau_es2.
2235
+ "
2236
+ {
2237
+ int i=size(v);
2238
+ while (i>=k)
2239
+ {
2240
+ if (v[i]!=1)
2241
+ {
2242
+ return(i);
2243
+ }
2244
+ else
2245
+ {
2246
+ i--;
2247
+ }
2248
+ }
2249
+ return(i);
2250
+ }
2251
+
2252
+ static proc intmat_minus_one (intmat M)
2253
+ "USAGE: intmat_minus_one(M); intmat M
2254
+ RETURN: intmat, all non-zero entries of M deminuished by 1.
2255
+ NOTE: This procedure is only for internal use; it is called in tau_es2.
2256
+ "
2257
+ {
2258
+ int i,j;
2259
+ for (i=1;i<=nrows(M);i++)
2260
+ {
2261
+ for (j=1;j<=ncols(M);j++)
2262
+ {
2263
+ if (M[i,j]!=0)
2264
+ {
2265
+ M[i,j]=M[i,j]-1;
2266
+ }
2267
+ }
2268
+ }
2269
+ return(M);
2270
+ }
2271
+
2272
+ proc proximitymatrix (def INPUT)
2273
+ "USAGE: proximitymatrix(INPUT); INPUT poly or list or intmat
2274
+ ASSUME: INPUT is either a REDUCED bivariate polynomial defining a plane curve singularity,
2275
+ or the output of @code{hnexpansion(f[,\"ess\"])}, or the list @code{hne} in
2276
+ the ring created by @code{hnexpansion(f[,\"ess\"])}, or the output of
2277
+ @code{develop(f)} resp. of @code{extdevelop(f,n)}, or a list containing
2278
+ the contact matrix and a list of integer vectors with the characteristic exponents
2279
+ of the branches of a plane curve singularity, or an integer vector containing the
2280
+ characteristic exponents of an irreducible plane curve singularity, or the resolution
2281
+ graph of a plane curve singularity (i.e. the output of resolutiongraph or
2282
+ the first entry in the output of totalmultiplicities).
2283
+ RETURN: list, of three integer matrices. The first one is the proximity matrix of
2284
+ the plane curve defined by the INPUT, i.e. the entry i,j is 1 if the
2285
+ infinitely near point corresponding to row i is proximate to the infinitely
2286
+ near point corresponding to row j. The second integer matrix is the incidence matrix of the
2287
+ resolution graph of the plane curve. The entry on the diagonal in row i is -s-1
2288
+ if s is the number of points proximate to the infinitely near point corresponding
2289
+ to the ith row in the matrix. The third integer matrix is the incidence matrix of
2290
+ the Enriques diagram of the plane curve singularity, i.e. each row corresponds to
2291
+ an infinitely near point in the minimal standard resolution, including the
2292
+ strict transforms of the branches, the diagonal element gives
2293
+ the level of the point, and the entry i,j is -1 if row i is proximate to row j.
2294
+ NOTE: In case the Hamburger-Noether expansion of the curve f is needed
2295
+ for other purposes as well it is better to calculate this first
2296
+ with the aid of @code{hnexpansion} and use it as input instead of
2297
+ the polynomial itself.
2298
+ @*
2299
+ If you are not sure whether the INPUT polynomial is reduced or not, use
2300
+ @code{squarefree(INPUT)} as input instead.
2301
+ @*
2302
+ If the input is a smooth curve, then the output will consist of
2303
+ three one-by-one zero matrices.
2304
+ @*
2305
+ For the definitions of the computed objects see e.g. the book
2306
+ Eduardo Casas-Alvero, Singularities of Plane Curves.
2307
+ SEE ALSO: develop, hnexpansion, totalmultiplicities, alexanderpolynomial
2308
+ EXAMPLE: example proximitymatrix; shows an example
2309
+ "
2310
+ {
2311
+ ///////// Decide on the type of input. //////////
2312
+ if (typeof(INPUT)=="intmat")
2313
+ {
2314
+ intmat resgr=INPUT;
2315
+ }
2316
+ else
2317
+ {
2318
+ intmat resgr=totalmultiplicities(INPUT)[1];
2319
+ }
2320
+ //////// Deal with the case of a smooth curve ////////////////
2321
+ if (size(resgr)==1)
2322
+ {
2323
+ return(list(intmat(intvec(1),1,1),intmat(intvec(-1),1,1),intmat(intvec(0),1,1)));
2324
+ }
2325
+ //////// Calculate the proximity resolution graph ////////////
2326
+ int i,j;
2327
+ int n=nrows(resgr);
2328
+ intvec diag; // Diagonal of the Enriques diagram.
2329
+ int si; // number of points proximate to the point corresponding to the ith row
2330
+ // Adjust the weights of the nodes corresponding to strict transforms so
2331
+ // as if there had been one additional blow up.
2332
+ for (i=1;i<=n;i++)
2333
+ {
2334
+ // Check if the row corresponds to an exceptional divisor ...
2335
+ if (resgr[i,i]<0)
2336
+ {
2337
+ j=1;
2338
+ while ((resgr[i,j]==0) or (i==j))
2339
+ {
2340
+ j++;
2341
+ }
2342
+ resgr[i,i]=resgr[j,j]+1;
2343
+ }
2344
+ }
2345
+ // Set the weights in the resolution graph to the blowing up level in the resolution.
2346
+ for (i=1;i<=n;i++)
2347
+ {
2348
+ resgr[i,i]=resgr[i,i]-1;
2349
+ diag[i]=resgr[i,i]; // The level of the corresponding infinitely near point.
2350
+ }
2351
+ // Replace the weights in the resolution graph by
2352
+ // -s-1, where s is the number of points which are proximate to the point.
2353
+ for (i=1;i<=n;i++)
2354
+ {
2355
+ si=-1;
2356
+ // Find the points of higher weight which are connected to the ith row.
2357
+ for (j=i+1;j<=n;j++)
2358
+ {
2359
+ // If the point in row j is connected to the ith row, then all the points of
2360
+ // weight resgr[i,i]+1 to weight resgr[j,j] in the corresponding subgraph
2361
+ // are proximate to the point of the ith row. This number is just resgr[j,j]-resgr[i,i].
2362
+ if ((resgr[i,j]!=0) and (resgr[j,j]>0))
2363
+ {
2364
+ si=si-(resgr[j,j]-resgr[i,i]);
2365
+ }
2366
+ }
2367
+ resgr[i,i]=si;
2368
+ }
2369
+ /////////////// Calculate the proximity matrix ///////////////////
2370
+ intmat proximity=proxgauss(resgr);
2371
+ intmat enriques=proximity;
2372
+ for (i=1;i<=nrows(enriques);i++)
2373
+ {
2374
+ enriques[i,i]=diag[i];
2375
+ }
2376
+ return(list(proximity,resgr,enriques));
2377
+ }
2378
+ example
2379
+ {
2380
+ "EXAMPLE:";
2381
+ echo=2;
2382
+ ring r=0,(x,y),ls;
2383
+ poly f1=(y2-x3)^2-4x5y-x7;
2384
+ poly f2=y2-x3;
2385
+ poly f3=y3-x2;
2386
+ list proximity=proximitymatrix(f1*f2*f3);
2387
+ /// The proximity matrix P ///
2388
+ print(proximity[1]);
2389
+ /// The proximity resolution graph N ///
2390
+ print(proximity[2]);
2391
+ /// They satisfy N=-transpose(P)*P ///
2392
+ print(-transpose(proximity[1])*proximity[1]);
2393
+ /// The incidence matrix of the Enriques diagram ///
2394
+ print(proximity[3]);
2395
+ /// If M is the matrix of multiplicities and TM the matrix of total
2396
+ /// multiplicities of the singularity, then M=P*TM.
2397
+ /// We therefore calculate the (total) multiplicities. Note that
2398
+ /// they have to be slightly extended.
2399
+ list MULT=extend_multiplicities(totalmultiplicities(f1*f2*f3));
2400
+ intmat TM=MULT[1]; // Total multiplicities.
2401
+ intmat M=MULT[2]; // Multiplicities.
2402
+ /// Check: M-P*TM=0.
2403
+ M-proximity[1]*TM;
2404
+ /// Check: inverse(P)*M-TM=0.
2405
+ intmat_inverse(proximity[1])*M-TM;
2406
+ }
2407
+
2408
+ static proc addmultiplrows (intmat M, int i, int j, int ki, int kj)
2409
+ "USAGE: addmultiplrows(M,i,j,ki,kj); intmat M, int i,j,ki,kj
2410
+ RETURN: intmat, replaces the j-th row in M by ki-times the i-th row plus
2411
+ kj times the j-th
2412
+ NOTE: This procedure is only for internal use; it is called in intmat_inverse
2413
+ and proxgauss.
2414
+ "
2415
+ {
2416
+ int k=ncols(M);
2417
+ M[j,1..k]=kj*M[j,1..k]+ki*M[i,1..k];
2418
+ return(M);
2419
+ }
2420
+
2421
+
2422
+ static proc proxgauss (intmat M)
2423
+ "USAGE: proxgauss(M); intmat M
2424
+ ASSUME: M is the output of proximity_resgr
2425
+ RETURN: intmat, replaces the j-th row in M by ki-times the i-th row plus
2426
+ kj times the j-th
2427
+ NOTE: This procedure is only for internal use; it is called in intmat_inverse.
2428
+ "
2429
+ {
2430
+ int i;
2431
+ int n=nrows(M);
2432
+ if (n==1)
2433
+ {
2434
+ M[1,1]=1;
2435
+ return(M);
2436
+ }
2437
+ else
2438
+ {
2439
+ if (M[n,n]<0)
2440
+ {
2441
+ M=addmultiplrows(M,n,n,-1,0);
2442
+ }
2443
+ for (i=n-1;i>=1;i--)
2444
+ {
2445
+ if (M[i,n]!=0)
2446
+ {
2447
+ M=addmultiplrows(M,n,i,-M[i,n],M[n,n]);
2448
+ }
2449
+ }
2450
+ intmat N[n-1][n-1]=M[1..n-1,1..n-1];
2451
+ N=proxgauss(N);
2452
+ M[1..n-1,1..n-1]=N[1..n-1,1..n-1];
2453
+ return(M);
2454
+ }
2455
+ }
2456
+
2457
+ proc extend_multiplicities (list rg)
2458
+ "USAGE: extend_multiplicities(rg); list rg
2459
+ ASSUME: rg is the output of the procedure totalmultiplicities
2460
+ RETURN: list, the first entry is an integer matrix containing the total
2461
+ multiplicities and the second entry is an integer matrix containing
2462
+ the multiplicies of the resolution given by rg, where the zeros
2463
+ corresponding to the strict transforms of the branches of the curve
2464
+ have been replaced by the (total) multiplicities of the infinitely near
2465
+ point corresponding to one further blow up for each branch.
2466
+ KEYWORDS: total multiplicities; multiplicity sequence; resolution graph
2467
+ EXAMPLE: example extend_multiplicities; shows an example
2468
+ "
2469
+ {
2470
+ intmat resgr,tm,mt=rg[1],rg[2],rg[3];
2471
+ int i,j;
2472
+ for (i=1;i<=nrows(resgr);i++)
2473
+ {
2474
+ if (resgr[i,i]<0)
2475
+ {
2476
+ j=1;
2477
+ while ((resgr[i,j]==0) or (i==j))
2478
+ {
2479
+ j++;
2480
+ }
2481
+ tm[i,1..ncols(tm)]=tm[j,1..ncols(tm)];
2482
+ tm[i,-resgr[i,i]]=tm[i,-resgr[i,i]]+1;
2483
+ mt[i,-resgr[i,i]]=1;
2484
+ }
2485
+ }
2486
+ return(list(tm,mt));
2487
+ }
2488
+ example
2489
+ {
2490
+ "EXAMPLE:";
2491
+ echo=2;
2492
+ ring r=0,(x,y),ls;
2493
+ poly f1=(y2-x3)^2-4x5y-x7;
2494
+ poly f2=y2-x3;
2495
+ poly f3=y3-x2;
2496
+ // Calculate the resolution graph and the (total) multiplicities of f1*f2*f3.
2497
+ list RESGR=totalmultiplicities(f1*f2*f3);
2498
+ // Extend the (total) multiplicities.
2499
+ list MULT=extend_multiplicities(RESGR);
2500
+ // Compare the total multiplicities.
2501
+ RESGR[2];
2502
+ MULT[1];
2503
+ // Compare the multiplicities.
2504
+ RESGR[3];
2505
+ MULT[2];
2506
+ }
2507
+
2508
+ proc intmat_inverse (intmat M)
2509
+ "USAGE: intmat_inverse(M); intmat M
2510
+ ASSUME: M is a lower triangular integer matrix with diagonal entries 1 or -1
2511
+ RETURN: intmat, the inverse of M
2512
+ KEYWORDS: integer matrix, inverse
2513
+ EXAMPLE: example intmat_inverse; shows an example
2514
+ "
2515
+ {
2516
+ int i,j,k;
2517
+ int n=nrows(M);
2518
+ intmat U[n][n];
2519
+ U=U+1;
2520
+ for (i=1;i<=n;i++)
2521
+ {
2522
+ if (M[i,i]==-1)
2523
+ {
2524
+ M=addmultiplrows(M,i,i,-1,0);
2525
+ U=addmultiplrows(U,i,i,-1,0);
2526
+ }
2527
+ for (j=i+1;j<=n;j++)
2528
+ {
2529
+ U=addmultiplrows(U,i,j,-M[j,i],M[i,i]);
2530
+ M=addmultiplrows(M,i,j,-M[j,i],M[i,i]);
2531
+ }
2532
+ }
2533
+ return(U);
2534
+ }
2535
+ example
2536
+ {
2537
+ "EXAMPLE:";echo=2;
2538
+ intmat M[5][5]=1,0,0,0,0,1,1,0,0,0,2,1,1,0,0,3,1,1,1,0,4,1,1,1,1 ;
2539
+ intmat U=intmat_inverse(M);
2540
+ print(U);
2541
+ print(U*M);
2542
+ }