passagemath-singular 10.6.31rc3__cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-singular might be problematic. Click here for more details.
- PySingular.cpython-314-x86_64-linux-gnu.so +0 -0
- passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
- passagemath_singular-10.6.31rc3.dist-info/RECORD +491 -0
- passagemath_singular-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_singular-10.6.31rc3.dist-info/top_level.txt +3 -0
- passagemath_singular.libs/libSingular-4-20aec911.4.1.so +0 -0
- passagemath_singular.libs/libcddgmp-21acf0c6.so.0.1.3 +0 -0
- passagemath_singular.libs/libfactory-4-fcee31da.4.1.so +0 -0
- passagemath_singular.libs/libflint-66e12231.so.21.0.0 +0 -0
- passagemath_singular.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
- passagemath_singular.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
- passagemath_singular.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_singular.libs/libgsl-cda90e79.so.28.0.0 +0 -0
- passagemath_singular.libs/libmpfr-82690d50.so.6.2.1 +0 -0
- passagemath_singular.libs/libntl-e6f0d543.so.44.0.1 +0 -0
- passagemath_singular.libs/libomalloc-0-5c9e866e.9.6.so +0 -0
- passagemath_singular.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_singular.libs/libpolys-4-5c0a87e0.4.1.so +0 -0
- passagemath_singular.libs/libquadmath-2284e583.so.0.0.0 +0 -0
- passagemath_singular.libs/libreadline-ea270e21.so.8.2 +0 -0
- passagemath_singular.libs/libsingular_resources-4-a1aafc6d.4.1.so +0 -0
- passagemath_singular.libs/libtinfo-ceb117d9.so.6.3 +0 -0
- sage/algebras/all__sagemath_singular.py +3 -0
- sage/algebras/fusion_rings/all.py +19 -0
- sage/algebras/fusion_rings/f_matrix.py +2448 -0
- sage/algebras/fusion_rings/fast_parallel_fmats_methods.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/fast_parallel_fmats_methods.pxd +5 -0
- sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +538 -0
- sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pxd +3 -0
- sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +331 -0
- sage/algebras/fusion_rings/fusion_double.py +899 -0
- sage/algebras/fusion_rings/fusion_ring.py +1580 -0
- sage/algebras/fusion_rings/poly_tup_engine.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/poly_tup_engine.pxd +24 -0
- sage/algebras/fusion_rings/poly_tup_engine.pyx +579 -0
- sage/algebras/fusion_rings/shm_managers.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/fusion_rings/shm_managers.pxd +24 -0
- sage/algebras/fusion_rings/shm_managers.pyx +780 -0
- sage/algebras/letterplace/all.py +1 -0
- sage/algebras/letterplace/free_algebra_element_letterplace.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/letterplace/free_algebra_element_letterplace.pxd +18 -0
- sage/algebras/letterplace/free_algebra_element_letterplace.pyx +755 -0
- sage/algebras/letterplace/free_algebra_letterplace.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/letterplace/free_algebra_letterplace.pxd +35 -0
- sage/algebras/letterplace/free_algebra_letterplace.pyx +914 -0
- sage/algebras/letterplace/letterplace_ideal.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/letterplace/letterplace_ideal.pyx +408 -0
- sage/algebras/quatalg/all.py +2 -0
- sage/algebras/quatalg/quaternion_algebra.py +4778 -0
- sage/algebras/quatalg/quaternion_algebra_cython.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
- sage/algebras/quatalg/quaternion_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/quatalg/quaternion_algebra_element.pxd +29 -0
- sage/algebras/quatalg/quaternion_algebra_element.pyx +2176 -0
- sage/all__sagemath_singular.py +11 -0
- sage/ext_data/all__sagemath_singular.py +1 -0
- sage/ext_data/singular/function_field/core.lib +98 -0
- sage/interfaces/all__sagemath_singular.py +1 -0
- sage/interfaces/singular.py +2835 -0
- sage/libs/all__sagemath_singular.py +1 -0
- sage/libs/singular/__init__.py +1 -0
- sage/libs/singular/decl.pxd +1168 -0
- sage/libs/singular/function.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/singular/function.pxd +87 -0
- sage/libs/singular/function.pyx +1901 -0
- sage/libs/singular/function_factory.py +61 -0
- sage/libs/singular/groebner_strategy.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/singular/groebner_strategy.pxd +22 -0
- sage/libs/singular/groebner_strategy.pyx +582 -0
- sage/libs/singular/option.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/singular/option.pyx +671 -0
- sage/libs/singular/polynomial.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/singular/polynomial.pxd +39 -0
- sage/libs/singular/polynomial.pyx +661 -0
- sage/libs/singular/ring.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/singular/ring.pxd +58 -0
- sage/libs/singular/ring.pyx +893 -0
- sage/libs/singular/singular.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/singular/singular.pxd +72 -0
- sage/libs/singular/singular.pyx +1944 -0
- sage/libs/singular/standard_options.py +145 -0
- sage/matrix/all__sagemath_singular.py +1 -0
- sage/matrix/matrix_mpolynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_mpolynomial_dense.pxd +7 -0
- sage/matrix/matrix_mpolynomial_dense.pyx +615 -0
- sage/rings/all__sagemath_singular.py +1 -0
- sage/rings/function_field/all__sagemath_singular.py +1 -0
- sage/rings/function_field/derivations_polymod.py +911 -0
- sage/rings/function_field/element_polymod.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/function_field/element_polymod.pyx +406 -0
- sage/rings/function_field/function_field_polymod.py +2611 -0
- sage/rings/function_field/ideal_polymod.py +1775 -0
- sage/rings/function_field/order_polymod.py +1475 -0
- sage/rings/function_field/place_polymod.py +681 -0
- sage/rings/polynomial/all__sagemath_singular.py +1 -0
- sage/rings/polynomial/multi_polynomial_ideal_libsingular.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/multi_polynomial_ideal_libsingular.pxd +5 -0
- sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +339 -0
- sage/rings/polynomial/multi_polynomial_libsingular.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/multi_polynomial_libsingular.pxd +30 -0
- sage/rings/polynomial/multi_polynomial_libsingular.pyx +6277 -0
- sage/rings/polynomial/plural.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/plural.pxd +48 -0
- sage/rings/polynomial/plural.pyx +3171 -0
- sage/symbolic/all__sagemath_singular.py +1 -0
- sage/symbolic/comparison_impl.pxi +428 -0
- sage/symbolic/constants_c_impl.pxi +178 -0
- sage/symbolic/expression.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/symbolic/expression.pxd +7 -0
- sage/symbolic/expression.pyx +14200 -0
- sage/symbolic/getitem_impl.pxi +202 -0
- sage/symbolic/pynac.pxi +572 -0
- sage/symbolic/pynac_constant_impl.pxi +133 -0
- sage/symbolic/pynac_function_impl.pxi +206 -0
- sage/symbolic/pynac_impl.pxi +2576 -0
- sage/symbolic/pynac_wrap.h +124 -0
- sage/symbolic/series_impl.pxi +272 -0
- sage/symbolic/substitution_map_impl.pxi +94 -0
- sage_wheels/bin/ESingular +0 -0
- sage_wheels/bin/Singular +0 -0
- sage_wheels/bin/TSingular +0 -0
- sage_wheels/lib/singular/MOD/cohomo.la +41 -0
- sage_wheels/lib/singular/MOD/cohomo.so +0 -0
- sage_wheels/lib/singular/MOD/customstd.la +41 -0
- sage_wheels/lib/singular/MOD/customstd.so +0 -0
- sage_wheels/lib/singular/MOD/freealgebra.la +41 -0
- sage_wheels/lib/singular/MOD/freealgebra.so +0 -0
- sage_wheels/lib/singular/MOD/gfanlib.la +41 -0
- sage_wheels/lib/singular/MOD/gfanlib.so +0 -0
- sage_wheels/lib/singular/MOD/gitfan.la +41 -0
- sage_wheels/lib/singular/MOD/gitfan.so +0 -0
- sage_wheels/lib/singular/MOD/interval.la +41 -0
- sage_wheels/lib/singular/MOD/interval.so +0 -0
- sage_wheels/lib/singular/MOD/loctriv.la +41 -0
- sage_wheels/lib/singular/MOD/loctriv.so +0 -0
- sage_wheels/lib/singular/MOD/machinelearning.la +41 -0
- sage_wheels/lib/singular/MOD/machinelearning.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldQ.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldQ.so +0 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldZp.la +41 -0
- sage_wheels/lib/singular/MOD/p_Procs_FieldZp.so +0 -0
- sage_wheels/lib/singular/MOD/partialgb.la +41 -0
- sage_wheels/lib/singular/MOD/partialgb.so +0 -0
- sage_wheels/lib/singular/MOD/pyobject.la +41 -0
- sage_wheels/lib/singular/MOD/pyobject.so +0 -0
- sage_wheels/lib/singular/MOD/singmathic.la +41 -0
- sage_wheels/lib/singular/MOD/singmathic.so +0 -0
- sage_wheels/lib/singular/MOD/sispasm.la +41 -0
- sage_wheels/lib/singular/MOD/sispasm.so +0 -0
- sage_wheels/lib/singular/MOD/subsets.la +41 -0
- sage_wheels/lib/singular/MOD/subsets.so +0 -0
- sage_wheels/lib/singular/MOD/systhreads.la +41 -0
- sage_wheels/lib/singular/MOD/systhreads.so +0 -0
- sage_wheels/lib/singular/MOD/syzextra.la +41 -0
- sage_wheels/lib/singular/MOD/syzextra.so +0 -0
- sage_wheels/libexec/singular/MOD/change_cost +0 -0
- sage_wheels/libexec/singular/MOD/singularsurf +11 -0
- sage_wheels/libexec/singular/MOD/singularsurf_jupyter +9 -0
- sage_wheels/libexec/singular/MOD/singularsurf_win +10 -0
- sage_wheels/libexec/singular/MOD/solve_IP +0 -0
- sage_wheels/libexec/singular/MOD/surfex +16 -0
- sage_wheels/libexec/singular/MOD/toric_ideal +0 -0
- sage_wheels/share/factory/gftables/10201 +342 -0
- sage_wheels/share/factory/gftables/1024 +37 -0
- sage_wheels/share/factory/gftables/10609 +356 -0
- sage_wheels/share/factory/gftables/11449 +384 -0
- sage_wheels/share/factory/gftables/11881 +398 -0
- sage_wheels/share/factory/gftables/121 +6 -0
- sage_wheels/share/factory/gftables/12167 +408 -0
- sage_wheels/share/factory/gftables/125 +7 -0
- sage_wheels/share/factory/gftables/12769 +428 -0
- sage_wheels/share/factory/gftables/128 +7 -0
- sage_wheels/share/factory/gftables/1331 +47 -0
- sage_wheels/share/factory/gftables/1369 +48 -0
- sage_wheels/share/factory/gftables/14641 +490 -0
- sage_wheels/share/factory/gftables/15625 +523 -0
- sage_wheels/share/factory/gftables/16 +3 -0
- sage_wheels/share/factory/gftables/16129 +540 -0
- sage_wheels/share/factory/gftables/16384 +549 -0
- sage_wheels/share/factory/gftables/16807 +563 -0
- sage_wheels/share/factory/gftables/1681 +58 -0
- sage_wheels/share/factory/gftables/169 +8 -0
- sage_wheels/share/factory/gftables/17161 +574 -0
- sage_wheels/share/factory/gftables/1849 +64 -0
- sage_wheels/share/factory/gftables/18769 +628 -0
- sage_wheels/share/factory/gftables/19321 +646 -0
- sage_wheels/share/factory/gftables/19683 +659 -0
- sage_wheels/share/factory/gftables/2048 +71 -0
- sage_wheels/share/factory/gftables/2187 +75 -0
- sage_wheels/share/factory/gftables/2197 +76 -0
- sage_wheels/share/factory/gftables/2209 +76 -0
- sage_wheels/share/factory/gftables/22201 +742 -0
- sage_wheels/share/factory/gftables/22801 +762 -0
- sage_wheels/share/factory/gftables/2401 +82 -0
- sage_wheels/share/factory/gftables/243 +11 -0
- sage_wheels/share/factory/gftables/24389 +815 -0
- sage_wheels/share/factory/gftables/24649 +824 -0
- sage_wheels/share/factory/gftables/25 +3 -0
- sage_wheels/share/factory/gftables/256 +11 -0
- sage_wheels/share/factory/gftables/26569 +888 -0
- sage_wheels/share/factory/gftables/27 +3 -0
- sage_wheels/share/factory/gftables/27889 +932 -0
- sage_wheels/share/factory/gftables/2809 +96 -0
- sage_wheels/share/factory/gftables/28561 +954 -0
- sage_wheels/share/factory/gftables/289 +12 -0
- sage_wheels/share/factory/gftables/29791 +995 -0
- sage_wheels/share/factory/gftables/29929 +1000 -0
- sage_wheels/share/factory/gftables/3125 +107 -0
- sage_wheels/share/factory/gftables/32 +4 -0
- sage_wheels/share/factory/gftables/32041 +1070 -0
- sage_wheels/share/factory/gftables/32761 +1094 -0
- sage_wheels/share/factory/gftables/32768 +1095 -0
- sage_wheels/share/factory/gftables/343 +14 -0
- sage_wheels/share/factory/gftables/3481 +118 -0
- sage_wheels/share/factory/gftables/361 +14 -0
- sage_wheels/share/factory/gftables/36481 +1218 -0
- sage_wheels/share/factory/gftables/3721 +126 -0
- sage_wheels/share/factory/gftables/37249 +1244 -0
- sage_wheels/share/factory/gftables/38809 +1296 -0
- sage_wheels/share/factory/gftables/39601 +1322 -0
- sage_wheels/share/factory/gftables/4 +3 -0
- sage_wheels/share/factory/gftables/4096 +139 -0
- sage_wheels/share/factory/gftables/44521 +1486 -0
- sage_wheels/share/factory/gftables/4489 +152 -0
- sage_wheels/share/factory/gftables/49 +4 -0
- sage_wheels/share/factory/gftables/4913 +166 -0
- sage_wheels/share/factory/gftables/49729 +1660 -0
- sage_wheels/share/factory/gftables/5041 +170 -0
- sage_wheels/share/factory/gftables/50653 +1691 -0
- sage_wheels/share/factory/gftables/512 +20 -0
- sage_wheels/share/factory/gftables/51529 +1720 -0
- sage_wheels/share/factory/gftables/52441 +1750 -0
- sage_wheels/share/factory/gftables/529 +20 -0
- sage_wheels/share/factory/gftables/5329 +180 -0
- sage_wheels/share/factory/gftables/54289 +1812 -0
- sage_wheels/share/factory/gftables/57121 +1906 -0
- sage_wheels/share/factory/gftables/58081 +1938 -0
- sage_wheels/share/factory/gftables/59049 +1971 -0
- sage_wheels/share/factory/gftables/6241 +210 -0
- sage_wheels/share/factory/gftables/625 +23 -0
- sage_wheels/share/factory/gftables/63001 +2102 -0
- sage_wheels/share/factory/gftables/64 +5 -0
- sage_wheels/share/factory/gftables/6561 +221 -0
- sage_wheels/share/factory/gftables/6859 +231 -0
- sage_wheels/share/factory/gftables/6889 +232 -0
- sage_wheels/share/factory/gftables/729 +27 -0
- sage_wheels/share/factory/gftables/7921 +266 -0
- sage_wheels/share/factory/gftables/8 +3 -0
- sage_wheels/share/factory/gftables/81 +5 -0
- sage_wheels/share/factory/gftables/8192 +276 -0
- sage_wheels/share/factory/gftables/841 +30 -0
- sage_wheels/share/factory/gftables/9 +3 -0
- sage_wheels/share/factory/gftables/9409 +316 -0
- sage_wheels/share/factory/gftables/961 +34 -0
- sage_wheels/share/info/singular.info +191898 -0
- sage_wheels/share/singular/LIB/GND.lib +1359 -0
- sage_wheels/share/singular/LIB/JMBTest.lib +976 -0
- sage_wheels/share/singular/LIB/JMSConst.lib +1363 -0
- sage_wheels/share/singular/LIB/KVequiv.lib +699 -0
- sage_wheels/share/singular/LIB/SingularityDBM.lib +491 -0
- sage_wheels/share/singular/LIB/VecField.lib +1542 -0
- sage_wheels/share/singular/LIB/absfact.lib +959 -0
- sage_wheels/share/singular/LIB/ainvar.lib +730 -0
- sage_wheels/share/singular/LIB/aksaka.lib +419 -0
- sage_wheels/share/singular/LIB/alexpoly.lib +2542 -0
- sage_wheels/share/singular/LIB/algebra.lib +1193 -0
- sage_wheels/share/singular/LIB/all.lib +136 -0
- sage_wheels/share/singular/LIB/arcpoint.lib +514 -0
- sage_wheels/share/singular/LIB/arnold.lib +4553 -0
- sage_wheels/share/singular/LIB/arnoldclassify.lib +2058 -0
- sage_wheels/share/singular/LIB/arr.lib +3486 -0
- sage_wheels/share/singular/LIB/assprimeszerodim.lib +755 -0
- sage_wheels/share/singular/LIB/autgradalg.lib +3361 -0
- sage_wheels/share/singular/LIB/bfun.lib +1964 -0
- sage_wheels/share/singular/LIB/bimodules.lib +774 -0
- sage_wheels/share/singular/LIB/brillnoether.lib +226 -0
- sage_wheels/share/singular/LIB/brnoeth.lib +5017 -0
- sage_wheels/share/singular/LIB/central.lib +2169 -0
- sage_wheels/share/singular/LIB/chern.lib +4162 -0
- sage_wheels/share/singular/LIB/cimonom.lib +571 -0
- sage_wheels/share/singular/LIB/cisimplicial.lib +1835 -0
- sage_wheels/share/singular/LIB/classify.lib +3239 -0
- sage_wheels/share/singular/LIB/classify2.lib +1462 -0
- sage_wheels/share/singular/LIB/classifyMapGerms.lib +1515 -0
- sage_wheels/share/singular/LIB/classify_aeq.lib +3253 -0
- sage_wheels/share/singular/LIB/classifyceq.lib +2092 -0
- sage_wheels/share/singular/LIB/classifyci.lib +1133 -0
- sage_wheels/share/singular/LIB/combinat.lib +91 -0
- sage_wheels/share/singular/LIB/compregb.lib +276 -0
- sage_wheels/share/singular/LIB/control.lib +1636 -0
- sage_wheels/share/singular/LIB/crypto.lib +3795 -0
- sage_wheels/share/singular/LIB/curveInv.lib +667 -0
- sage_wheels/share/singular/LIB/curvepar.lib +1817 -0
- sage_wheels/share/singular/LIB/customstd.lib +100 -0
- sage_wheels/share/singular/LIB/deRham.lib +5979 -0
- sage_wheels/share/singular/LIB/decodegb.lib +2134 -0
- sage_wheels/share/singular/LIB/decomp.lib +1655 -0
- sage_wheels/share/singular/LIB/deflation.lib +872 -0
- sage_wheels/share/singular/LIB/deform.lib +925 -0
- sage_wheels/share/singular/LIB/difform.lib +3055 -0
- sage_wheels/share/singular/LIB/divisors.lib +750 -0
- sage_wheels/share/singular/LIB/dmod.lib +5817 -0
- sage_wheels/share/singular/LIB/dmodapp.lib +3269 -0
- sage_wheels/share/singular/LIB/dmodideal.lib +1211 -0
- sage_wheels/share/singular/LIB/dmodloc.lib +2645 -0
- sage_wheels/share/singular/LIB/dmodvar.lib +818 -0
- sage_wheels/share/singular/LIB/dummy.lib +17 -0
- sage_wheels/share/singular/LIB/elim.lib +1009 -0
- sage_wheels/share/singular/LIB/ellipticcovers.lib +548 -0
- sage_wheels/share/singular/LIB/enumpoints.lib +146 -0
- sage_wheels/share/singular/LIB/equising.lib +2127 -0
- sage_wheels/share/singular/LIB/ffmodstd.lib +2384 -0
- sage_wheels/share/singular/LIB/ffsolve.lib +1289 -0
- sage_wheels/share/singular/LIB/findifs.lib +778 -0
- sage_wheels/share/singular/LIB/finitediff.lib +1768 -0
- sage_wheels/share/singular/LIB/finvar.lib +7989 -0
- sage_wheels/share/singular/LIB/fpadim.lib +2429 -0
- sage_wheels/share/singular/LIB/fpalgebras.lib +1666 -0
- sage_wheels/share/singular/LIB/fpaprops.lib +1462 -0
- sage_wheels/share/singular/LIB/freegb.lib +3853 -0
- sage_wheels/share/singular/LIB/general.lib +1350 -0
- sage_wheels/share/singular/LIB/gfan.lib +1768 -0
- sage_wheels/share/singular/LIB/gitfan.lib +3130 -0
- sage_wheels/share/singular/LIB/gkdim.lib +99 -0
- sage_wheels/share/singular/LIB/gmspoly.lib +589 -0
- sage_wheels/share/singular/LIB/gmssing.lib +1739 -0
- sage_wheels/share/singular/LIB/goettsche.lib +909 -0
- sage_wheels/share/singular/LIB/graal.lib +1366 -0
- sage_wheels/share/singular/LIB/gradedModules.lib +2541 -0
- sage_wheels/share/singular/LIB/graphics.lib +360 -0
- sage_wheels/share/singular/LIB/grobcov.lib +7706 -0
- sage_wheels/share/singular/LIB/groups.lib +1123 -0
- sage_wheels/share/singular/LIB/grwalk.lib +507 -0
- sage_wheels/share/singular/LIB/hdepth.lib +194 -0
- sage_wheels/share/singular/LIB/help.cnf +57 -0
- sage_wheels/share/singular/LIB/hess.lib +1946 -0
- sage_wheels/share/singular/LIB/hnoether.lib +4292 -0
- sage_wheels/share/singular/LIB/hodge.lib +400 -0
- sage_wheels/share/singular/LIB/homolog.lib +1965 -0
- sage_wheels/share/singular/LIB/hyperel.lib +975 -0
- sage_wheels/share/singular/LIB/inout.lib +679 -0
- sage_wheels/share/singular/LIB/integralbasis.lib +6224 -0
- sage_wheels/share/singular/LIB/interval.lib +1418 -0
- sage_wheels/share/singular/LIB/intprog.lib +778 -0
- sage_wheels/share/singular/LIB/invar.lib +443 -0
- sage_wheels/share/singular/LIB/involut.lib +980 -0
- sage_wheels/share/singular/LIB/jacobson.lib +1215 -0
- sage_wheels/share/singular/LIB/kskernel.lib +534 -0
- sage_wheels/share/singular/LIB/latex.lib +3146 -0
- sage_wheels/share/singular/LIB/lejeune.lib +651 -0
- sage_wheels/share/singular/LIB/linalg.lib +2040 -0
- sage_wheels/share/singular/LIB/locnormal.lib +212 -0
- sage_wheels/share/singular/LIB/lrcalc.lib +526 -0
- sage_wheels/share/singular/LIB/makedbm.lib +294 -0
- sage_wheels/share/singular/LIB/mathml.lib +813 -0
- sage_wheels/share/singular/LIB/matrix.lib +1372 -0
- sage_wheels/share/singular/LIB/maxlike.lib +1132 -0
- sage_wheels/share/singular/LIB/methods.lib +212 -0
- sage_wheels/share/singular/LIB/moddiq.lib +322 -0
- sage_wheels/share/singular/LIB/modfinduni.lib +181 -0
- sage_wheels/share/singular/LIB/modnormal.lib +218 -0
- sage_wheels/share/singular/LIB/modprimdec.lib +1278 -0
- sage_wheels/share/singular/LIB/modquotient.lib +269 -0
- sage_wheels/share/singular/LIB/modstd.lib +1024 -0
- sage_wheels/share/singular/LIB/modular.lib +545 -0
- sage_wheels/share/singular/LIB/modules.lib +2561 -0
- sage_wheels/share/singular/LIB/modwalk.lib +609 -0
- sage_wheels/share/singular/LIB/mondromy.lib +1016 -0
- sage_wheels/share/singular/LIB/monomialideal.lib +3851 -0
- sage_wheels/share/singular/LIB/mprimdec.lib +2353 -0
- sage_wheels/share/singular/LIB/mregular.lib +1863 -0
- sage_wheels/share/singular/LIB/multigrading.lib +5629 -0
- sage_wheels/share/singular/LIB/ncHilb.lib +777 -0
- sage_wheels/share/singular/LIB/ncModslimgb.lib +791 -0
- sage_wheels/share/singular/LIB/ncalg.lib +16311 -0
- sage_wheels/share/singular/LIB/ncall.lib +31 -0
- sage_wheels/share/singular/LIB/ncdecomp.lib +468 -0
- sage_wheels/share/singular/LIB/ncfactor.lib +13371 -0
- sage_wheels/share/singular/LIB/ncfrac.lib +1023 -0
- sage_wheels/share/singular/LIB/nchilbert.lib +448 -0
- sage_wheels/share/singular/LIB/nchomolog.lib +759 -0
- sage_wheels/share/singular/LIB/ncloc.lib +361 -0
- sage_wheels/share/singular/LIB/ncpreim.lib +795 -0
- sage_wheels/share/singular/LIB/ncrat.lib +2849 -0
- sage_wheels/share/singular/LIB/nctools.lib +1887 -0
- sage_wheels/share/singular/LIB/nets.lib +1456 -0
- sage_wheels/share/singular/LIB/nfmodstd.lib +1000 -0
- sage_wheels/share/singular/LIB/nfmodsyz.lib +732 -0
- sage_wheels/share/singular/LIB/noether.lib +1106 -0
- sage_wheels/share/singular/LIB/normal.lib +8700 -0
- sage_wheels/share/singular/LIB/normaliz.lib +2226 -0
- sage_wheels/share/singular/LIB/ntsolve.lib +362 -0
- sage_wheels/share/singular/LIB/numerAlg.lib +560 -0
- sage_wheels/share/singular/LIB/numerDecom.lib +2261 -0
- sage_wheels/share/singular/LIB/olga.lib +1933 -0
- sage_wheels/share/singular/LIB/orbitparam.lib +351 -0
- sage_wheels/share/singular/LIB/parallel.lib +319 -0
- sage_wheels/share/singular/LIB/paraplanecurves.lib +3110 -0
- sage_wheels/share/singular/LIB/perron.lib +202 -0
- sage_wheels/share/singular/LIB/pfd.lib +2223 -0
- sage_wheels/share/singular/LIB/phindex.lib +642 -0
- sage_wheels/share/singular/LIB/pointid.lib +673 -0
- sage_wheels/share/singular/LIB/polybori.lib +1430 -0
- sage_wheels/share/singular/LIB/polyclass.lib +525 -0
- sage_wheels/share/singular/LIB/polylib.lib +1174 -0
- sage_wheels/share/singular/LIB/polymake.lib +1902 -0
- sage_wheels/share/singular/LIB/presolve.lib +1533 -0
- sage_wheels/share/singular/LIB/primdec.lib +9576 -0
- sage_wheels/share/singular/LIB/primdecint.lib +1782 -0
- sage_wheels/share/singular/LIB/primitiv.lib +401 -0
- sage_wheels/share/singular/LIB/puiseuxexpansions.lib +1631 -0
- sage_wheels/share/singular/LIB/purityfiltration.lib +960 -0
- sage_wheels/share/singular/LIB/qhmoduli.lib +1561 -0
- sage_wheels/share/singular/LIB/qmatrix.lib +293 -0
- sage_wheels/share/singular/LIB/random.lib +455 -0
- sage_wheels/share/singular/LIB/ratgb.lib +489 -0
- sage_wheels/share/singular/LIB/realclassify.lib +5759 -0
- sage_wheels/share/singular/LIB/realizationMatroids.lib +772 -0
- sage_wheels/share/singular/LIB/realrad.lib +1197 -0
- sage_wheels/share/singular/LIB/recover.lib +2628 -0
- sage_wheels/share/singular/LIB/redcgs.lib +3984 -0
- sage_wheels/share/singular/LIB/reesclos.lib +465 -0
- sage_wheels/share/singular/LIB/resbinomial.lib +2802 -0
- sage_wheels/share/singular/LIB/resgraph.lib +789 -0
- sage_wheels/share/singular/LIB/resjung.lib +820 -0
- sage_wheels/share/singular/LIB/resolve.lib +5110 -0
- sage_wheels/share/singular/LIB/resources.lib +170 -0
- sage_wheels/share/singular/LIB/reszeta.lib +5473 -0
- sage_wheels/share/singular/LIB/ring.lib +1328 -0
- sage_wheels/share/singular/LIB/ringgb.lib +343 -0
- sage_wheels/share/singular/LIB/rinvar.lib +1153 -0
- sage_wheels/share/singular/LIB/rootisolation.lib +1481 -0
- sage_wheels/share/singular/LIB/rootsmr.lib +709 -0
- sage_wheels/share/singular/LIB/rootsur.lib +886 -0
- sage_wheels/share/singular/LIB/rstandard.lib +607 -0
- sage_wheels/share/singular/LIB/rwalk.lib +336 -0
- sage_wheels/share/singular/LIB/sagbi.lib +1353 -0
- sage_wheels/share/singular/LIB/sagbiNormaliz.lib +1622 -0
- sage_wheels/share/singular/LIB/sagbiNormaliz0.lib +1498 -0
- sage_wheels/share/singular/LIB/sagbigrob.lib +449 -0
- sage_wheels/share/singular/LIB/schreyer.lib +321 -0
- sage_wheels/share/singular/LIB/schubert.lib +2551 -0
- sage_wheels/share/singular/LIB/sets.lib +524 -0
- sage_wheels/share/singular/LIB/sheafcoh.lib +1663 -0
- sage_wheels/share/singular/LIB/signcond.lib +437 -0
- sage_wheels/share/singular/LIB/sing.lib +1094 -0
- sage_wheels/share/singular/LIB/sing4ti2.lib +419 -0
- sage_wheels/share/singular/LIB/solve.lib +2243 -0
- sage_wheels/share/singular/LIB/spcurve.lib +1077 -0
- sage_wheels/share/singular/LIB/spectrum.lib +62 -0
- sage_wheels/share/singular/LIB/sresext.lib +757 -0
- sage_wheels/share/singular/LIB/ssi.lib +143 -0
- sage_wheels/share/singular/LIB/standard.lib +2769 -0
- sage_wheels/share/singular/LIB/stanleyreisner.lib +473 -0
- sage_wheels/share/singular/LIB/stdmodule.lib +547 -0
- sage_wheels/share/singular/LIB/stratify.lib +1070 -0
- sage_wheels/share/singular/LIB/surf.lib +506 -0
- sage_wheels/share/singular/LIB/surf_jupyter.lib +223 -0
- sage_wheels/share/singular/LIB/surfacesignature.lib +522 -0
- sage_wheels/share/singular/LIB/surfex.lib +1462 -0
- sage_wheels/share/singular/LIB/swalk.lib +877 -0
- sage_wheels/share/singular/LIB/symodstd.lib +1570 -0
- sage_wheels/share/singular/LIB/systhreads.lib +74 -0
- sage_wheels/share/singular/LIB/tasks.lib +1324 -0
- sage_wheels/share/singular/LIB/tateProdCplxNegGrad.lib +2412 -0
- sage_wheels/share/singular/LIB/teachstd.lib +858 -0
- sage_wheels/share/singular/LIB/template.lib +116 -0
- sage_wheels/share/singular/LIB/toric.lib +1119 -0
- sage_wheels/share/singular/LIB/transformation.lib +116 -0
- sage_wheels/share/singular/LIB/triang.lib +1197 -0
- sage_wheels/share/singular/LIB/tropical.lib +8741 -0
- sage_wheels/share/singular/LIB/tropicalEllipticCovers.lib +2922 -0
- sage_wheels/share/singular/LIB/tropicalNewton.lib +1128 -0
- sage_wheels/share/singular/LIB/tst.lib +1108 -0
- sage_wheels/share/singular/LIB/weierstr.lib +241 -0
- sage_wheels/share/singular/LIB/zeroset.lib +1478 -0
- sage_wheels/share/singular/emacs/.emacs-general +184 -0
- sage_wheels/share/singular/emacs/.emacs-singular +234 -0
- sage_wheels/share/singular/emacs/COPYING +44 -0
- sage_wheels/share/singular/emacs/cmd-cmpl.el +241 -0
- sage_wheels/share/singular/emacs/ex-cmpl.el +1681 -0
- sage_wheels/share/singular/emacs/hlp-cmpl.el +4318 -0
- sage_wheels/share/singular/emacs/lib-cmpl.el +179 -0
- sage_wheels/share/singular/emacs/singular.el +4273 -0
- sage_wheels/share/singular/emacs/singular.xpm +39 -0
- 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
|
+
}
|