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