passagemath-singular 10.6.31rc3__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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-aarch64-linux-gnu.so +0 -0
- passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
- passagemath_singular-10.6.31rc3.dist-info/RECORD +490 -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-6a2a8666.4.1.so +0 -0
- passagemath_singular.libs/libcddgmp-ac579979.so.0.1.3 +0 -0
- passagemath_singular.libs/libfactory-4-66e33516.4.1.so +0 -0
- passagemath_singular.libs/libflint-81de1160.so.21.0.0 +0 -0
- passagemath_singular.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
- passagemath_singular.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
- passagemath_singular.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_singular.libs/libgsl-e3525837.so.28.0.0 +0 -0
- passagemath_singular.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
- passagemath_singular.libs/libntl-0043a3a2.so.44.0.1 +0 -0
- passagemath_singular.libs/libomalloc-0-06512335.9.6.so +0 -0
- passagemath_singular.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
- passagemath_singular.libs/libpolys-4-cb7246b5.4.1.so +0 -0
- passagemath_singular.libs/libreadline-28330744.so.8.2 +0 -0
- passagemath_singular.libs/libsingular_resources-4-8c425241.4.1.so +0 -0
- passagemath_singular.libs/libtinfo-f81c2d16.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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
- sage/algebras/quatalg/quaternion_algebra_element.cpython-314-aarch64-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-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/libs/singular/option.pyx +671 -0
- sage/libs/singular/polynomial.cpython-314-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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,3171 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-singular
|
|
2
|
+
# sage.doctest: needs sage.combinat
|
|
3
|
+
r"""
|
|
4
|
+
Noncommutative polynomials via libSINGULAR/Plural
|
|
5
|
+
|
|
6
|
+
This module provides specialized and optimized implementations for
|
|
7
|
+
noncommutative multivariate polynomials over many coefficient rings, via the
|
|
8
|
+
shared library interface to SINGULAR. In particular, the following coefficient
|
|
9
|
+
rings are supported by this implementation:
|
|
10
|
+
|
|
11
|
+
- the rational numbers `\QQ`, and
|
|
12
|
+
|
|
13
|
+
- finite fields `\GF{p}` for `p` prime
|
|
14
|
+
|
|
15
|
+
AUTHORS:
|
|
16
|
+
|
|
17
|
+
The PLURAL wrapper is due to
|
|
18
|
+
|
|
19
|
+
- Burcin Erocal (2008-11 and 2010-07): initial implementation and concept
|
|
20
|
+
|
|
21
|
+
- Michael Brickenstein (2008-11 and 2010-07): initial implementation and concept
|
|
22
|
+
|
|
23
|
+
- Oleksandr Motsak (2010-07): complete overall noncommutative functionality and first release
|
|
24
|
+
|
|
25
|
+
- Alexander Dreyer (2010-07): noncommutative ring functionality and documentation
|
|
26
|
+
|
|
27
|
+
- Simon King (2011-09): left and two-sided ideals; normal forms; pickling;
|
|
28
|
+
documentation
|
|
29
|
+
|
|
30
|
+
The underlying libSINGULAR interface was implemented by
|
|
31
|
+
|
|
32
|
+
- Martin Albrecht (2007-01): initial implementation
|
|
33
|
+
|
|
34
|
+
- Joel Mohler (2008-01): misc improvements, polishing
|
|
35
|
+
|
|
36
|
+
- Martin Albrecht (2008-08): added `\QQ(a)` and `\ZZ` support
|
|
37
|
+
|
|
38
|
+
- Simon King (2009-04): improved coercion
|
|
39
|
+
|
|
40
|
+
- Martin Albrecht (2009-05): added `\ZZ/n\ZZ` support, refactoring
|
|
41
|
+
|
|
42
|
+
- Martin Albrecht (2009-06): refactored the code to allow better re-use
|
|
43
|
+
|
|
44
|
+
.. TODO::
|
|
45
|
+
|
|
46
|
+
extend functionality towards those of libSINGULARs commutative part
|
|
47
|
+
|
|
48
|
+
EXAMPLES:
|
|
49
|
+
|
|
50
|
+
We show how to construct various noncommutative polynomial rings::
|
|
51
|
+
|
|
52
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
53
|
+
sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
54
|
+
|
|
55
|
+
sage: P
|
|
56
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
|
|
57
|
+
|
|
58
|
+
sage: y*x + 1/2
|
|
59
|
+
-x*y + 1/2
|
|
60
|
+
|
|
61
|
+
sage: A.<x,y,z> = FreeAlgebra(GF(17), 3)
|
|
62
|
+
sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
63
|
+
sage: P
|
|
64
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 17, nc-relations: {y*x: -x*y}
|
|
65
|
+
|
|
66
|
+
sage: y*x + 7
|
|
67
|
+
-x*y + 7
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Raw use of this class; *this is not the intended use!*
|
|
71
|
+
::
|
|
72
|
+
|
|
73
|
+
sage: from sage.matrix.constructor import Matrix
|
|
74
|
+
sage: c = Matrix(3)
|
|
75
|
+
sage: c[0,1] = -2
|
|
76
|
+
sage: c[0,2] = 1
|
|
77
|
+
sage: c[1,2] = 1
|
|
78
|
+
|
|
79
|
+
sage: d = Matrix(3)
|
|
80
|
+
sage: d[0, 1] = 17
|
|
81
|
+
sage: P = QQ['x','y','z']
|
|
82
|
+
sage: c = c.change_ring(P)
|
|
83
|
+
sage: d = d.change_ring(P)
|
|
84
|
+
|
|
85
|
+
sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
|
|
86
|
+
sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, c = c, d = d, order=TermOrder('lex',3),category=Algebras(QQ))
|
|
87
|
+
sage: R
|
|
88
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -2*x*y + 17}
|
|
89
|
+
|
|
90
|
+
sage: R.term_order()
|
|
91
|
+
Lexicographic term order
|
|
92
|
+
|
|
93
|
+
sage: a,b,c = R.gens()
|
|
94
|
+
sage: f = 57 * a^2*b + 43 * c + 1; f
|
|
95
|
+
57*x^2*y + 43*z + 1
|
|
96
|
+
|
|
97
|
+
TESTS::
|
|
98
|
+
|
|
99
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
100
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
101
|
+
sage: TestSuite(P).run()
|
|
102
|
+
sage: loads(dumps(P)) is P
|
|
103
|
+
True
|
|
104
|
+
|
|
105
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
106
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
107
|
+
sage: P.is_commutative()
|
|
108
|
+
False
|
|
109
|
+
|
|
110
|
+
sage: R.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
111
|
+
sage: P = R.g_algebra(relations={}, order='lex')
|
|
112
|
+
sage: P.is_commutative()
|
|
113
|
+
True
|
|
114
|
+
"""
|
|
115
|
+
from cysignals.memory cimport sig_malloc, sig_free
|
|
116
|
+
|
|
117
|
+
from sage.categories.algebras import Algebras
|
|
118
|
+
from sage.cpython.string cimport char_to_str
|
|
119
|
+
|
|
120
|
+
# singular rings
|
|
121
|
+
|
|
122
|
+
from sage.libs.singular.ring cimport singular_ring_delete, wrap_ring, singular_ring_reference
|
|
123
|
+
|
|
124
|
+
from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
from sage.libs.singular.function cimport RingWrap
|
|
128
|
+
|
|
129
|
+
from sage.libs.singular.polynomial cimport (singular_polynomial_cmp, singular_polynomial_add, singular_polynomial_sub, singular_polynomial_neg, singular_polynomial_pow, singular_polynomial_mul, singular_polynomial_rmul, singular_polynomial_deg, singular_polynomial_str_with_changed_varnames, singular_polynomial_latex, singular_polynomial_str, singular_polynomial_div_coeff)
|
|
130
|
+
|
|
131
|
+
import sage.libs.singular.ring
|
|
132
|
+
|
|
133
|
+
from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn
|
|
134
|
+
from sage.rings.integer cimport Integer
|
|
135
|
+
from sage.rings.integer_ring import IntegerRing_class
|
|
136
|
+
|
|
137
|
+
from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular, MPolynomial_libsingular, new_MP
|
|
138
|
+
from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal
|
|
139
|
+
|
|
140
|
+
from sage.rings.polynomial.polydict import ETuple
|
|
141
|
+
from sage.rings.ring import CommutativeRing
|
|
142
|
+
from sage.structure.category_object cimport check_default_category
|
|
143
|
+
from sage.structure.element cimport CommutativeRingElement, Element, RingElement
|
|
144
|
+
from sage.structure.factory import UniqueFactory
|
|
145
|
+
from sage.structure.richcmp cimport rich_to_bool
|
|
146
|
+
from sage.structure.parent cimport Parent
|
|
147
|
+
from sage.rings.polynomial.term_order import TermOrder
|
|
148
|
+
|
|
149
|
+
from sage.misc.functional import coerce
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class G_AlgFactory(UniqueFactory):
|
|
153
|
+
"""
|
|
154
|
+
A factory for the creation of g-algebras as unique parents.
|
|
155
|
+
|
|
156
|
+
TESTS::
|
|
157
|
+
|
|
158
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
159
|
+
sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
160
|
+
sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) # indirect doctest
|
|
161
|
+
True
|
|
162
|
+
"""
|
|
163
|
+
def create_object(self, version, key, **extra_args):
|
|
164
|
+
"""
|
|
165
|
+
Create a g-algebra to a given unique key.
|
|
166
|
+
|
|
167
|
+
INPUT:
|
|
168
|
+
|
|
169
|
+
- ``key`` -- a 6-tuple, formed by a base ring, a tuple of names, two
|
|
170
|
+
matrices over a polynomial ring over the base ring with the given
|
|
171
|
+
variable names, a term order, and a category
|
|
172
|
+
- ``extra_args`` -- dictionary, whose only relevant key is 'check'
|
|
173
|
+
|
|
174
|
+
TESTS::
|
|
175
|
+
|
|
176
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
177
|
+
sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
178
|
+
sage: sorted(H.relations().items(), key=str)
|
|
179
|
+
[(y*x, x*y - z), (z*x, x*z + 2*x), (z*y, y*z - 2*y)]
|
|
180
|
+
"""
|
|
181
|
+
# key = (base_ring,names, c,d, order, category)
|
|
182
|
+
# extra args: check
|
|
183
|
+
base_ring,names, c, d, order, category = key
|
|
184
|
+
check = extra_args.get('check')
|
|
185
|
+
return NCPolynomialRing_plural(base_ring, names, c, d, order,
|
|
186
|
+
category, check)
|
|
187
|
+
|
|
188
|
+
def create_key_and_extra_args(self, base_ring, c, d, names=None, order=None,
|
|
189
|
+
category=None, check=None, commutative=None):
|
|
190
|
+
"""
|
|
191
|
+
Create a unique key for g-algebras.
|
|
192
|
+
|
|
193
|
+
INPUT:
|
|
194
|
+
|
|
195
|
+
- ``base_ring`` -- a ring
|
|
196
|
+
- ``c``, ``d`` -- two matrices
|
|
197
|
+
- ``names`` -- tuple or list of names
|
|
198
|
+
- ``order`` -- (optional) term order
|
|
199
|
+
- ``category`` -- (optional) category
|
|
200
|
+
- ``check`` -- (optional) boolean
|
|
201
|
+
- ``commutative`` -- (optional) boolean
|
|
202
|
+
|
|
203
|
+
TESTS::
|
|
204
|
+
|
|
205
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
206
|
+
sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
207
|
+
sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) # indirect doctest
|
|
208
|
+
True
|
|
209
|
+
|
|
210
|
+
sage: P = A.g_algebra(relations={}, order='lex')
|
|
211
|
+
sage: P.category()
|
|
212
|
+
Category of commutative algebras over Rational Field
|
|
213
|
+
"""
|
|
214
|
+
if names is None:
|
|
215
|
+
raise ValueError("The generator names must be provided")
|
|
216
|
+
|
|
217
|
+
# Get the number of names:
|
|
218
|
+
names = tuple(names)
|
|
219
|
+
n = len(names)
|
|
220
|
+
if not isinstance(order, TermOrder):
|
|
221
|
+
order = TermOrder(order or 'degrevlex', n)
|
|
222
|
+
|
|
223
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
224
|
+
P = PolynomialRing(base_ring, n, names, order=order)
|
|
225
|
+
# The names may have been normalised in P:
|
|
226
|
+
names = P.variable_names()
|
|
227
|
+
c = c.change_ring(P)
|
|
228
|
+
c.set_immutable()
|
|
229
|
+
d = d.change_ring(P)
|
|
230
|
+
d.set_immutable()
|
|
231
|
+
|
|
232
|
+
# Get the correct category
|
|
233
|
+
if commutative:
|
|
234
|
+
usualcat = Algebras(base_ring).Commutative()
|
|
235
|
+
else:
|
|
236
|
+
usualcat = Algebras(base_ring)
|
|
237
|
+
category = check_default_category(usualcat, category)
|
|
238
|
+
|
|
239
|
+
# Extra arg
|
|
240
|
+
if check is None:
|
|
241
|
+
return (base_ring, names, c, d, order, category), {}
|
|
242
|
+
return (base_ring, names, c, d, order, category), {'check':check}
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
g_Algebra = G_AlgFactory('sage.rings.polynomial.plural.g_Algebra')
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
cdef class NCPolynomialRing_plural(Ring):
|
|
249
|
+
"""
|
|
250
|
+
A non-commutative polynomial ring.
|
|
251
|
+
|
|
252
|
+
EXAMPLES::
|
|
253
|
+
|
|
254
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
255
|
+
sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
256
|
+
sage: H._is_category_initialized()
|
|
257
|
+
True
|
|
258
|
+
sage: H.category()
|
|
259
|
+
Category of algebras over Rational Field
|
|
260
|
+
sage: TestSuite(H).run()
|
|
261
|
+
|
|
262
|
+
Note that two variables commute if they are not part of the given
|
|
263
|
+
relations::
|
|
264
|
+
|
|
265
|
+
sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y})
|
|
266
|
+
sage: x*y == y*x
|
|
267
|
+
True
|
|
268
|
+
"""
|
|
269
|
+
def __init__(self, base_ring, names, c, d, order, category, check=True):
|
|
270
|
+
r"""
|
|
271
|
+
Construct a noncommutative polynomial G-algebra subject to the following conditions:
|
|
272
|
+
|
|
273
|
+
INPUT:
|
|
274
|
+
|
|
275
|
+
- ``base_ring`` -- base ring (must be either `\GF{q}`, `\ZZ`, `\ZZ/n\ZZ`, `\QQ` or absolute number field)
|
|
276
|
+
- ``names`` -- tuple of names of ring variables
|
|
277
|
+
- ``c``, ``d`` -- upper triangular matrices of coefficients,
|
|
278
|
+
resp. commutative polynomials, satisfying the nondegeneracy
|
|
279
|
+
conditions, which are to be tested if ``check`` is ``True``. These
|
|
280
|
+
matrices describe the noncommutative relations:
|
|
281
|
+
|
|
282
|
+
``self.gen(j)*self.gen(i) == c[i, j] * self.gen(i)*self.gen(j) + d[i, j],``
|
|
283
|
+
|
|
284
|
+
where ``0 <= i < j < self.ngens()``. Note that two variables
|
|
285
|
+
commute if they are not part of one of these relations.
|
|
286
|
+
- ``order`` -- term order
|
|
287
|
+
- ``check`` -- check the noncommutative conditions (default: ``True``)
|
|
288
|
+
|
|
289
|
+
TESTS:
|
|
290
|
+
|
|
291
|
+
It is strongly recommended to construct a g-algebra using
|
|
292
|
+
:class:`G_AlgFactory`. The following is just for documenting
|
|
293
|
+
the arguments of the ``__init__`` method::
|
|
294
|
+
|
|
295
|
+
sage: from sage.matrix.constructor import Matrix
|
|
296
|
+
sage: c0 = Matrix(3)
|
|
297
|
+
sage: c0[0,1] = -1
|
|
298
|
+
sage: c0[0,2] = 1
|
|
299
|
+
sage: c0[1,2] = 1
|
|
300
|
+
|
|
301
|
+
sage: d0 = Matrix(3)
|
|
302
|
+
sage: d0[0, 1] = 17
|
|
303
|
+
sage: P = QQ['x','y','z']
|
|
304
|
+
sage: c = c0.change_ring(P)
|
|
305
|
+
sage: d = d0.change_ring(P)
|
|
306
|
+
|
|
307
|
+
sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
|
|
308
|
+
sage: P.<x,y,z> = NCPolynomialRing_plural(QQ, c = c, d = d, order=TermOrder('lex',3), category=Algebras(QQ))
|
|
309
|
+
|
|
310
|
+
sage: P # indirect doctest
|
|
311
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y + 17}
|
|
312
|
+
|
|
313
|
+
sage: P(x*y)
|
|
314
|
+
x*y
|
|
315
|
+
|
|
316
|
+
sage: f = 27/113 * x^2 + y*z + 1/2; f
|
|
317
|
+
27/113*x^2 + y*z + 1/2
|
|
318
|
+
|
|
319
|
+
sage: P.term_order()
|
|
320
|
+
Lexicographic term order
|
|
321
|
+
|
|
322
|
+
sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
|
|
323
|
+
sage: P = GF(7)['x','y','z']
|
|
324
|
+
sage: c = c0.change_ring(P)
|
|
325
|
+
sage: d = d0.change_ring(P)
|
|
326
|
+
sage: P.<x,y,z> = NCPolynomialRing_plural(GF(7), c = c, d = d, order=TermOrder('degrevlex',3), category=Algebras(GF(7)))
|
|
327
|
+
|
|
328
|
+
sage: P # indirect doctest
|
|
329
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 7, nc-relations: {y*x: -x*y + 3}
|
|
330
|
+
|
|
331
|
+
sage: P(x*y)
|
|
332
|
+
x*y
|
|
333
|
+
|
|
334
|
+
sage: f = 3 * x^2 + y*z + 5; f
|
|
335
|
+
3*x^2 + y*z - 2
|
|
336
|
+
|
|
337
|
+
sage: P.term_order()
|
|
338
|
+
Degree reverse lexicographic term order
|
|
339
|
+
"""
|
|
340
|
+
n = len(names)
|
|
341
|
+
self._relations = None
|
|
342
|
+
|
|
343
|
+
P = c.base_ring()
|
|
344
|
+
self._c = c
|
|
345
|
+
self._d = d
|
|
346
|
+
|
|
347
|
+
from sage.libs.singular.function import singular_function
|
|
348
|
+
ncalgebra = singular_function('nc_algebra')
|
|
349
|
+
|
|
350
|
+
cdef RingWrap rw = ncalgebra(self._c, self._d, ring=P)
|
|
351
|
+
|
|
352
|
+
# rw._output()
|
|
353
|
+
self._ring = singular_ring_reference(rw._ring)
|
|
354
|
+
self._ring.ShortOut = 0
|
|
355
|
+
|
|
356
|
+
self._ngens = n
|
|
357
|
+
self._term_order = order
|
|
358
|
+
|
|
359
|
+
Parent.__init__(self, base=base_ring, names=names, category=category)
|
|
360
|
+
self._populate_coercion_lists_()
|
|
361
|
+
|
|
362
|
+
assert n == len(self._names)
|
|
363
|
+
|
|
364
|
+
self._one_element = new_NCP(self, p_ISet(1, self._ring))
|
|
365
|
+
self._zero_element = new_NCP(self, NULL)
|
|
366
|
+
|
|
367
|
+
if check:
|
|
368
|
+
from sage.libs.singular.function_factory import ff
|
|
369
|
+
test = ff.nctools__lib.ndcond(ring = self)
|
|
370
|
+
if (len(test) != 1) or (test[0] != 0):
|
|
371
|
+
raise ValueError("NDC check failed!")
|
|
372
|
+
|
|
373
|
+
def __reduce__(self):
|
|
374
|
+
"""
|
|
375
|
+
TESTS::
|
|
376
|
+
|
|
377
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
378
|
+
sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
379
|
+
sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
380
|
+
True
|
|
381
|
+
sage: H is loads(dumps(H)) # indirect doctest
|
|
382
|
+
True
|
|
383
|
+
sage: A2.<x,y,z> = FreeAlgebra(GF(5), 3)
|
|
384
|
+
sage: R2 = A2.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2))
|
|
385
|
+
|
|
386
|
+
Check that :issue:`17224` is fixed::
|
|
387
|
+
|
|
388
|
+
sage: from sage.rings.polynomial.term_order import TermOrder
|
|
389
|
+
sage: F.<x,y> = FreeAlgebra(QQ)
|
|
390
|
+
sage: g = F.g_algebra({y*x:-x*y}, order=TermOrder('wdegrevlex', [1,2]))
|
|
391
|
+
sage: loads(dumps(g)) == g
|
|
392
|
+
True
|
|
393
|
+
"""
|
|
394
|
+
return g_Algebra, (self.base_ring(), self._c, self._d,
|
|
395
|
+
self.variable_names(),
|
|
396
|
+
self.term_order(),
|
|
397
|
+
self.category())
|
|
398
|
+
|
|
399
|
+
def __dealloc__(self):
|
|
400
|
+
r"""
|
|
401
|
+
Carefully deallocate the ring, without changing "currRing"
|
|
402
|
+
(since this method can be at unpredictable times due to garbage
|
|
403
|
+
collection).
|
|
404
|
+
|
|
405
|
+
TESTS:
|
|
406
|
+
|
|
407
|
+
This example caused a segmentation fault with a previous version
|
|
408
|
+
of this method. This doctest still results in a segmentation fault
|
|
409
|
+
occasionally which is difficult to isolate, so this test is partially
|
|
410
|
+
disabled (:issue:`29528`)::
|
|
411
|
+
|
|
412
|
+
sage: import gc
|
|
413
|
+
sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
|
|
414
|
+
sage: from sage.algebras.free_algebra import FreeAlgebra
|
|
415
|
+
sage: A1.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
416
|
+
sage: R1 = A1.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2))
|
|
417
|
+
sage: A2.<x,y,z> = FreeAlgebra(GF(5), 3) # not tested
|
|
418
|
+
sage: R2 = A2.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) # not tested
|
|
419
|
+
sage: A3.<x,y,z> = FreeAlgebra(GF(11), 3) # not tested
|
|
420
|
+
sage: R3 = A3.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) # not tested
|
|
421
|
+
sage: A4.<x,y,z> = FreeAlgebra(GF(13), 3) # not tested
|
|
422
|
+
sage: R4 = A4.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) # not tested
|
|
423
|
+
sage: _ = gc.collect()
|
|
424
|
+
sage: foo = R1.gen(0)
|
|
425
|
+
sage: del foo
|
|
426
|
+
sage: del R1
|
|
427
|
+
sage: _ = gc.collect()
|
|
428
|
+
sage: del R2 # not tested
|
|
429
|
+
sage: _ = gc.collect() # not tested
|
|
430
|
+
sage: del R3 # not tested
|
|
431
|
+
sage: _ = gc.collect() # not tested
|
|
432
|
+
"""
|
|
433
|
+
singular_ring_delete(self._ring)
|
|
434
|
+
|
|
435
|
+
def _element_constructor_(self, element):
|
|
436
|
+
"""
|
|
437
|
+
Make sure element is a valid member of ``self``, and return the constructed element.
|
|
438
|
+
|
|
439
|
+
EXAMPLES::
|
|
440
|
+
|
|
441
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
442
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
443
|
+
|
|
444
|
+
We can construct elements from the base ring::
|
|
445
|
+
|
|
446
|
+
sage: P(1/2)
|
|
447
|
+
1/2
|
|
448
|
+
|
|
449
|
+
and all kinds of integers::
|
|
450
|
+
|
|
451
|
+
sage: P(17)
|
|
452
|
+
17
|
|
453
|
+
sage: P(int(19))
|
|
454
|
+
19
|
|
455
|
+
|
|
456
|
+
TESTS:
|
|
457
|
+
|
|
458
|
+
Check conversion from ``self``::
|
|
459
|
+
|
|
460
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
461
|
+
sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
462
|
+
|
|
463
|
+
sage: P._element_constructor_(1/2)
|
|
464
|
+
1/2
|
|
465
|
+
|
|
466
|
+
sage: P._element_constructor_(x*y)
|
|
467
|
+
x*y
|
|
468
|
+
|
|
469
|
+
sage: P._element_constructor_(y*x)
|
|
470
|
+
-x*y
|
|
471
|
+
|
|
472
|
+
Testing special cases::
|
|
473
|
+
|
|
474
|
+
sage: P._element_constructor_(1)
|
|
475
|
+
1
|
|
476
|
+
|
|
477
|
+
sage: P._element_constructor_(0)
|
|
478
|
+
0
|
|
479
|
+
|
|
480
|
+
From the parent free algebra::
|
|
481
|
+
|
|
482
|
+
sage: F.<x,y,z> = FreeAlgebra(QQ,3)
|
|
483
|
+
sage: G = F.g_algebra({y*x: -x*y})
|
|
484
|
+
sage: G._element_constructor_(y*x)
|
|
485
|
+
-x*y
|
|
486
|
+
|
|
487
|
+
From another free algebra::
|
|
488
|
+
|
|
489
|
+
sage: A.<a,b> = FreeAlgebra(QQ, 2)
|
|
490
|
+
sage: G._element_constructor_(b)
|
|
491
|
+
Traceback (most recent call last):
|
|
492
|
+
...
|
|
493
|
+
ValueError: unable to construct an element of this ring
|
|
494
|
+
|
|
495
|
+
From another g-algebra::
|
|
496
|
+
|
|
497
|
+
sage: B = A.g_algebra({b*a: -a*b})
|
|
498
|
+
sage: abar, bbar = B.gens()
|
|
499
|
+
sage: G._element_constructor_(bbar)
|
|
500
|
+
Traceback (most recent call last):
|
|
501
|
+
...
|
|
502
|
+
ValueError: unable to construct an element of this ring
|
|
503
|
+
|
|
504
|
+
Check that it works for rings with parameters::
|
|
505
|
+
|
|
506
|
+
sage: F = PolynomialRing(QQ,'t1,t2').fraction_field()
|
|
507
|
+
sage: A = FreeAlgebra(F, 2, 'x,y')
|
|
508
|
+
sage: A.inject_variables()
|
|
509
|
+
Defining x, y
|
|
510
|
+
sage: B = A.g_algebra({y*x:-x*y})
|
|
511
|
+
sage: B(2)
|
|
512
|
+
2
|
|
513
|
+
"""
|
|
514
|
+
if element == 0:
|
|
515
|
+
return self._zero_element
|
|
516
|
+
if element == 1:
|
|
517
|
+
return self._one_element
|
|
518
|
+
|
|
519
|
+
cdef poly *_p
|
|
520
|
+
cdef ring *_ring,
|
|
521
|
+
cdef number *_n
|
|
522
|
+
|
|
523
|
+
_ring = self._ring
|
|
524
|
+
|
|
525
|
+
base_ring = self.base_ring()
|
|
526
|
+
|
|
527
|
+
try:
|
|
528
|
+
element = coerce(base_ring, element)
|
|
529
|
+
except Exception:
|
|
530
|
+
pass
|
|
531
|
+
|
|
532
|
+
if _ring != currRing:
|
|
533
|
+
rChangeCurrRing(_ring)
|
|
534
|
+
|
|
535
|
+
if isinstance(element, NCPolynomial_plural):
|
|
536
|
+
|
|
537
|
+
if element.parent() is <object>self:
|
|
538
|
+
return element
|
|
539
|
+
elif element.parent() == self:
|
|
540
|
+
# is this safe?
|
|
541
|
+
_p = p_Copy((<NCPolynomial_plural>element)._poly, _ring)
|
|
542
|
+
else:
|
|
543
|
+
raise ValueError("unable to construct an element of this ring")
|
|
544
|
+
|
|
545
|
+
elif isinstance(element, CommutativeRingElement):
|
|
546
|
+
# base ring elements
|
|
547
|
+
if <Parent>element.parent() is base_ring:
|
|
548
|
+
# shortcut for GF(p)
|
|
549
|
+
if isinstance(base_ring, FiniteField_prime_modn):
|
|
550
|
+
_p = p_ISet(int(element) % _ring.cf.ch, _ring)
|
|
551
|
+
else:
|
|
552
|
+
_n = sa2si(element,_ring)
|
|
553
|
+
_p = p_NSet(_n, _ring)
|
|
554
|
+
|
|
555
|
+
# also accepting ZZ
|
|
556
|
+
elif isinstance(element.parent(), IntegerRing_class):
|
|
557
|
+
if isinstance(base_ring, FiniteField_prime_modn):
|
|
558
|
+
_p = p_ISet(int(element),_ring)
|
|
559
|
+
else:
|
|
560
|
+
_n = sa2si(base_ring(element),_ring)
|
|
561
|
+
_p = p_NSet(_n, _ring)
|
|
562
|
+
else:
|
|
563
|
+
# fall back to base ring
|
|
564
|
+
element = base_ring.coerce(element)
|
|
565
|
+
_n = sa2si(element,_ring)
|
|
566
|
+
_p = p_NSet(_n, _ring)
|
|
567
|
+
|
|
568
|
+
elif isinstance(element, RingElement):
|
|
569
|
+
# the parent free algebra
|
|
570
|
+
if element.parent() == self.free_algebra():
|
|
571
|
+
return element(self.gens())
|
|
572
|
+
else:
|
|
573
|
+
raise ValueError("unable to construct an element of this ring")
|
|
574
|
+
|
|
575
|
+
# Accepting int
|
|
576
|
+
elif isinstance(element, int):
|
|
577
|
+
if isinstance(base_ring, FiniteField_prime_modn):
|
|
578
|
+
_p = p_ISet(int(element) % _ring.cf.ch, _ring)
|
|
579
|
+
else:
|
|
580
|
+
_n = sa2si(base_ring(element), _ring)
|
|
581
|
+
_p = p_NSet(_n, _ring)
|
|
582
|
+
|
|
583
|
+
else:
|
|
584
|
+
raise NotImplementedError(f"not able to interpret {element}"
|
|
585
|
+
f" of type {type(element)}"
|
|
586
|
+
" as noncommutative polynomial") # ???
|
|
587
|
+
return new_NCP(self, _p)
|
|
588
|
+
|
|
589
|
+
cpdef _coerce_map_from_(self, S):
|
|
590
|
+
"""
|
|
591
|
+
The only things that coerce into this ring are:
|
|
592
|
+
|
|
593
|
+
- the integer ring
|
|
594
|
+
- other localizations away from fewer primes
|
|
595
|
+
|
|
596
|
+
EXAMPLES::
|
|
597
|
+
|
|
598
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
599
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
600
|
+
sage: P._coerce_map_from_(ZZ)
|
|
601
|
+
True
|
|
602
|
+
"""
|
|
603
|
+
if self.base_ring().has_coerce_map_from(S):
|
|
604
|
+
return True
|
|
605
|
+
|
|
606
|
+
def free_algebra(self):
|
|
607
|
+
"""
|
|
608
|
+
Return the free algebra of which this is the quotient.
|
|
609
|
+
|
|
610
|
+
EXAMPLES::
|
|
611
|
+
|
|
612
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
613
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
614
|
+
sage: B = P.free_algebra()
|
|
615
|
+
sage: A == B
|
|
616
|
+
True
|
|
617
|
+
"""
|
|
618
|
+
from sage.algebras.free_algebra import FreeAlgebra
|
|
619
|
+
return FreeAlgebra(self.base_ring(), names=self.variable_names(), order=self.term_order())
|
|
620
|
+
|
|
621
|
+
def __hash__(self):
|
|
622
|
+
"""
|
|
623
|
+
Return a hash for this noncommutative ring.
|
|
624
|
+
|
|
625
|
+
This is a hash of the string
|
|
626
|
+
representation of this polynomial ring.
|
|
627
|
+
|
|
628
|
+
NOTE:
|
|
629
|
+
|
|
630
|
+
G-algebras are unique parents, provided that the g-algebra constructor
|
|
631
|
+
is used. Thus, the hash simply is the memory address of the g-algebra
|
|
632
|
+
(so, it is a session hash, but no stable hash). It is possible to
|
|
633
|
+
destroy uniqueness of g-algebras on purpose, but that's your own
|
|
634
|
+
problem if you do those things.
|
|
635
|
+
|
|
636
|
+
EXAMPLES::
|
|
637
|
+
|
|
638
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
639
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
640
|
+
sage: {P:2}[P] # indirect doctest
|
|
641
|
+
2
|
|
642
|
+
"""
|
|
643
|
+
return <Py_hash_t> <void *> self
|
|
644
|
+
|
|
645
|
+
def __pow__(self, n, _):
|
|
646
|
+
"""
|
|
647
|
+
Return the free module of rank `n` over this ring.
|
|
648
|
+
|
|
649
|
+
.. NOTE::
|
|
650
|
+
|
|
651
|
+
This is not properly implemented yet. Thus, there is
|
|
652
|
+
a warning.
|
|
653
|
+
|
|
654
|
+
EXAMPLES::
|
|
655
|
+
|
|
656
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
657
|
+
sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
658
|
+
sage: P^3
|
|
659
|
+
d...: UserWarning: You are constructing a free module
|
|
660
|
+
over a noncommutative ring. Sage does not have a concept
|
|
661
|
+
of left/right and both sided modules, so be careful.
|
|
662
|
+
It's also not guaranteed that all multiplications are
|
|
663
|
+
done from the right side.
|
|
664
|
+
d...: UserWarning: You are constructing a free module
|
|
665
|
+
over a noncommutative ring. Sage does not have a concept
|
|
666
|
+
of left/right and both sided modules, so be careful.
|
|
667
|
+
It's also not guaranteed that all multiplications are
|
|
668
|
+
done from the right side.
|
|
669
|
+
Ambient free module of rank 3 over Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
|
|
670
|
+
"""
|
|
671
|
+
from sage.modules.free_module import FreeModule
|
|
672
|
+
return FreeModule(self, n)
|
|
673
|
+
|
|
674
|
+
def term_order(self):
|
|
675
|
+
"""
|
|
676
|
+
Return the term ordering of the noncommutative ring.
|
|
677
|
+
|
|
678
|
+
EXAMPLES::
|
|
679
|
+
|
|
680
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
681
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
682
|
+
sage: P.term_order()
|
|
683
|
+
Lexicographic term order
|
|
684
|
+
|
|
685
|
+
sage: P = A.g_algebra(relations={y*x:-x*y})
|
|
686
|
+
sage: P.term_order()
|
|
687
|
+
Degree reverse lexicographic term order
|
|
688
|
+
"""
|
|
689
|
+
return self._term_order
|
|
690
|
+
|
|
691
|
+
def is_field(self, *args, **kwargs) -> bool:
|
|
692
|
+
"""
|
|
693
|
+
Return ``False``.
|
|
694
|
+
|
|
695
|
+
EXAMPLES::
|
|
696
|
+
|
|
697
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
698
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
699
|
+
sage: P.is_field()
|
|
700
|
+
False
|
|
701
|
+
|
|
702
|
+
TESTS:
|
|
703
|
+
|
|
704
|
+
Make the method accept additional parameters, such as the flag ``proof``.
|
|
705
|
+
See :issue:`22910`::
|
|
706
|
+
|
|
707
|
+
sage: P.is_field(proof=False)
|
|
708
|
+
False
|
|
709
|
+
"""
|
|
710
|
+
return False
|
|
711
|
+
|
|
712
|
+
def _repr_(self):
|
|
713
|
+
"""
|
|
714
|
+
EXAMPLES::
|
|
715
|
+
|
|
716
|
+
sage: A.<x,y> = FreeAlgebra(QQ, 2)
|
|
717
|
+
sage: H.<x,y> = A.g_algebra({y*x:-x*y})
|
|
718
|
+
sage: H # indirect doctest
|
|
719
|
+
Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: {y*x: -x*y}
|
|
720
|
+
sage: x*y
|
|
721
|
+
x*y
|
|
722
|
+
sage: y*x
|
|
723
|
+
-x*y
|
|
724
|
+
"""
|
|
725
|
+
from sage.repl.rich_output.backend_base import BackendBase
|
|
726
|
+
from sage.repl.display.pretty_print import SagePrettyPrinter
|
|
727
|
+
varstr = ", ".join(char_to_str(rRingVar(i, self._ring))
|
|
728
|
+
for i in range(self._ngens))
|
|
729
|
+
backend = BackendBase()
|
|
730
|
+
relations = backend._apply_pretty_printer(SagePrettyPrinter,
|
|
731
|
+
self.relations())
|
|
732
|
+
return (f"Noncommutative Multivariate Polynomial Ring in {varstr} "
|
|
733
|
+
f"over {self.base_ring()}, nc-relations: {relations}")
|
|
734
|
+
|
|
735
|
+
def _ringlist(self):
|
|
736
|
+
"""
|
|
737
|
+
Return an internal list representation of the noncommutative ring.
|
|
738
|
+
|
|
739
|
+
EXAMPLES::
|
|
740
|
+
|
|
741
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
742
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
743
|
+
sage: P._ringlist()
|
|
744
|
+
[
|
|
745
|
+
[ 0 -1 1]
|
|
746
|
+
[ 0 0 1]
|
|
747
|
+
0, ['x', 'y', 'z'], [['lp', (1, 1, 1)], ['C', (0,)]], [0], [ 0 0 0],
|
|
748
|
+
<BLANKLINE>
|
|
749
|
+
[0 0 0]
|
|
750
|
+
[0 0 0]
|
|
751
|
+
[0 0 0]
|
|
752
|
+
]
|
|
753
|
+
"""
|
|
754
|
+
cdef ring* _ring = self._ring
|
|
755
|
+
if _ring != currRing:
|
|
756
|
+
rChangeCurrRing(_ring)
|
|
757
|
+
from sage.libs.singular.function import singular_function
|
|
758
|
+
ringlist = singular_function('ringlist')
|
|
759
|
+
return ringlist(self, ring=self)
|
|
760
|
+
|
|
761
|
+
def relations(self, add_commutative=False):
|
|
762
|
+
"""
|
|
763
|
+
Return the relations of this g-algebra.
|
|
764
|
+
|
|
765
|
+
INPUT:
|
|
766
|
+
|
|
767
|
+
- ``add_commutative`` -- boolean (default: ``False``)
|
|
768
|
+
|
|
769
|
+
OUTPUT:
|
|
770
|
+
|
|
771
|
+
The defining relations. There are some implicit relations:
|
|
772
|
+
Two generators commute if they are not part of any given
|
|
773
|
+
relation. The implicit relations are not provided, unless
|
|
774
|
+
``add_commutative==True``.
|
|
775
|
+
|
|
776
|
+
EXAMPLES::
|
|
777
|
+
|
|
778
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
779
|
+
sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y})
|
|
780
|
+
sage: x*y == y*x
|
|
781
|
+
True
|
|
782
|
+
sage: H.relations()
|
|
783
|
+
{z*x: x*z + 2*x, z*y: y*z - 2*y}
|
|
784
|
+
sage: H.relations(add_commutative=True)
|
|
785
|
+
{y*x: x*y, z*x: x*z + 2*x, z*y: y*z - 2*y}
|
|
786
|
+
"""
|
|
787
|
+
if add_commutative:
|
|
788
|
+
if self._relations_commutative is not None:
|
|
789
|
+
return self._relations_commutative
|
|
790
|
+
|
|
791
|
+
from sage.algebras.free_algebra import FreeAlgebra
|
|
792
|
+
A = FreeAlgebra(self.base_ring(), self.ngens(), self.variable_names())
|
|
793
|
+
|
|
794
|
+
res = {}
|
|
795
|
+
n = self.ngens()
|
|
796
|
+
for r in range(0, n-1, 1):
|
|
797
|
+
for c in range(r+1, n, 1):
|
|
798
|
+
res[A.gen(c) * A.gen(r)] = self.gen(c) * self.gen(r) # C[r, c] * P.gen(r) * P.gen(c) + D[r, c]
|
|
799
|
+
self._relations_commutative = res
|
|
800
|
+
return res
|
|
801
|
+
|
|
802
|
+
if self._relations is not None:
|
|
803
|
+
return self._relations
|
|
804
|
+
|
|
805
|
+
from sage.algebras.free_algebra import FreeAlgebra
|
|
806
|
+
A = FreeAlgebra(self.base_ring(), self.ngens(), self.variable_names())
|
|
807
|
+
|
|
808
|
+
res = {}
|
|
809
|
+
n = self.ngens()
|
|
810
|
+
for r in range(0, n-1, 1):
|
|
811
|
+
for c in range(r+1, n, 1):
|
|
812
|
+
if (self.gen(c) * self.gen(r) != self.gen(r) * self.gen(c)):
|
|
813
|
+
res[A.gen(c) * A.gen(r)] = self.gen(c) * self.gen(r) # C[r, c] * P.gen(r) * P.gen(c) + D[r, c]
|
|
814
|
+
|
|
815
|
+
self._relations = res
|
|
816
|
+
return self._relations
|
|
817
|
+
|
|
818
|
+
def ngens(self):
|
|
819
|
+
"""
|
|
820
|
+
Return the number of variables in this noncommutative polynomial ring.
|
|
821
|
+
|
|
822
|
+
EXAMPLES::
|
|
823
|
+
|
|
824
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
825
|
+
sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
826
|
+
sage: P.ngens()
|
|
827
|
+
3
|
|
828
|
+
"""
|
|
829
|
+
return int(self._ngens)
|
|
830
|
+
|
|
831
|
+
def gen(self, int n=0):
|
|
832
|
+
"""
|
|
833
|
+
Return the ``n``-th generator of this noncommutative polynomial
|
|
834
|
+
ring.
|
|
835
|
+
|
|
836
|
+
INPUT:
|
|
837
|
+
|
|
838
|
+
- ``n`` -- nonnegative integer
|
|
839
|
+
|
|
840
|
+
EXAMPLES::
|
|
841
|
+
|
|
842
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
843
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
844
|
+
sage: P.gen(),P.gen(1)
|
|
845
|
+
(x, y)
|
|
846
|
+
|
|
847
|
+
Note that the generators are not cached::
|
|
848
|
+
|
|
849
|
+
sage: P.gen(1) is P.gen(1)
|
|
850
|
+
False
|
|
851
|
+
"""
|
|
852
|
+
cdef poly *_p
|
|
853
|
+
cdef ring *_ring = self._ring
|
|
854
|
+
|
|
855
|
+
if n < 0 or n >= self._ngens:
|
|
856
|
+
raise ValueError("Generator not defined.")
|
|
857
|
+
|
|
858
|
+
rChangeCurrRing(_ring)
|
|
859
|
+
_p = p_ISet(1,_ring)
|
|
860
|
+
p_SetExp(_p, n+1, 1, _ring)
|
|
861
|
+
p_Setm(_p, _ring)
|
|
862
|
+
|
|
863
|
+
return new_NCP(self,_p)
|
|
864
|
+
|
|
865
|
+
def algebra_generators(self):
|
|
866
|
+
r"""
|
|
867
|
+
Return the algebra generators of ``self``.
|
|
868
|
+
|
|
869
|
+
EXAMPLES::
|
|
870
|
+
|
|
871
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
872
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
873
|
+
sage: P.algebra_generators()
|
|
874
|
+
Finite family {'x': x, 'y': y, 'z': z}
|
|
875
|
+
"""
|
|
876
|
+
from sage.sets.family import Family
|
|
877
|
+
return Family(self.gens_dict())
|
|
878
|
+
|
|
879
|
+
def ideal(self, *gens, **kwds):
|
|
880
|
+
"""
|
|
881
|
+
Create an ideal in this polynomial ring.
|
|
882
|
+
|
|
883
|
+
INPUT:
|
|
884
|
+
|
|
885
|
+
- ``*gens`` -- list or tuple of generators (or several input arguments)
|
|
886
|
+
- ``coerce`` -- boolean (default: ``True``); this must be a
|
|
887
|
+
keyword argument. Only set it to ``False`` if you are certain
|
|
888
|
+
that each generator is already in the ring.
|
|
889
|
+
- ``side`` -- string (either "left", which is the default, or "twosided")
|
|
890
|
+
Must be a keyword argument. Defines whether the ideal is a left ideal
|
|
891
|
+
or a two-sided ideal. Right ideals are not implemented.
|
|
892
|
+
|
|
893
|
+
EXAMPLES::
|
|
894
|
+
|
|
895
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
896
|
+
sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
897
|
+
|
|
898
|
+
sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x])
|
|
899
|
+
Left Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
|
|
900
|
+
sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x], side='twosided')
|
|
901
|
+
Twosided Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
|
|
902
|
+
"""
|
|
903
|
+
coerce = kwds.get('coerce', True)
|
|
904
|
+
if len(gens) == 1:
|
|
905
|
+
gens = gens[0]
|
|
906
|
+
# if is_SingularElement(gens):
|
|
907
|
+
# gens = list(gens)
|
|
908
|
+
# coerce = True
|
|
909
|
+
# elif is_Macaulay2Element(gens):
|
|
910
|
+
# gens = list(gens)
|
|
911
|
+
# coerce = True
|
|
912
|
+
if not isinstance(gens, (list, tuple)):
|
|
913
|
+
gens = [gens]
|
|
914
|
+
if coerce:
|
|
915
|
+
gens = [self(x) for x in gens] # this will even coerce from singular ideals correctly!
|
|
916
|
+
return NCPolynomialIdeal(self, gens, coerce=False, side=kwds.get('side','left'))
|
|
917
|
+
|
|
918
|
+
def _list_to_ring(self, L):
|
|
919
|
+
"""
|
|
920
|
+
Convert internal list representation to noncommutative ring.
|
|
921
|
+
|
|
922
|
+
EXAMPLES::
|
|
923
|
+
|
|
924
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
925
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
926
|
+
sage: rlist = P._ringlist()
|
|
927
|
+
sage: Q = P._list_to_ring(rlist)
|
|
928
|
+
sage: Q # indirect doctest
|
|
929
|
+
<noncommutative RingWrap>
|
|
930
|
+
"""
|
|
931
|
+
cdef ring* _ring = self._ring
|
|
932
|
+
if _ring != currRing:
|
|
933
|
+
rChangeCurrRing(_ring)
|
|
934
|
+
|
|
935
|
+
from sage.libs.singular.function import singular_function
|
|
936
|
+
ring = singular_function('ring')
|
|
937
|
+
return ring(L, ring=self)
|
|
938
|
+
|
|
939
|
+
# TODO: Implement this properly!
|
|
940
|
+
# def quotient(self, I):
|
|
941
|
+
# """
|
|
942
|
+
# Construct quotient ring of ``self`` and the two-sided Groebner basis of `ideal`
|
|
943
|
+
#
|
|
944
|
+
# EXAMPLES::
|
|
945
|
+
#
|
|
946
|
+
# sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
947
|
+
# sage: H = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
948
|
+
# sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd()
|
|
949
|
+
#
|
|
950
|
+
# sage: Q = H.quotient(I); Q
|
|
951
|
+
# Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
|
|
952
|
+
#
|
|
953
|
+
# TESTS:
|
|
954
|
+
#
|
|
955
|
+
# check coercion bug::
|
|
956
|
+
#
|
|
957
|
+
# sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
958
|
+
# sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
|
|
959
|
+
# sage: rlist = P._ringlist()
|
|
960
|
+
# sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
961
|
+
# sage: H = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
962
|
+
# sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd()
|
|
963
|
+
# sage: Q = H.quotient(I); Q
|
|
964
|
+
# Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
|
|
965
|
+
# sage: Q.gen(0)^2
|
|
966
|
+
# 0
|
|
967
|
+
# sage: Q.gen(1) * Q.gen(0)
|
|
968
|
+
# -x*y
|
|
969
|
+
# """
|
|
970
|
+
# L = self._ringlist()
|
|
971
|
+
# L[3] = I.twostd()
|
|
972
|
+
# W = self._list_to_ring(L)
|
|
973
|
+
# return new_NRing(W, self.base_ring())
|
|
974
|
+
|
|
975
|
+
# The following methods are handy for implementing Groebner
|
|
976
|
+
# basis algorithms. They do only superficial type/sanity checks
|
|
977
|
+
# and should be called carefully.
|
|
978
|
+
|
|
979
|
+
def monomial_quotient(self, NCPolynomial_plural f, NCPolynomial_plural g, coeff=False):
|
|
980
|
+
r"""
|
|
981
|
+
Return ``f/g``, where both ``f`` and ``g`` are treated as
|
|
982
|
+
monomials.
|
|
983
|
+
|
|
984
|
+
Coefficients are ignored by default.
|
|
985
|
+
|
|
986
|
+
INPUT:
|
|
987
|
+
|
|
988
|
+
- ``f`` -- monomial
|
|
989
|
+
- ``g`` -- monomial
|
|
990
|
+
- ``coeff`` -- divide coefficients as well (default: ``False``)
|
|
991
|
+
|
|
992
|
+
EXAMPLES::
|
|
993
|
+
|
|
994
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
995
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
996
|
+
sage: P.inject_variables()
|
|
997
|
+
Defining x, y, z
|
|
998
|
+
|
|
999
|
+
sage: P.monomial_quotient(3/2*x*y,x,coeff=True)
|
|
1000
|
+
3/2*y
|
|
1001
|
+
|
|
1002
|
+
Note that `\ZZ` behaves differently if ``coeff=True``::
|
|
1003
|
+
|
|
1004
|
+
sage: P.monomial_quotient(2*x,3*x)
|
|
1005
|
+
1
|
|
1006
|
+
sage: P.monomial_quotient(2*x,3*x,coeff=True)
|
|
1007
|
+
2/3
|
|
1008
|
+
|
|
1009
|
+
TESTS::
|
|
1010
|
+
|
|
1011
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1012
|
+
sage: R = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1013
|
+
sage: R.inject_variables()
|
|
1014
|
+
Defining x, y, z
|
|
1015
|
+
|
|
1016
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1017
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1018
|
+
sage: P.inject_variables()
|
|
1019
|
+
Defining x, y, z
|
|
1020
|
+
|
|
1021
|
+
sage: P.monomial_quotient(x*y,x)
|
|
1022
|
+
y
|
|
1023
|
+
|
|
1024
|
+
sage: P.monomial_quotient(x*y,R.gen()) # not tested
|
|
1025
|
+
y
|
|
1026
|
+
|
|
1027
|
+
sage: P.monomial_quotient(P(0),P(1))
|
|
1028
|
+
0
|
|
1029
|
+
|
|
1030
|
+
sage: P.monomial_quotient(P(1),P(0))
|
|
1031
|
+
Traceback (most recent call last):
|
|
1032
|
+
...
|
|
1033
|
+
ZeroDivisionError
|
|
1034
|
+
|
|
1035
|
+
sage: P.monomial_quotient(P(3/2),P(2/3), coeff=True)
|
|
1036
|
+
9/4
|
|
1037
|
+
|
|
1038
|
+
sage: P.monomial_quotient(x,P(1))
|
|
1039
|
+
x
|
|
1040
|
+
|
|
1041
|
+
TESTS::
|
|
1042
|
+
|
|
1043
|
+
sage: P.monomial_quotient(x,y) # Note the wrong result
|
|
1044
|
+
x*y^...
|
|
1045
|
+
|
|
1046
|
+
.. WARNING::
|
|
1047
|
+
|
|
1048
|
+
Assumes that the head term of f is a multiple of the head
|
|
1049
|
+
term of g and return the multiplicant m. If this rule is
|
|
1050
|
+
violated, funny things may happen.
|
|
1051
|
+
"""
|
|
1052
|
+
cdef poly *res
|
|
1053
|
+
cdef ring *r = self._ring
|
|
1054
|
+
cdef number *n
|
|
1055
|
+
|
|
1056
|
+
if self is not f._parent:
|
|
1057
|
+
f = self.coerce(f)
|
|
1058
|
+
if self is not g._parent:
|
|
1059
|
+
g = self.coerce(g)
|
|
1060
|
+
|
|
1061
|
+
if r != currRing:
|
|
1062
|
+
rChangeCurrRing(r)
|
|
1063
|
+
|
|
1064
|
+
if not f._poly:
|
|
1065
|
+
return self._zero_element
|
|
1066
|
+
if not g._poly:
|
|
1067
|
+
raise ZeroDivisionError
|
|
1068
|
+
|
|
1069
|
+
res = pMDivide(f._poly, g._poly)
|
|
1070
|
+
if coeff:
|
|
1071
|
+
if (r.cf.type == n_unknown) or r.cf.cfDivBy(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r), r.cf):
|
|
1072
|
+
n = r.cf.cfDiv(p_GetCoeff(f._poly, r),
|
|
1073
|
+
p_GetCoeff(g._poly, r), r.cf)
|
|
1074
|
+
p_SetCoeff0(res, n, r)
|
|
1075
|
+
else:
|
|
1076
|
+
raise ArithmeticError("Cannot divide these coefficients.")
|
|
1077
|
+
else:
|
|
1078
|
+
p_SetCoeff0(res, n_Init(1, r.cf), r)
|
|
1079
|
+
return new_NCP(self, res)
|
|
1080
|
+
|
|
1081
|
+
def monomial_divides(self, NCPolynomial_plural a, NCPolynomial_plural b):
|
|
1082
|
+
"""
|
|
1083
|
+
Return ``False`` if ``a`` does not divide ``b`` and ``True``
|
|
1084
|
+
otherwise.
|
|
1085
|
+
|
|
1086
|
+
Coefficients are ignored.
|
|
1087
|
+
|
|
1088
|
+
INPUT:
|
|
1089
|
+
|
|
1090
|
+
- ``a`` -- monomial
|
|
1091
|
+
|
|
1092
|
+
- ``b`` -- monomial
|
|
1093
|
+
|
|
1094
|
+
EXAMPLES::
|
|
1095
|
+
|
|
1096
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1097
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1098
|
+
sage: P.inject_variables()
|
|
1099
|
+
Defining x, y, z
|
|
1100
|
+
|
|
1101
|
+
sage: P.monomial_divides(x*y*z, x^3*y^2*z^4)
|
|
1102
|
+
True
|
|
1103
|
+
sage: P.monomial_divides(x^3*y^2*z^4, x*y*z)
|
|
1104
|
+
False
|
|
1105
|
+
|
|
1106
|
+
TESTS::
|
|
1107
|
+
|
|
1108
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1109
|
+
sage: Q = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1110
|
+
sage: Q.inject_variables()
|
|
1111
|
+
Defining x, y, z
|
|
1112
|
+
|
|
1113
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1114
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1115
|
+
sage: P.inject_variables()
|
|
1116
|
+
Defining x, y, z
|
|
1117
|
+
|
|
1118
|
+
sage: P.monomial_divides(P(1), P(0))
|
|
1119
|
+
True
|
|
1120
|
+
sage: P.monomial_divides(P(1), x)
|
|
1121
|
+
True
|
|
1122
|
+
"""
|
|
1123
|
+
cdef poly *_a
|
|
1124
|
+
cdef poly *_b
|
|
1125
|
+
cdef ring *_r
|
|
1126
|
+
if a._parent is not b._parent:
|
|
1127
|
+
b = (<NCPolynomialRing_plural>a._parent).coerce(b)
|
|
1128
|
+
|
|
1129
|
+
_a = a._poly
|
|
1130
|
+
_b = b._poly
|
|
1131
|
+
_r = (<NCPolynomialRing_plural>a._parent)._ring
|
|
1132
|
+
|
|
1133
|
+
if _a == NULL:
|
|
1134
|
+
raise ZeroDivisionError
|
|
1135
|
+
if _b == NULL:
|
|
1136
|
+
return True
|
|
1137
|
+
|
|
1138
|
+
if not p_DivisibleBy(_a, _b, _r):
|
|
1139
|
+
return False
|
|
1140
|
+
else:
|
|
1141
|
+
return True
|
|
1142
|
+
|
|
1143
|
+
def monomial_lcm(self, NCPolynomial_plural f, NCPolynomial_plural g):
|
|
1144
|
+
"""
|
|
1145
|
+
LCM for monomials. Coefficients are ignored.
|
|
1146
|
+
|
|
1147
|
+
INPUT:
|
|
1148
|
+
|
|
1149
|
+
- ``f`` -- monomial
|
|
1150
|
+
|
|
1151
|
+
- ``g`` -- monomial
|
|
1152
|
+
|
|
1153
|
+
EXAMPLES::
|
|
1154
|
+
|
|
1155
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1156
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1157
|
+
sage: P.inject_variables()
|
|
1158
|
+
Defining x, y, z
|
|
1159
|
+
|
|
1160
|
+
sage: P.monomial_lcm(3/2*x*y,x)
|
|
1161
|
+
x*y
|
|
1162
|
+
|
|
1163
|
+
TESTS::
|
|
1164
|
+
|
|
1165
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1166
|
+
sage: R = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1167
|
+
sage: R.inject_variables()
|
|
1168
|
+
Defining x, y, z
|
|
1169
|
+
|
|
1170
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1171
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1172
|
+
sage: P.inject_variables()
|
|
1173
|
+
Defining x, y, z
|
|
1174
|
+
|
|
1175
|
+
sage: P.monomial_lcm(x*y,R.gen()) # not tested
|
|
1176
|
+
x*y
|
|
1177
|
+
|
|
1178
|
+
sage: P.monomial_lcm(P(3/2),P(2/3))
|
|
1179
|
+
1
|
|
1180
|
+
|
|
1181
|
+
sage: P.monomial_lcm(x,P(1))
|
|
1182
|
+
x
|
|
1183
|
+
"""
|
|
1184
|
+
cdef poly *m = p_ISet(1, self._ring)
|
|
1185
|
+
|
|
1186
|
+
if self is not f._parent:
|
|
1187
|
+
f = self.coerce(f)
|
|
1188
|
+
if self is not g._parent:
|
|
1189
|
+
g = self.coerce(g)
|
|
1190
|
+
|
|
1191
|
+
if f._poly == NULL:
|
|
1192
|
+
if g._poly == NULL:
|
|
1193
|
+
return self._zero_element
|
|
1194
|
+
else:
|
|
1195
|
+
raise ArithmeticError("Cannot compute LCM of zero and nonzero element.")
|
|
1196
|
+
if g._poly == NULL:
|
|
1197
|
+
raise ArithmeticError("Cannot compute LCM of zero and nonzero element.")
|
|
1198
|
+
|
|
1199
|
+
if self._ring != currRing:
|
|
1200
|
+
rChangeCurrRing(self._ring)
|
|
1201
|
+
|
|
1202
|
+
pLcm(f._poly, g._poly, m)
|
|
1203
|
+
p_Setm(m, self._ring)
|
|
1204
|
+
return new_NCP(self,m)
|
|
1205
|
+
|
|
1206
|
+
def monomial_reduce(self, NCPolynomial_plural f, G):
|
|
1207
|
+
"""
|
|
1208
|
+
Try to find a ``g`` in ``G`` where ``g.lm()`` divides
|
|
1209
|
+
``f``. If found ``(flt,g)`` is returned, ``(0,0)`` otherwise,
|
|
1210
|
+
where ``flt`` is ``f/g.lm()``.
|
|
1211
|
+
|
|
1212
|
+
It is assumed that ``G`` is iterable and contains *only*
|
|
1213
|
+
elements in this polynomial ring.
|
|
1214
|
+
|
|
1215
|
+
Coefficients are ignored.
|
|
1216
|
+
|
|
1217
|
+
INPUT:
|
|
1218
|
+
|
|
1219
|
+
- ``f`` -- monomial
|
|
1220
|
+
- ``G`` -- list/set of mpolynomials
|
|
1221
|
+
|
|
1222
|
+
EXAMPLES::
|
|
1223
|
+
|
|
1224
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1225
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1226
|
+
sage: P.inject_variables()
|
|
1227
|
+
Defining x, y, z
|
|
1228
|
+
|
|
1229
|
+
sage: f = x*y^2
|
|
1230
|
+
sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2 ]
|
|
1231
|
+
sage: P.monomial_reduce(f,G)
|
|
1232
|
+
(y, 1/4*x*y + 2/7)
|
|
1233
|
+
|
|
1234
|
+
TESTS::
|
|
1235
|
+
|
|
1236
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1237
|
+
sage: Q = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1238
|
+
sage: Q.inject_variables()
|
|
1239
|
+
Defining x, y, z
|
|
1240
|
+
|
|
1241
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1242
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1243
|
+
sage: P.inject_variables()
|
|
1244
|
+
Defining x, y, z
|
|
1245
|
+
sage: f = x*y^2
|
|
1246
|
+
sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2 ]
|
|
1247
|
+
|
|
1248
|
+
sage: P.monomial_reduce(P(0),G)
|
|
1249
|
+
(0, 0)
|
|
1250
|
+
|
|
1251
|
+
sage: P.monomial_reduce(f,[P(0)])
|
|
1252
|
+
(0, 0)
|
|
1253
|
+
"""
|
|
1254
|
+
cdef poly *m = f._poly
|
|
1255
|
+
cdef ring *r = self._ring
|
|
1256
|
+
cdef poly *flt
|
|
1257
|
+
|
|
1258
|
+
if not m:
|
|
1259
|
+
return (f, f)
|
|
1260
|
+
|
|
1261
|
+
for g in G:
|
|
1262
|
+
if isinstance(g, NCPolynomial_plural) and g:
|
|
1263
|
+
h = <NCPolynomial_plural>g
|
|
1264
|
+
if p_LmDivisibleBy(h._poly, m, r):
|
|
1265
|
+
flt = pMDivide(f._poly, h._poly)
|
|
1266
|
+
p_SetCoeff(flt, n_Init(1, r.cf), r)
|
|
1267
|
+
return (new_NCP(self,flt), h)
|
|
1268
|
+
return (self._zero_element, self._zero_element)
|
|
1269
|
+
|
|
1270
|
+
def monomial_pairwise_prime(self, NCPolynomial_plural g, NCPolynomial_plural h):
|
|
1271
|
+
"""
|
|
1272
|
+
Return ``True`` if ``h`` and ``g`` are pairwise prime.
|
|
1273
|
+
|
|
1274
|
+
Both ``h`` and ``g`` are treated as monomials.
|
|
1275
|
+
|
|
1276
|
+
Coefficients are ignored.
|
|
1277
|
+
|
|
1278
|
+
INPUT:
|
|
1279
|
+
|
|
1280
|
+
- ``h`` -- monomial
|
|
1281
|
+
- ``g`` -- monomial
|
|
1282
|
+
|
|
1283
|
+
EXAMPLES::
|
|
1284
|
+
|
|
1285
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1286
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1287
|
+
sage: P.inject_variables()
|
|
1288
|
+
Defining x, y, z
|
|
1289
|
+
|
|
1290
|
+
sage: P.monomial_pairwise_prime(x^2*z^3, y^4)
|
|
1291
|
+
True
|
|
1292
|
+
|
|
1293
|
+
sage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3)
|
|
1294
|
+
False
|
|
1295
|
+
|
|
1296
|
+
TESTS::
|
|
1297
|
+
|
|
1298
|
+
sage: A.<x1,y1,z1> = FreeAlgebra(QQ, 3)
|
|
1299
|
+
sage: Q = A.g_algebra(relations={y1*x1:-x1*y1}, order='lex')
|
|
1300
|
+
sage: Q.inject_variables()
|
|
1301
|
+
Defining x1, y1, z1
|
|
1302
|
+
|
|
1303
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1304
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1305
|
+
sage: P.inject_variables()
|
|
1306
|
+
Defining x, y, z
|
|
1307
|
+
|
|
1308
|
+
sage: P.monomial_pairwise_prime(x^2*z^3, x1^4) # not tested
|
|
1309
|
+
True
|
|
1310
|
+
|
|
1311
|
+
sage: P.monomial_pairwise_prime((2)*x^3*y^2, Q.zero()) # not tested
|
|
1312
|
+
True
|
|
1313
|
+
|
|
1314
|
+
sage: P.monomial_pairwise_prime(2*P.one(),x)
|
|
1315
|
+
False
|
|
1316
|
+
"""
|
|
1317
|
+
cdef int i
|
|
1318
|
+
cdef ring *r
|
|
1319
|
+
cdef poly *p
|
|
1320
|
+
cdef poly *q
|
|
1321
|
+
|
|
1322
|
+
if h._parent is not g._parent:
|
|
1323
|
+
g = (<NCPolynomialRing_plural>h._parent).coerce(g)
|
|
1324
|
+
|
|
1325
|
+
r = (<NCPolynomialRing_plural>h._parent)._ring
|
|
1326
|
+
p = g._poly
|
|
1327
|
+
q = h._poly
|
|
1328
|
+
|
|
1329
|
+
if p == NULL:
|
|
1330
|
+
if q == NULL:
|
|
1331
|
+
return False # GCD(0,0) = 0
|
|
1332
|
+
else:
|
|
1333
|
+
return True # GCD(x,0) = 1
|
|
1334
|
+
|
|
1335
|
+
elif q == NULL:
|
|
1336
|
+
return True # GCD(0,x) = 1
|
|
1337
|
+
|
|
1338
|
+
elif p_IsConstant(p, r) or p_IsConstant(q, r): # assuming a base field
|
|
1339
|
+
return False
|
|
1340
|
+
|
|
1341
|
+
for i from 1 <= i <= r.N:
|
|
1342
|
+
if p_GetExp(p, i, r) and p_GetExp(q, i, r):
|
|
1343
|
+
return False
|
|
1344
|
+
return True
|
|
1345
|
+
|
|
1346
|
+
def monomial_all_divisors(self, NCPolynomial_plural t):
|
|
1347
|
+
"""
|
|
1348
|
+
Return a list of all monomials that divide ``t``.
|
|
1349
|
+
|
|
1350
|
+
Coefficients are ignored.
|
|
1351
|
+
|
|
1352
|
+
INPUT:
|
|
1353
|
+
|
|
1354
|
+
- ``t`` -- a monomial
|
|
1355
|
+
|
|
1356
|
+
OUTPUT: list of monomials
|
|
1357
|
+
|
|
1358
|
+
EXAMPLES::
|
|
1359
|
+
|
|
1360
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1361
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1362
|
+
sage: P.inject_variables()
|
|
1363
|
+
Defining x, y, z
|
|
1364
|
+
|
|
1365
|
+
sage: P.monomial_all_divisors(x^2*z^3)
|
|
1366
|
+
[x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]
|
|
1367
|
+
|
|
1368
|
+
ALGORITHM: addwithcarry idea by Toon Segers
|
|
1369
|
+
"""
|
|
1370
|
+
|
|
1371
|
+
M = list()
|
|
1372
|
+
|
|
1373
|
+
cdef ring *_ring = self._ring
|
|
1374
|
+
cdef poly *maxvector = t._poly
|
|
1375
|
+
cdef poly *tempvector = p_ISet(1, _ring)
|
|
1376
|
+
|
|
1377
|
+
pos = 1
|
|
1378
|
+
|
|
1379
|
+
while not p_ExpVectorEqual(tempvector, maxvector, _ring):
|
|
1380
|
+
tempvector = addwithcarry(tempvector, maxvector, pos, _ring)
|
|
1381
|
+
M.append(new_NCP(self, p_Copy(tempvector,_ring)))
|
|
1382
|
+
return M
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
def unpickle_NCPolynomial_plural(NCPolynomialRing_plural R, d):
|
|
1386
|
+
"""
|
|
1387
|
+
Auxiliary function to unpickle a non-commutative polynomial.
|
|
1388
|
+
|
|
1389
|
+
TESTS::
|
|
1390
|
+
|
|
1391
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1392
|
+
sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
1393
|
+
sage: p = x*y+2*z+4*x*y*z*x
|
|
1394
|
+
sage: loads(dumps(p)) == p # indirect doctest
|
|
1395
|
+
True
|
|
1396
|
+
"""
|
|
1397
|
+
cdef ring *r = R._ring
|
|
1398
|
+
cdef poly *m
|
|
1399
|
+
cdef poly *p
|
|
1400
|
+
cdef int _i, _e
|
|
1401
|
+
p = p_ISet(0,r)
|
|
1402
|
+
rChangeCurrRing(r)
|
|
1403
|
+
for mon, c in d.items():
|
|
1404
|
+
m = p_Init(r)
|
|
1405
|
+
for i,e in mon.sparse_iter():
|
|
1406
|
+
_i = i
|
|
1407
|
+
if _i >= r.N:
|
|
1408
|
+
p_Delete(&p,r)
|
|
1409
|
+
p_Delete(&m,r)
|
|
1410
|
+
raise TypeError("variable index too big")
|
|
1411
|
+
_e = e
|
|
1412
|
+
if _e <= 0:
|
|
1413
|
+
p_Delete(&p,r)
|
|
1414
|
+
p_Delete(&m,r)
|
|
1415
|
+
raise TypeError("exponent too small")
|
|
1416
|
+
overflow_check(_e, r)
|
|
1417
|
+
p_SetExp(m, _i+1,_e, r)
|
|
1418
|
+
p_SetCoeff(m, sa2si(c, r), r)
|
|
1419
|
+
p_Setm(m,r)
|
|
1420
|
+
p = p_Add_q(p,m,r)
|
|
1421
|
+
return new_NCP(R,p)
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
cdef class NCPolynomial_plural(RingElement):
|
|
1425
|
+
"""
|
|
1426
|
+
A noncommutative multivariate polynomial implemented using libSINGULAR.
|
|
1427
|
+
"""
|
|
1428
|
+
def __init__(self, NCPolynomialRing_plural parent):
|
|
1429
|
+
"""
|
|
1430
|
+
Construct a zero element in parent.
|
|
1431
|
+
|
|
1432
|
+
EXAMPLES::
|
|
1433
|
+
|
|
1434
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1435
|
+
sage: H = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1436
|
+
sage: from sage.rings.polynomial.plural import NCPolynomial_plural
|
|
1437
|
+
sage: NCPolynomial_plural(H)
|
|
1438
|
+
0
|
|
1439
|
+
"""
|
|
1440
|
+
self._poly = NULL
|
|
1441
|
+
self._parent = parent
|
|
1442
|
+
|
|
1443
|
+
def __dealloc__(self):
|
|
1444
|
+
# TODO: Warn otherwise!
|
|
1445
|
+
# for some mysterious reason, various things may be NULL in some cases
|
|
1446
|
+
if self._parent is not None and (<NCPolynomialRing_plural>self._parent)._ring != NULL and self._poly != NULL:
|
|
1447
|
+
p_Delete(&self._poly, (<NCPolynomialRing_plural>self._parent)._ring)
|
|
1448
|
+
|
|
1449
|
+
def __reduce__(self):
|
|
1450
|
+
"""
|
|
1451
|
+
TESTS::
|
|
1452
|
+
|
|
1453
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1454
|
+
sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
1455
|
+
sage: loads(dumps(x*y+2*z+4*x*y*z*x))
|
|
1456
|
+
4*x^2*y*z + 8*x^2*y - 4*x*z^2 + x*y - 8*x*z + 2*z
|
|
1457
|
+
"""
|
|
1458
|
+
return unpickle_NCPolynomial_plural, (self._parent, self.dict())
|
|
1459
|
+
|
|
1460
|
+
def __hash__(self):
|
|
1461
|
+
"""
|
|
1462
|
+
This hash incorporates the variable name in an effort to
|
|
1463
|
+
respect the obvious inclusions into multi-variable polynomial
|
|
1464
|
+
rings.
|
|
1465
|
+
|
|
1466
|
+
The tuple algorithm is borrowed from http://effbot.org/zone/python-hash.htm.
|
|
1467
|
+
|
|
1468
|
+
EXAMPLES::
|
|
1469
|
+
|
|
1470
|
+
sage: R.<x>=QQ[]
|
|
1471
|
+
sage: S.<x,y>=QQ[]
|
|
1472
|
+
sage: hash(S(1/2))==hash(1/2) # respect inclusions of the rationals
|
|
1473
|
+
True
|
|
1474
|
+
sage: hash(S.0)==hash(R.0) # respect inclusions into mpoly rings
|
|
1475
|
+
True
|
|
1476
|
+
sage: # the point is to make for more flexible dictionary look ups
|
|
1477
|
+
sage: d={S.0:12}
|
|
1478
|
+
sage: d[R.0]
|
|
1479
|
+
12
|
|
1480
|
+
"""
|
|
1481
|
+
return self._hash_c()
|
|
1482
|
+
|
|
1483
|
+
cpdef _richcmp_(left, right, int op):
|
|
1484
|
+
"""
|
|
1485
|
+
Compare left and right.
|
|
1486
|
+
|
|
1487
|
+
EXAMPLES::
|
|
1488
|
+
|
|
1489
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1490
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1491
|
+
sage: P.inject_variables()
|
|
1492
|
+
Defining x, z, y
|
|
1493
|
+
|
|
1494
|
+
sage: x == x
|
|
1495
|
+
True
|
|
1496
|
+
|
|
1497
|
+
sage: x > y
|
|
1498
|
+
True
|
|
1499
|
+
sage: y^2 > x
|
|
1500
|
+
False
|
|
1501
|
+
|
|
1502
|
+
TESTS::
|
|
1503
|
+
|
|
1504
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1505
|
+
sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
|
|
1506
|
+
sage: P.inject_variables()
|
|
1507
|
+
Defining x, z, y
|
|
1508
|
+
|
|
1509
|
+
sage: x > P(0)
|
|
1510
|
+
True
|
|
1511
|
+
|
|
1512
|
+
sage: P(0) == P(0)
|
|
1513
|
+
True
|
|
1514
|
+
|
|
1515
|
+
sage: P(0) < P(1)
|
|
1516
|
+
True
|
|
1517
|
+
|
|
1518
|
+
sage: x > P(1)
|
|
1519
|
+
True
|
|
1520
|
+
|
|
1521
|
+
sage: 1/2*x < 3/4*x
|
|
1522
|
+
True
|
|
1523
|
+
|
|
1524
|
+
sage: (x+1) > x
|
|
1525
|
+
True
|
|
1526
|
+
"""
|
|
1527
|
+
if left is right:
|
|
1528
|
+
return rich_to_bool(op, 0)
|
|
1529
|
+
cdef poly *p = (<NCPolynomial_plural>left)._poly
|
|
1530
|
+
cdef poly *q = (<NCPolynomial_plural>right)._poly
|
|
1531
|
+
cdef ring *r = (<NCPolynomialRing_plural>left._parent)._ring
|
|
1532
|
+
return rich_to_bool(op, singular_polynomial_cmp(p, q, r))
|
|
1533
|
+
|
|
1534
|
+
cpdef _add_(left, right):
|
|
1535
|
+
"""
|
|
1536
|
+
Add ``left`` and ``right``.
|
|
1537
|
+
|
|
1538
|
+
EXAMPLES::
|
|
1539
|
+
|
|
1540
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1541
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1542
|
+
sage: P.inject_variables()
|
|
1543
|
+
Defining x, z, y
|
|
1544
|
+
sage: 3/2*x + 1/2*y + 1 # indirect doctest
|
|
1545
|
+
3/2*x + 1/2*y + 1
|
|
1546
|
+
"""
|
|
1547
|
+
cdef poly *_p
|
|
1548
|
+
singular_polynomial_add(&_p, left._poly,
|
|
1549
|
+
(<NCPolynomial_plural>right)._poly,
|
|
1550
|
+
(<NCPolynomialRing_plural>left._parent)._ring)
|
|
1551
|
+
return new_NCP((<NCPolynomialRing_plural>left._parent), _p)
|
|
1552
|
+
|
|
1553
|
+
cpdef _sub_(left, right):
|
|
1554
|
+
"""
|
|
1555
|
+
Subtract left and right.
|
|
1556
|
+
|
|
1557
|
+
EXAMPLES::
|
|
1558
|
+
|
|
1559
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1560
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1561
|
+
sage: P.inject_variables()
|
|
1562
|
+
Defining x, z, y
|
|
1563
|
+
sage: 3/2*x - 1/2*y - 1 # indirect doctest
|
|
1564
|
+
3/2*x - 1/2*y - 1
|
|
1565
|
+
"""
|
|
1566
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>left._parent)._ring
|
|
1567
|
+
|
|
1568
|
+
cdef poly *_p
|
|
1569
|
+
singular_polynomial_sub(&_p, left._poly,
|
|
1570
|
+
(<NCPolynomial_plural>right)._poly,
|
|
1571
|
+
_ring)
|
|
1572
|
+
return new_NCP((<NCPolynomialRing_plural>left._parent), _p)
|
|
1573
|
+
|
|
1574
|
+
cpdef _lmul_(self, Element left):
|
|
1575
|
+
"""
|
|
1576
|
+
Multiply ``self`` with a base ring element.
|
|
1577
|
+
|
|
1578
|
+
EXAMPLES::
|
|
1579
|
+
|
|
1580
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1581
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1582
|
+
sage: P.inject_variables()
|
|
1583
|
+
Defining x, z, y
|
|
1584
|
+
sage: 3/2*x # indirect doctest
|
|
1585
|
+
3/2*x
|
|
1586
|
+
|
|
1587
|
+
::
|
|
1588
|
+
|
|
1589
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1590
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1591
|
+
sage: P.inject_variables()
|
|
1592
|
+
Defining x, z, y
|
|
1593
|
+
sage: x* (2/3) # indirect doctest
|
|
1594
|
+
2/3*x
|
|
1595
|
+
"""
|
|
1596
|
+
|
|
1597
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1598
|
+
if not left:
|
|
1599
|
+
return (<NCPolynomialRing_plural>self._parent)._zero_element
|
|
1600
|
+
cdef poly *_p
|
|
1601
|
+
singular_polynomial_rmul(&_p, self._poly, left, _ring)
|
|
1602
|
+
return new_NCP((<NCPolynomialRing_plural>self._parent),_p)
|
|
1603
|
+
|
|
1604
|
+
cpdef _mul_(left, right):
|
|
1605
|
+
"""
|
|
1606
|
+
Multiply left and right.
|
|
1607
|
+
|
|
1608
|
+
EXAMPLES::
|
|
1609
|
+
|
|
1610
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1611
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1612
|
+
sage: P.inject_variables()
|
|
1613
|
+
Defining x, z, y
|
|
1614
|
+
sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest
|
|
1615
|
+
9/4*x^2 + 3/2*x*y - 3/4*z - 1/4*y^2 - y - 1
|
|
1616
|
+
|
|
1617
|
+
TESTS::
|
|
1618
|
+
|
|
1619
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1620
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1621
|
+
sage: P.inject_variables()
|
|
1622
|
+
Defining x, z, y
|
|
1623
|
+
sage: (x^2^31) * x^2^31
|
|
1624
|
+
Traceback (most recent call last):
|
|
1625
|
+
...
|
|
1626
|
+
OverflowError: exponent overflow (2147483648)
|
|
1627
|
+
"""
|
|
1628
|
+
# all currently implemented rings are commutative
|
|
1629
|
+
cdef poly *_p
|
|
1630
|
+
singular_polynomial_mul(&_p, left._poly,
|
|
1631
|
+
(<NCPolynomial_plural>right)._poly,
|
|
1632
|
+
(<NCPolynomialRing_plural>left._parent)._ring)
|
|
1633
|
+
return new_NCP((<NCPolynomialRing_plural>left._parent),_p)
|
|
1634
|
+
|
|
1635
|
+
cpdef _div_(left, right):
|
|
1636
|
+
"""
|
|
1637
|
+
Divide ``left`` by ``right``.
|
|
1638
|
+
|
|
1639
|
+
EXAMPLES::
|
|
1640
|
+
|
|
1641
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1642
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1643
|
+
sage: R.inject_variables()
|
|
1644
|
+
Defining x, z, y
|
|
1645
|
+
sage: f = (x + y)/3 # indirect doctest
|
|
1646
|
+
sage: f.parent()
|
|
1647
|
+
Noncommutative Multivariate Polynomial Ring in x, z, y over Rational Field, nc-relations: {y*x: -x*y + z}
|
|
1648
|
+
|
|
1649
|
+
TESTS::
|
|
1650
|
+
|
|
1651
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1652
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1653
|
+
sage: R.inject_variables()
|
|
1654
|
+
Defining x, z, y
|
|
1655
|
+
sage: x/0
|
|
1656
|
+
Traceback (most recent call last):
|
|
1657
|
+
...
|
|
1658
|
+
ZeroDivisionError: rational division by zero
|
|
1659
|
+
"""
|
|
1660
|
+
cdef poly *p
|
|
1661
|
+
cdef bint is_field = left._parent._base.is_field()
|
|
1662
|
+
if p_IsConstant((<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring):
|
|
1663
|
+
if is_field:
|
|
1664
|
+
singular_polynomial_div_coeff(&p, left._poly, (<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring)
|
|
1665
|
+
return new_NCP(left._parent, p)
|
|
1666
|
+
else:
|
|
1667
|
+
return left.change_ring(left.base_ring().fraction_field())/right
|
|
1668
|
+
else:
|
|
1669
|
+
return (<NCPolynomialRing_plural>left._parent).fraction_field()(left,right)
|
|
1670
|
+
|
|
1671
|
+
def __pow__(NCPolynomial_plural self, exp, mod):
|
|
1672
|
+
"""
|
|
1673
|
+
Return ``self**(exp)``.
|
|
1674
|
+
|
|
1675
|
+
The exponent must be an integer.
|
|
1676
|
+
|
|
1677
|
+
EXAMPLES::
|
|
1678
|
+
|
|
1679
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1680
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1681
|
+
sage: R.inject_variables()
|
|
1682
|
+
Defining x, z, y
|
|
1683
|
+
sage: f = x^3 + y
|
|
1684
|
+
sage: f^2
|
|
1685
|
+
x^6 + x^2*z + y^2
|
|
1686
|
+
|
|
1687
|
+
TESTS::
|
|
1688
|
+
|
|
1689
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1690
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1691
|
+
sage: P.inject_variables()
|
|
1692
|
+
Defining x, z, y
|
|
1693
|
+
sage: (x+y^2^31)^10
|
|
1694
|
+
Traceback (most recent call last):
|
|
1695
|
+
....
|
|
1696
|
+
OverflowError: exponent overflow (2147483648)
|
|
1697
|
+
|
|
1698
|
+
Check that using third argument raises an error::
|
|
1699
|
+
|
|
1700
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1701
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1702
|
+
sage: P.inject_variables()
|
|
1703
|
+
Defining x, z, y
|
|
1704
|
+
sage: pow(x + y + z, 2, x)
|
|
1705
|
+
Traceback (most recent call last):
|
|
1706
|
+
...
|
|
1707
|
+
NotImplementedError: pow() with a modulus is not implemented for this ring
|
|
1708
|
+
"""
|
|
1709
|
+
if mod is not None:
|
|
1710
|
+
raise NotImplementedError(
|
|
1711
|
+
"pow() with a modulus is not implemented for this ring"
|
|
1712
|
+
)
|
|
1713
|
+
if type(exp) is not Integer:
|
|
1714
|
+
try:
|
|
1715
|
+
exp = Integer(exp)
|
|
1716
|
+
except TypeError:
|
|
1717
|
+
raise TypeError("non-integral exponents not supported")
|
|
1718
|
+
|
|
1719
|
+
if exp < 0:
|
|
1720
|
+
return 1/(self**(-exp))
|
|
1721
|
+
elif exp == 0:
|
|
1722
|
+
return (<NCPolynomialRing_plural>self._parent)._one_element
|
|
1723
|
+
|
|
1724
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1725
|
+
cdef poly *_p
|
|
1726
|
+
singular_polynomial_pow(&_p, self._poly, exp, _ring)
|
|
1727
|
+
return new_NCP((<NCPolynomialRing_plural>self._parent),_p)
|
|
1728
|
+
|
|
1729
|
+
def __neg__(self):
|
|
1730
|
+
"""
|
|
1731
|
+
Return ``-self``.
|
|
1732
|
+
|
|
1733
|
+
EXAMPLES::
|
|
1734
|
+
|
|
1735
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1736
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1737
|
+
sage: R.inject_variables()
|
|
1738
|
+
Defining x, z, y
|
|
1739
|
+
sage: f = x^3 + y
|
|
1740
|
+
sage: -f
|
|
1741
|
+
-x^3 - y
|
|
1742
|
+
"""
|
|
1743
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1744
|
+
|
|
1745
|
+
cdef poly *p
|
|
1746
|
+
singular_polynomial_neg(&p, self._poly, _ring)
|
|
1747
|
+
return new_NCP((<NCPolynomialRing_plural>self._parent), p)
|
|
1748
|
+
|
|
1749
|
+
def reduce(self, I):
|
|
1750
|
+
"""
|
|
1751
|
+
|
|
1752
|
+
EXAMPLES::
|
|
1753
|
+
|
|
1754
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
1755
|
+
sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
|
|
1756
|
+
sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False)
|
|
1757
|
+
|
|
1758
|
+
The result of reduction is not the normal form, if one reduces
|
|
1759
|
+
by a list of polynomials::
|
|
1760
|
+
|
|
1761
|
+
sage: (x*z).reduce(I.gens())
|
|
1762
|
+
x*z
|
|
1763
|
+
|
|
1764
|
+
However, if the argument is an ideal, then a normal form (reduction
|
|
1765
|
+
with respect to a two-sided Groebner basis) is returned::
|
|
1766
|
+
|
|
1767
|
+
sage: (x*z).reduce(I)
|
|
1768
|
+
-x
|
|
1769
|
+
|
|
1770
|
+
The Groebner basis shows that the result is correct::
|
|
1771
|
+
|
|
1772
|
+
sage: I.std() #random
|
|
1773
|
+
Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
|
|
1774
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational
|
|
1775
|
+
Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
|
|
1776
|
+
sage: sorted(I.std().gens(),key=str)
|
|
1777
|
+
[2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]
|
|
1778
|
+
"""
|
|
1779
|
+
cdef ideal *_I
|
|
1780
|
+
cdef NCPolynomialRing_plural parent = <NCPolynomialRing_plural>self._parent
|
|
1781
|
+
cdef int i = 0
|
|
1782
|
+
cdef ring *r = parent._ring
|
|
1783
|
+
cdef poly *res
|
|
1784
|
+
|
|
1785
|
+
if r != currRing:
|
|
1786
|
+
rChangeCurrRing(r)
|
|
1787
|
+
|
|
1788
|
+
if isinstance(I, NCPolynomialIdeal):
|
|
1789
|
+
try:
|
|
1790
|
+
strat = I._groebner_strategy()
|
|
1791
|
+
return strat.normal_form(self)
|
|
1792
|
+
except (TypeError, NotImplementedError) as msg:
|
|
1793
|
+
pass
|
|
1794
|
+
I = I.gens()
|
|
1795
|
+
|
|
1796
|
+
_I = idInit(len(I),1)
|
|
1797
|
+
for f in I:
|
|
1798
|
+
if not (isinstance(f, NCPolynomial_plural)
|
|
1799
|
+
and <NCPolynomialRing_plural>(<NCPolynomial_plural>f)._parent is parent):
|
|
1800
|
+
try:
|
|
1801
|
+
f = parent.coerce(f)
|
|
1802
|
+
except TypeError as msg:
|
|
1803
|
+
id_Delete(&_I,r)
|
|
1804
|
+
raise TypeError(msg)
|
|
1805
|
+
|
|
1806
|
+
_I.m[i] = p_Copy((<NCPolynomial_plural>f)._poly, r)
|
|
1807
|
+
i+=1
|
|
1808
|
+
|
|
1809
|
+
# the second parameter would be qring!
|
|
1810
|
+
res = kNF(_I, NULL, self._poly)
|
|
1811
|
+
id_Delete(&_I, r)
|
|
1812
|
+
return new_NCP(parent,res)
|
|
1813
|
+
|
|
1814
|
+
def _repr_(self):
|
|
1815
|
+
"""
|
|
1816
|
+
EXAMPLES::
|
|
1817
|
+
|
|
1818
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1819
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1820
|
+
sage: R.inject_variables()
|
|
1821
|
+
Defining x, z, y
|
|
1822
|
+
sage: f = x^3 + y*x*z + z
|
|
1823
|
+
sage: f # indirect doctest
|
|
1824
|
+
x^3 - x*z*y + z^2 + z
|
|
1825
|
+
"""
|
|
1826
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1827
|
+
s = singular_polynomial_str(self._poly, _ring)
|
|
1828
|
+
return s
|
|
1829
|
+
|
|
1830
|
+
cpdef _repr_short_(self):
|
|
1831
|
+
"""
|
|
1832
|
+
This is a faster but less pretty way to print polynomials. If
|
|
1833
|
+
available it uses the short SINGULAR notation.
|
|
1834
|
+
|
|
1835
|
+
EXAMPLES::
|
|
1836
|
+
|
|
1837
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1838
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1839
|
+
sage: R.inject_variables()
|
|
1840
|
+
Defining x, z, y
|
|
1841
|
+
sage: f = x^3 + y
|
|
1842
|
+
sage: f._repr_short_()
|
|
1843
|
+
'x3+y'
|
|
1844
|
+
"""
|
|
1845
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1846
|
+
rChangeCurrRing(_ring)
|
|
1847
|
+
if _ring.CanShortOut:
|
|
1848
|
+
_ring.ShortOut = 1
|
|
1849
|
+
s = char_to_str(p_String(self._poly, _ring, _ring))
|
|
1850
|
+
_ring.ShortOut = 0
|
|
1851
|
+
else:
|
|
1852
|
+
s = char_to_str(p_String(self._poly, _ring, _ring))
|
|
1853
|
+
return s
|
|
1854
|
+
|
|
1855
|
+
def _latex_(self):
|
|
1856
|
+
r"""
|
|
1857
|
+
Return a polynomial LaTeX representation of this polynomial.
|
|
1858
|
+
|
|
1859
|
+
EXAMPLES::
|
|
1860
|
+
|
|
1861
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1862
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1863
|
+
sage: R.inject_variables()
|
|
1864
|
+
Defining x, z, y
|
|
1865
|
+
sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
|
|
1866
|
+
sage: latex(f) # indirect doctest
|
|
1867
|
+
-x^{2} y - z^{2} - \frac{25}{27} y^{3}
|
|
1868
|
+
"""
|
|
1869
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1870
|
+
gens = self.parent().latex_variable_names()
|
|
1871
|
+
base = self.parent().base()
|
|
1872
|
+
return singular_polynomial_latex(self._poly, _ring, base, gens)
|
|
1873
|
+
|
|
1874
|
+
def _repr_with_changed_varnames(self, varnames):
|
|
1875
|
+
"""
|
|
1876
|
+
Return string representing this polynomial but change the
|
|
1877
|
+
variable names to ``varnames``.
|
|
1878
|
+
|
|
1879
|
+
EXAMPLES::
|
|
1880
|
+
|
|
1881
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1882
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1883
|
+
sage: R.inject_variables()
|
|
1884
|
+
Defining x, z, y
|
|
1885
|
+
sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
|
|
1886
|
+
sage: print(f._repr_with_changed_varnames(['FOO', 'BAR', 'FOOBAR']))
|
|
1887
|
+
-FOO^2*FOOBAR - BAR^2 - 25/27*FOOBAR^3
|
|
1888
|
+
"""
|
|
1889
|
+
return singular_polynomial_str_with_changed_varnames(self._poly, (<NCPolynomialRing_plural>self._parent)._ring, varnames)
|
|
1890
|
+
|
|
1891
|
+
def degree(self, NCPolynomial_plural x=None):
|
|
1892
|
+
"""
|
|
1893
|
+
Return the maximal degree of this polynomial in ``x``, where
|
|
1894
|
+
``x`` must be one of the generators for the parent of this
|
|
1895
|
+
polynomial.
|
|
1896
|
+
|
|
1897
|
+
INPUT:
|
|
1898
|
+
|
|
1899
|
+
- ``x`` -- multivariate polynomial (a generator of the parent of
|
|
1900
|
+
self) If x is not specified (or is ``None``), return the total
|
|
1901
|
+
degree, which is the maximum degree of any monomial.
|
|
1902
|
+
|
|
1903
|
+
OUTPUT: integer
|
|
1904
|
+
|
|
1905
|
+
EXAMPLES::
|
|
1906
|
+
|
|
1907
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1908
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1909
|
+
sage: R.inject_variables()
|
|
1910
|
+
Defining x, z, y
|
|
1911
|
+
sage: f = y^2 - x^9 - x
|
|
1912
|
+
sage: f.degree(x)
|
|
1913
|
+
9
|
|
1914
|
+
sage: f.degree(y)
|
|
1915
|
+
2
|
|
1916
|
+
sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x)
|
|
1917
|
+
3
|
|
1918
|
+
sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y)
|
|
1919
|
+
10
|
|
1920
|
+
|
|
1921
|
+
TESTS::
|
|
1922
|
+
|
|
1923
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1924
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1925
|
+
sage: P.inject_variables()
|
|
1926
|
+
Defining x, z, y
|
|
1927
|
+
sage: P(0).degree(x)
|
|
1928
|
+
-1
|
|
1929
|
+
sage: P(1).degree(x)
|
|
1930
|
+
0
|
|
1931
|
+
"""
|
|
1932
|
+
cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1933
|
+
cdef poly *p = self._poly
|
|
1934
|
+
if not x:
|
|
1935
|
+
return singular_polynomial_deg(p,NULL,r)
|
|
1936
|
+
|
|
1937
|
+
# TODO: we can do this faster
|
|
1938
|
+
if x not in self._parent.gens():
|
|
1939
|
+
raise TypeError("x must be one of the generators of the parent.")
|
|
1940
|
+
|
|
1941
|
+
return singular_polynomial_deg(p, (<NCPolynomial_plural>x)._poly, r)
|
|
1942
|
+
|
|
1943
|
+
def total_degree(self):
|
|
1944
|
+
"""
|
|
1945
|
+
Return the total degree of ``self``, which is the maximum degree
|
|
1946
|
+
of all monomials in ``self``.
|
|
1947
|
+
|
|
1948
|
+
EXAMPLES::
|
|
1949
|
+
|
|
1950
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1951
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1952
|
+
sage: R.inject_variables()
|
|
1953
|
+
Defining x, z, y
|
|
1954
|
+
sage: f=2*x*y^3*z^2
|
|
1955
|
+
sage: f.total_degree()
|
|
1956
|
+
6
|
|
1957
|
+
sage: f=4*x^2*y^2*z^3
|
|
1958
|
+
sage: f.total_degree()
|
|
1959
|
+
7
|
|
1960
|
+
sage: f=99*x^6*y^3*z^9
|
|
1961
|
+
sage: f.total_degree()
|
|
1962
|
+
18
|
|
1963
|
+
sage: f=x*y^3*z^6+3*x^2
|
|
1964
|
+
sage: f.total_degree()
|
|
1965
|
+
10
|
|
1966
|
+
sage: f=z^3+8*x^4*y^5*z
|
|
1967
|
+
sage: f.total_degree()
|
|
1968
|
+
10
|
|
1969
|
+
sage: f=z^9+10*x^4+y^8*x^2
|
|
1970
|
+
sage: f.total_degree()
|
|
1971
|
+
10
|
|
1972
|
+
|
|
1973
|
+
TESTS::
|
|
1974
|
+
|
|
1975
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
1976
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
1977
|
+
sage: R.inject_variables()
|
|
1978
|
+
Defining x, z, y
|
|
1979
|
+
sage: R(0).total_degree()
|
|
1980
|
+
-1
|
|
1981
|
+
sage: R(1).total_degree()
|
|
1982
|
+
0
|
|
1983
|
+
"""
|
|
1984
|
+
cdef poly *p = self._poly
|
|
1985
|
+
cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
1986
|
+
return singular_polynomial_deg(p,NULL,r)
|
|
1987
|
+
|
|
1988
|
+
def degrees(self):
|
|
1989
|
+
"""
|
|
1990
|
+
Return a tuple with the maximal degree of each variable in
|
|
1991
|
+
this polynomial.
|
|
1992
|
+
|
|
1993
|
+
The list of degrees is ordered by the order
|
|
1994
|
+
of the generators.
|
|
1995
|
+
|
|
1996
|
+
EXAMPLES::
|
|
1997
|
+
|
|
1998
|
+
sage: A.<y0,y1,y2> = FreeAlgebra(QQ, 3)
|
|
1999
|
+
sage: R = A.g_algebra(relations={y1*y0:-y0*y1 + y2}, order='lex')
|
|
2000
|
+
sage: R.inject_variables()
|
|
2001
|
+
Defining y0, y1, y2
|
|
2002
|
+
sage: q = 3*y0*y1*y1*y2; q
|
|
2003
|
+
3*y0*y1^2*y2
|
|
2004
|
+
sage: q.degrees()
|
|
2005
|
+
(1, 2, 1)
|
|
2006
|
+
sage: (q + y0^5).degrees()
|
|
2007
|
+
(5, 2, 1)
|
|
2008
|
+
"""
|
|
2009
|
+
cdef poly *p = self._poly
|
|
2010
|
+
cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2011
|
+
cdef int i
|
|
2012
|
+
cdef list d = [0 for _ in range(r.N)]
|
|
2013
|
+
while p:
|
|
2014
|
+
for i from 0 <= i < r.N:
|
|
2015
|
+
d[i] = max(d[i],p_GetExp(p, i+1, r))
|
|
2016
|
+
p = pNext(p)
|
|
2017
|
+
return tuple(d)
|
|
2018
|
+
|
|
2019
|
+
def coefficient(self, degrees):
|
|
2020
|
+
"""
|
|
2021
|
+
Return the coefficient of the variables with the degrees
|
|
2022
|
+
specified in the python dictionary ``degrees``.
|
|
2023
|
+
|
|
2024
|
+
Mathematically, this is the coefficient in the base ring
|
|
2025
|
+
adjoined by the variables of this ring not listed in
|
|
2026
|
+
``degrees``. However, the result has the same parent as this
|
|
2027
|
+
polynomial.
|
|
2028
|
+
|
|
2029
|
+
This function contrasts with the function
|
|
2030
|
+
:meth:`monomial_coefficient` which returns the coefficient in the
|
|
2031
|
+
base ring of a monomial.
|
|
2032
|
+
|
|
2033
|
+
INPUT:
|
|
2034
|
+
|
|
2035
|
+
- ``degrees`` -- can be any of:
|
|
2036
|
+
- a dictionary of degree restrictions
|
|
2037
|
+
- a list of degree restrictions (with ``None`` in the unrestricted variables)
|
|
2038
|
+
- a monomial (very fast, but not as flexible)
|
|
2039
|
+
|
|
2040
|
+
OUTPUT: element of the parent of this element
|
|
2041
|
+
|
|
2042
|
+
.. NOTE::
|
|
2043
|
+
|
|
2044
|
+
For coefficients of specific monomials, look at :meth:`monomial_coefficient`.
|
|
2045
|
+
|
|
2046
|
+
EXAMPLES::
|
|
2047
|
+
|
|
2048
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
2049
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2050
|
+
sage: R.inject_variables()
|
|
2051
|
+
Defining x, z, y
|
|
2052
|
+
sage: f=x*y+y+5
|
|
2053
|
+
sage: f.coefficient({x:0,y:1})
|
|
2054
|
+
1
|
|
2055
|
+
sage: f.coefficient({x:0})
|
|
2056
|
+
y + 5
|
|
2057
|
+
sage: f=(1+y+y^2)*(1+x+x^2)
|
|
2058
|
+
sage: f.coefficient({x:0})
|
|
2059
|
+
z + y^2 + y + 1
|
|
2060
|
+
|
|
2061
|
+
sage: f.coefficient(x)
|
|
2062
|
+
y^2 - y + 1
|
|
2063
|
+
|
|
2064
|
+
sage: f.coefficient([0,None]) # not tested
|
|
2065
|
+
y^2 + y + 1
|
|
2066
|
+
|
|
2067
|
+
Be aware that this may not be what you think! The physical
|
|
2068
|
+
appearance of the variable x is deceiving -- particularly if
|
|
2069
|
+
the exponent would be a variable. ::
|
|
2070
|
+
|
|
2071
|
+
sage: f.coefficient(x^0) # outputs the full polynomial
|
|
2072
|
+
x^2*y^2 + x^2*y + x^2 + x*y^2 - x*y + x + z + y^2 + y + 1
|
|
2073
|
+
|
|
2074
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2075
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2076
|
+
sage: R.inject_variables()
|
|
2077
|
+
Defining x, z, y
|
|
2078
|
+
sage: f=x*y+5
|
|
2079
|
+
sage: c=f.coefficient({x:0,y:0}); c
|
|
2080
|
+
5
|
|
2081
|
+
sage: parent(c)
|
|
2082
|
+
Noncommutative Multivariate Polynomial Ring in x, z, y over Finite Field of size 389, nc-relations: {y*x: -x*y + z}
|
|
2083
|
+
|
|
2084
|
+
AUTHOR:
|
|
2085
|
+
|
|
2086
|
+
- Joel B. Mohler (2007-10-31)
|
|
2087
|
+
"""
|
|
2088
|
+
cdef poly *_degrees = <poly*>0
|
|
2089
|
+
cdef poly *p = self._poly
|
|
2090
|
+
cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2091
|
+
cdef poly *newp = p_ISet(0, r)
|
|
2092
|
+
cdef poly *newptemp
|
|
2093
|
+
cdef int i
|
|
2094
|
+
cdef int flag
|
|
2095
|
+
cdef int gens = self._parent.ngens()
|
|
2096
|
+
cdef int *exps = <int*>sig_malloc(sizeof(int)*gens)
|
|
2097
|
+
for i from 0<=i<gens:
|
|
2098
|
+
exps[i] = -1
|
|
2099
|
+
|
|
2100
|
+
if isinstance(degrees, NCPolynomial_plural) and self._parent is (<NCPolynomial_plural>degrees)._parent:
|
|
2101
|
+
_degrees = (<NCPolynomial_plural>degrees)._poly
|
|
2102
|
+
if pLength(_degrees) != 1:
|
|
2103
|
+
raise TypeError("degrees must be a monomial")
|
|
2104
|
+
for i from 0<=i<gens:
|
|
2105
|
+
if p_GetExp(_degrees,i+1,r)!=0:
|
|
2106
|
+
exps[i] = p_GetExp(_degrees,i+1,r)
|
|
2107
|
+
elif type(degrees) is list:
|
|
2108
|
+
for i from 0<=i<gens:
|
|
2109
|
+
if degrees[i] is None:
|
|
2110
|
+
exps[i] = -1
|
|
2111
|
+
else:
|
|
2112
|
+
exps[i] = int(degrees[i])
|
|
2113
|
+
elif type(degrees) is dict:
|
|
2114
|
+
# Extract the ordered list of degree specifications from the dictionary
|
|
2115
|
+
poly_vars = self.parent().gens()
|
|
2116
|
+
for i from 0<=i<gens:
|
|
2117
|
+
try:
|
|
2118
|
+
exps[i] = degrees[poly_vars[i]]
|
|
2119
|
+
except KeyError:
|
|
2120
|
+
pass
|
|
2121
|
+
else:
|
|
2122
|
+
raise TypeError("The input degrees must be a dictionary of variables to exponents.")
|
|
2123
|
+
|
|
2124
|
+
# Extract the monomials that match the specifications
|
|
2125
|
+
while p:
|
|
2126
|
+
flag = 0
|
|
2127
|
+
for i from 0<=i<gens:
|
|
2128
|
+
if exps[i] != -1 and p_GetExp(p,i+1,r)!=exps[i]:
|
|
2129
|
+
flag = 1
|
|
2130
|
+
if flag == 0:
|
|
2131
|
+
newptemp = p_LmInit(p,r)
|
|
2132
|
+
p_SetCoeff(newptemp,n_Copy(p_GetCoeff(p,r),r.cf),r)
|
|
2133
|
+
for i from 0<=i<gens:
|
|
2134
|
+
if exps[i] != -1:
|
|
2135
|
+
p_SetExp(newptemp,i+1,0,r)
|
|
2136
|
+
p_Setm(newptemp,r)
|
|
2137
|
+
newp = p_Add_q(newp,newptemp,r)
|
|
2138
|
+
p = pNext(p)
|
|
2139
|
+
|
|
2140
|
+
sig_free(exps)
|
|
2141
|
+
|
|
2142
|
+
return new_NCP(self.parent(),newp)
|
|
2143
|
+
|
|
2144
|
+
def monomial_coefficient(self, NCPolynomial_plural mon):
|
|
2145
|
+
"""
|
|
2146
|
+
Return the coefficient in the base ring of the monomial ``mon`` in
|
|
2147
|
+
``self``, where ``mon`` must have the same parent as ``self``.
|
|
2148
|
+
|
|
2149
|
+
This function contrasts with the function :meth:`coefficient`
|
|
2150
|
+
which returns the coefficient of a monomial viewing this
|
|
2151
|
+
polynomial in a polynomial ring over a base ring having fewer
|
|
2152
|
+
variables.
|
|
2153
|
+
|
|
2154
|
+
INPUT:
|
|
2155
|
+
|
|
2156
|
+
- ``mon`` -- a monomial
|
|
2157
|
+
|
|
2158
|
+
OUTPUT: coefficient in base ring
|
|
2159
|
+
|
|
2160
|
+
.. SEEALSO::
|
|
2161
|
+
|
|
2162
|
+
For coefficients in a base ring of fewer variables, look at :meth:`coefficient`
|
|
2163
|
+
|
|
2164
|
+
EXAMPLES::
|
|
2165
|
+
|
|
2166
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2167
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2168
|
+
sage: P.inject_variables()
|
|
2169
|
+
Defining x, z, y
|
|
2170
|
+
|
|
2171
|
+
The parent of the return is a member of the base ring.
|
|
2172
|
+
sage: f = 2 * x * y
|
|
2173
|
+
sage: c = f.monomial_coefficient(x*y); c
|
|
2174
|
+
2
|
|
2175
|
+
sage: c.parent()
|
|
2176
|
+
Finite Field of size 389
|
|
2177
|
+
|
|
2178
|
+
sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y
|
|
2179
|
+
sage: f.monomial_coefficient(y^2)
|
|
2180
|
+
1
|
|
2181
|
+
sage: f.monomial_coefficient(x*y)
|
|
2182
|
+
5
|
|
2183
|
+
sage: f.monomial_coefficient(x^9)
|
|
2184
|
+
388
|
|
2185
|
+
sage: f.monomial_coefficient(x^10)
|
|
2186
|
+
0
|
|
2187
|
+
"""
|
|
2188
|
+
cdef poly *p = self._poly
|
|
2189
|
+
cdef poly *m = mon._poly
|
|
2190
|
+
cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2191
|
+
|
|
2192
|
+
if mon._parent is not self._parent:
|
|
2193
|
+
raise TypeError("mon must have same parent as self")
|
|
2194
|
+
|
|
2195
|
+
while p:
|
|
2196
|
+
if p_ExpVectorEqual(p, m, r) == 1:
|
|
2197
|
+
return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base)
|
|
2198
|
+
p = pNext(p)
|
|
2199
|
+
|
|
2200
|
+
return (<NCPolynomialRing_plural>self._parent)._base._zero_element
|
|
2201
|
+
|
|
2202
|
+
cpdef dict dict(self):
|
|
2203
|
+
"""
|
|
2204
|
+
Return a dictionary representing ``self``. This dictionary is in
|
|
2205
|
+
the same format as the generic MPolynomial: The dictionary
|
|
2206
|
+
consists of ``ETuple:coefficient`` pairs.
|
|
2207
|
+
|
|
2208
|
+
EXAMPLES::
|
|
2209
|
+
|
|
2210
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2211
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2212
|
+
sage: R.inject_variables()
|
|
2213
|
+
Defining x, z, y
|
|
2214
|
+
|
|
2215
|
+
sage: f = (2*x*y^3*z^2 + (7)*x^2 + (3))
|
|
2216
|
+
sage: f.dict()
|
|
2217
|
+
{(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
|
|
2218
|
+
|
|
2219
|
+
sage: f.monomial_coefficients()
|
|
2220
|
+
{(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
|
|
2221
|
+
"""
|
|
2222
|
+
cdef poly *p
|
|
2223
|
+
cdef ring *r
|
|
2224
|
+
cdef int n
|
|
2225
|
+
cdef int v
|
|
2226
|
+
r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2227
|
+
if r != currRing:
|
|
2228
|
+
rChangeCurrRing(r)
|
|
2229
|
+
base = (<NCPolynomialRing_plural>self._parent)._base
|
|
2230
|
+
p = self._poly
|
|
2231
|
+
cdef dict d
|
|
2232
|
+
cdef dict pd = dict()
|
|
2233
|
+
while p:
|
|
2234
|
+
d = dict()
|
|
2235
|
+
for v from 1 <= v <= r.N:
|
|
2236
|
+
n = p_GetExp(p, v, r)
|
|
2237
|
+
if n != 0:
|
|
2238
|
+
d[v-1] = n
|
|
2239
|
+
|
|
2240
|
+
pd[ETuple(d, r.N)] = si2sa(p_GetCoeff(p, r), r, base)
|
|
2241
|
+
|
|
2242
|
+
p = pNext(p)
|
|
2243
|
+
return pd
|
|
2244
|
+
|
|
2245
|
+
cpdef dict monomial_coefficients(self, bint copy=True):
|
|
2246
|
+
"""
|
|
2247
|
+
Return a dictionary representation of ``self`` with the keys
|
|
2248
|
+
the exponent vectors and the values the corresponding coefficients.
|
|
2249
|
+
|
|
2250
|
+
INPUT:
|
|
2251
|
+
|
|
2252
|
+
- ``copy`` -- ignored
|
|
2253
|
+
|
|
2254
|
+
EXAMPLES::
|
|
2255
|
+
|
|
2256
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2257
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2258
|
+
sage: R.inject_variables()
|
|
2259
|
+
Defining x, z, y
|
|
2260
|
+
sage: f = (2*x*y^3*z^2 + (7)*x^2 + (3))
|
|
2261
|
+
sage: d = f.monomial_coefficients(False); d
|
|
2262
|
+
{(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
|
|
2263
|
+
sage: d.clear()
|
|
2264
|
+
sage: f.monomial_coefficients()
|
|
2265
|
+
{(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
|
|
2266
|
+
"""
|
|
2267
|
+
return self.dict()
|
|
2268
|
+
|
|
2269
|
+
def _im_gens_(self, codomain, im_gens, base_map=None):
|
|
2270
|
+
"""
|
|
2271
|
+
Return the image of ``self`` in codomain under the map that sends
|
|
2272
|
+
the images of the generators of the parent of ``self`` to the
|
|
2273
|
+
tuple of elements of im_gens.
|
|
2274
|
+
|
|
2275
|
+
INPUT:
|
|
2276
|
+
|
|
2277
|
+
- ``codomain`` -- the parent where the images live
|
|
2278
|
+
|
|
2279
|
+
- ``im_gens`` -- list or tuple with the images of the generators of this ring
|
|
2280
|
+
|
|
2281
|
+
EXAMPLES::
|
|
2282
|
+
|
|
2283
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(9), 3)
|
|
2284
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2285
|
+
sage: R.inject_variables()
|
|
2286
|
+
Defining x, z, y
|
|
2287
|
+
sage: B.<a,b,c> = FreeAlgebra(GF(9), 3)
|
|
2288
|
+
sage: S = B.g_algebra({b*a:2*a*b, c*a:-2*a*c})
|
|
2289
|
+
sage: S.inject_variables()
|
|
2290
|
+
Defining a, b, c
|
|
2291
|
+
sage: (x*y - x^2*z)._im_gens_(S, [a*b, b, a*b*c])
|
|
2292
|
+
a^2*b^3 - a^2*b^2*c
|
|
2293
|
+
sage: -(a*b)*(a*b)*b+(a*b)*(a*b*c)
|
|
2294
|
+
a^2*b^3 - a^2*b^2*c
|
|
2295
|
+
|
|
2296
|
+
sage: z2 = GF(9).gen()
|
|
2297
|
+
sage: phi = R.hom([a*b, b, a*b*c], check=False)
|
|
2298
|
+
sage: phi(x*y - x^2*z)
|
|
2299
|
+
a^2*b^3 - a^2*b^2*c
|
|
2300
|
+
sage: phi(x*y - z2*x^2*z)
|
|
2301
|
+
z2*a^2*b^3 - a^2*b^2*c
|
|
2302
|
+
sage: phi = R.hom([a*b, b, a*b*c], base_map=GF(9).frobenius_endomorphism(), check=False)
|
|
2303
|
+
sage: phi(x*y - x^2*z)
|
|
2304
|
+
a^2*b^3 - a^2*b^2*c
|
|
2305
|
+
sage: phi(x*y - z2*x^2*z)
|
|
2306
|
+
(-z2 + 1)*a^2*b^3 - a^2*b^2*c
|
|
2307
|
+
sage: z2^3
|
|
2308
|
+
2*z2 + 1
|
|
2309
|
+
"""
|
|
2310
|
+
if self.is_zero():
|
|
2311
|
+
return codomain.zero()
|
|
2312
|
+
from sage.misc.misc_c import prod
|
|
2313
|
+
d = self.dict()
|
|
2314
|
+
if base_map is None:
|
|
2315
|
+
base_map = codomain
|
|
2316
|
+
return sum(prod(im_gens[i]**val for i, val in enumerate(t))*base_map(d[t]) for t in d)
|
|
2317
|
+
|
|
2318
|
+
cdef long _hash_c(self) noexcept:
|
|
2319
|
+
"""
|
|
2320
|
+
See :meth:`__hash__`
|
|
2321
|
+
"""
|
|
2322
|
+
cdef poly *p
|
|
2323
|
+
cdef ring *r
|
|
2324
|
+
cdef int n
|
|
2325
|
+
cdef int v
|
|
2326
|
+
r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2327
|
+
if r != currRing:
|
|
2328
|
+
rChangeCurrRing(r)
|
|
2329
|
+
base = (<NCPolynomialRing_plural>self._parent)._base
|
|
2330
|
+
p = self._poly
|
|
2331
|
+
cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap
|
|
2332
|
+
cdef long result_mon
|
|
2333
|
+
var_name_hash = [hash(vn) for vn in self._parent.variable_names()]
|
|
2334
|
+
cdef long c_hash
|
|
2335
|
+
while p:
|
|
2336
|
+
c_hash = hash(si2sa(p_GetCoeff(p, r), r, base))
|
|
2337
|
+
if c_hash != 0: # this is always going to be true, because we are sparse (correct?)
|
|
2338
|
+
# Hash (self[i], gen_a, exp_a, gen_b, exp_b, gen_c, exp_c, ...) as a tuple according to the algorithm.
|
|
2339
|
+
# I omit gen,exp pairs where the exponent is zero.
|
|
2340
|
+
result_mon = c_hash
|
|
2341
|
+
for v from 1 <= v <= r.N:
|
|
2342
|
+
n = p_GetExp(p,v,r)
|
|
2343
|
+
if n!=0:
|
|
2344
|
+
result_mon = (1000003 * result_mon) ^ var_name_hash[v-1]
|
|
2345
|
+
result_mon = (1000003 * result_mon) ^ n
|
|
2346
|
+
result += result_mon
|
|
2347
|
+
|
|
2348
|
+
p = pNext(p)
|
|
2349
|
+
if result == -1:
|
|
2350
|
+
return -2
|
|
2351
|
+
return result
|
|
2352
|
+
|
|
2353
|
+
def __getitem__(self, x):
|
|
2354
|
+
"""
|
|
2355
|
+
Same as :meth:`monomial_coefficient` but for exponent vectors.
|
|
2356
|
+
|
|
2357
|
+
INPUT:
|
|
2358
|
+
|
|
2359
|
+
- ``x`` -- tuple or, in case of a single-variable MPolynomial
|
|
2360
|
+
ring ``x`` can also be an integer
|
|
2361
|
+
|
|
2362
|
+
EXAMPLES::
|
|
2363
|
+
|
|
2364
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2365
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2366
|
+
sage: R.inject_variables()
|
|
2367
|
+
Defining x, z, y
|
|
2368
|
+
sage: f = (-10*x^3*y + 17*x*y)* ( 15*z^3 + 2*x*y*z - 1); f
|
|
2369
|
+
20*x^4*z*y^2 - 150*x^3*z^3*y - 20*x^3*z^2*y + 10*x^3*y - 34*x^2*z*y^2 - 134*x*z^3*y + 34*x*z^2*y - 17*x*y
|
|
2370
|
+
sage: f[4,1,2]
|
|
2371
|
+
20
|
|
2372
|
+
sage: f[1,0,1]
|
|
2373
|
+
372
|
|
2374
|
+
sage: f[0,0,0]
|
|
2375
|
+
0
|
|
2376
|
+
|
|
2377
|
+
sage: R.<x> = PolynomialRing(GF(7), implementation='singular'); R
|
|
2378
|
+
Multivariate Polynomial Ring in x over Finite Field of size 7
|
|
2379
|
+
sage: f = 5*x^2 + 3; f
|
|
2380
|
+
-2*x^2 + 3
|
|
2381
|
+
sage: f[2]
|
|
2382
|
+
5
|
|
2383
|
+
"""
|
|
2384
|
+
cdef poly *m
|
|
2385
|
+
cdef poly *p = self._poly
|
|
2386
|
+
cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2387
|
+
cdef int i
|
|
2388
|
+
|
|
2389
|
+
if isinstance(x, NCPolynomial_plural):
|
|
2390
|
+
return self.monomial_coefficient(x)
|
|
2391
|
+
if not isinstance(x, tuple):
|
|
2392
|
+
try:
|
|
2393
|
+
x = tuple(x)
|
|
2394
|
+
except TypeError:
|
|
2395
|
+
x = (x,)
|
|
2396
|
+
|
|
2397
|
+
if len(x) != (<NCPolynomialRing_plural>self._parent)._ngens:
|
|
2398
|
+
raise TypeError("x must have length self.ngens()")
|
|
2399
|
+
|
|
2400
|
+
m = p_ISet(1,r)
|
|
2401
|
+
i = 1
|
|
2402
|
+
for e in x:
|
|
2403
|
+
overflow_check(e, r)
|
|
2404
|
+
p_SetExp(m, i, int(e), r)
|
|
2405
|
+
i += 1
|
|
2406
|
+
p_Setm(m, r)
|
|
2407
|
+
|
|
2408
|
+
while p:
|
|
2409
|
+
if p_ExpVectorEqual(p, m, r) == 1:
|
|
2410
|
+
p_Delete(&m,r)
|
|
2411
|
+
return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base)
|
|
2412
|
+
p = pNext(p)
|
|
2413
|
+
|
|
2414
|
+
p_Delete(&m,r)
|
|
2415
|
+
return (<NCPolynomialRing_plural>self._parent)._base._zero_element
|
|
2416
|
+
|
|
2417
|
+
def exponents(self, as_ETuples=True):
|
|
2418
|
+
"""
|
|
2419
|
+
Return the exponents of the monomials appearing in this polynomial.
|
|
2420
|
+
|
|
2421
|
+
INPUT:
|
|
2422
|
+
|
|
2423
|
+
- ``as_ETuples`` -- boolean (default: ``True``); if ``True`` returns
|
|
2424
|
+
the result as an list of ETuples, otherwise returns a list of tuples
|
|
2425
|
+
|
|
2426
|
+
EXAMPLES::
|
|
2427
|
+
|
|
2428
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2429
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2430
|
+
sage: R.inject_variables()
|
|
2431
|
+
Defining x, z, y
|
|
2432
|
+
sage: f = x^3 + y + 2*z^2
|
|
2433
|
+
sage: f.exponents()
|
|
2434
|
+
[(3, 0, 0), (0, 2, 0), (0, 0, 1)]
|
|
2435
|
+
sage: f.exponents(as_ETuples=False)
|
|
2436
|
+
[(3, 0, 0), (0, 2, 0), (0, 0, 1)]
|
|
2437
|
+
"""
|
|
2438
|
+
cdef poly *p
|
|
2439
|
+
cdef ring *r
|
|
2440
|
+
cdef int v
|
|
2441
|
+
cdef list pl, ml
|
|
2442
|
+
|
|
2443
|
+
r = (< NCPolynomialRing_plural>self._parent)._ring
|
|
2444
|
+
p = self._poly
|
|
2445
|
+
|
|
2446
|
+
pl = list()
|
|
2447
|
+
ml = list(range(r.N))
|
|
2448
|
+
while p:
|
|
2449
|
+
for v from 1 <= v <= r.N:
|
|
2450
|
+
ml[v - 1] = p_GetExp(p, v, r)
|
|
2451
|
+
|
|
2452
|
+
if as_ETuples:
|
|
2453
|
+
pl.append(ETuple(ml))
|
|
2454
|
+
else:
|
|
2455
|
+
pl.append(tuple(ml))
|
|
2456
|
+
|
|
2457
|
+
p = pNext(p)
|
|
2458
|
+
return pl
|
|
2459
|
+
|
|
2460
|
+
def is_homogeneous(self):
|
|
2461
|
+
"""
|
|
2462
|
+
Return ``True`` if this polynomial is homogeneous.
|
|
2463
|
+
|
|
2464
|
+
EXAMPLES::
|
|
2465
|
+
|
|
2466
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2467
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2468
|
+
sage: P.inject_variables()
|
|
2469
|
+
Defining x, z, y
|
|
2470
|
+
sage: (x+y+z).is_homogeneous()
|
|
2471
|
+
True
|
|
2472
|
+
sage: (x.parent()(0)).is_homogeneous()
|
|
2473
|
+
True
|
|
2474
|
+
sage: (x+y^2+z^3).is_homogeneous()
|
|
2475
|
+
False
|
|
2476
|
+
sage: (x^2 + y^2).is_homogeneous()
|
|
2477
|
+
True
|
|
2478
|
+
sage: (x^2 + y^2*x).is_homogeneous()
|
|
2479
|
+
False
|
|
2480
|
+
sage: (x^2*y + y^2*x).is_homogeneous()
|
|
2481
|
+
True
|
|
2482
|
+
"""
|
|
2483
|
+
cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2484
|
+
if _ring != currRing:
|
|
2485
|
+
rChangeCurrRing(_ring)
|
|
2486
|
+
return bool(p_IsHomogeneous(self._poly,_ring))
|
|
2487
|
+
|
|
2488
|
+
def is_monomial(self):
|
|
2489
|
+
"""
|
|
2490
|
+
Return ``True`` if this polynomial is a monomial.
|
|
2491
|
+
|
|
2492
|
+
A monomial is defined to be a product of generators with
|
|
2493
|
+
coefficient 1.
|
|
2494
|
+
|
|
2495
|
+
EXAMPLES::
|
|
2496
|
+
|
|
2497
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2498
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2499
|
+
sage: P.inject_variables()
|
|
2500
|
+
Defining x, z, y
|
|
2501
|
+
sage: x.is_monomial()
|
|
2502
|
+
True
|
|
2503
|
+
sage: (2*x).is_monomial()
|
|
2504
|
+
False
|
|
2505
|
+
sage: (x*y).is_monomial()
|
|
2506
|
+
True
|
|
2507
|
+
sage: (x*y + x).is_monomial()
|
|
2508
|
+
False
|
|
2509
|
+
"""
|
|
2510
|
+
cdef poly *_p
|
|
2511
|
+
cdef ring *_ring
|
|
2512
|
+
cdef number *_n
|
|
2513
|
+
_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2514
|
+
|
|
2515
|
+
if self._poly == NULL:
|
|
2516
|
+
return True
|
|
2517
|
+
|
|
2518
|
+
if _ring != currRing:
|
|
2519
|
+
rChangeCurrRing(_ring)
|
|
2520
|
+
|
|
2521
|
+
_p = p_Head(self._poly, _ring)
|
|
2522
|
+
_n = p_GetCoeff(_p, _ring)
|
|
2523
|
+
|
|
2524
|
+
ret = bool((not self._poly.next) and _ring.cf.cfIsOne(_n,_ring.cf))
|
|
2525
|
+
|
|
2526
|
+
p_Delete(&_p, _ring)
|
|
2527
|
+
return ret
|
|
2528
|
+
|
|
2529
|
+
def monomials(self):
|
|
2530
|
+
"""
|
|
2531
|
+
Return the list of monomials in ``self``.
|
|
2532
|
+
|
|
2533
|
+
The returned list is decreasingly ordered by the term ordering
|
|
2534
|
+
of ``self.parent()``.
|
|
2535
|
+
|
|
2536
|
+
EXAMPLES::
|
|
2537
|
+
|
|
2538
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2539
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2540
|
+
sage: P.inject_variables()
|
|
2541
|
+
Defining x, z, y
|
|
2542
|
+
sage: f = x + (3*2)*y*z^2 + (2+3)
|
|
2543
|
+
sage: f.monomials()
|
|
2544
|
+
[x, z^2*y, 1]
|
|
2545
|
+
sage: f = P(3^2)
|
|
2546
|
+
sage: f.monomials()
|
|
2547
|
+
[1]
|
|
2548
|
+
|
|
2549
|
+
TESTS::
|
|
2550
|
+
|
|
2551
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2552
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2553
|
+
sage: P.inject_variables()
|
|
2554
|
+
Defining x, z, y
|
|
2555
|
+
sage: f = x
|
|
2556
|
+
sage: f.monomials()
|
|
2557
|
+
[x]
|
|
2558
|
+
|
|
2559
|
+
Check if :issue:`12706` is fixed::
|
|
2560
|
+
|
|
2561
|
+
sage: f = P(0)
|
|
2562
|
+
sage: f.monomials()
|
|
2563
|
+
[]
|
|
2564
|
+
|
|
2565
|
+
Check if :issue:`7152` is fixed::
|
|
2566
|
+
|
|
2567
|
+
sage: # needs sage.symbolic
|
|
2568
|
+
sage: x = var('x')
|
|
2569
|
+
sage: K.<rho> = NumberField(x**2 + 1)
|
|
2570
|
+
sage: R.<x,y> = QQ[]
|
|
2571
|
+
sage: p = rho*x
|
|
2572
|
+
sage: q = x
|
|
2573
|
+
sage: p.monomials()
|
|
2574
|
+
[x]
|
|
2575
|
+
sage: q.monomials()
|
|
2576
|
+
[x]
|
|
2577
|
+
sage: p.monomials()
|
|
2578
|
+
[x]
|
|
2579
|
+
"""
|
|
2580
|
+
l = list()
|
|
2581
|
+
cdef NCPolynomialRing_plural parent = <NCPolynomialRing_plural>self._parent
|
|
2582
|
+
cdef ring *_ring = parent._ring
|
|
2583
|
+
if _ring != currRing:
|
|
2584
|
+
rChangeCurrRing(_ring)
|
|
2585
|
+
cdef poly *p = p_Copy(self._poly, _ring)
|
|
2586
|
+
cdef poly *t
|
|
2587
|
+
|
|
2588
|
+
if p == NULL:
|
|
2589
|
+
return []
|
|
2590
|
+
|
|
2591
|
+
while p:
|
|
2592
|
+
t = pNext(p)
|
|
2593
|
+
p.next = NULL
|
|
2594
|
+
p_SetCoeff(p, n_Init(1,_ring.cf), _ring)
|
|
2595
|
+
p_Setm(p, _ring)
|
|
2596
|
+
l.append(new_NCP(parent, p))
|
|
2597
|
+
p = t
|
|
2598
|
+
|
|
2599
|
+
return l
|
|
2600
|
+
|
|
2601
|
+
def constant_coefficient(self):
|
|
2602
|
+
"""
|
|
2603
|
+
Return the constant coefficient of this multivariate
|
|
2604
|
+
polynomial.
|
|
2605
|
+
|
|
2606
|
+
EXAMPLES::
|
|
2607
|
+
|
|
2608
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2609
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2610
|
+
sage: P.inject_variables()
|
|
2611
|
+
Defining x, z, y
|
|
2612
|
+
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
|
|
2613
|
+
sage: f.constant_coefficient()
|
|
2614
|
+
5
|
|
2615
|
+
sage: f = 3*x^2
|
|
2616
|
+
sage: f.constant_coefficient()
|
|
2617
|
+
0
|
|
2618
|
+
"""
|
|
2619
|
+
cdef poly *p = self._poly
|
|
2620
|
+
cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2621
|
+
if p == NULL:
|
|
2622
|
+
return (<NCPolynomialRing_plural>self._parent)._base._zero_element
|
|
2623
|
+
|
|
2624
|
+
while p.next:
|
|
2625
|
+
p = pNext(p)
|
|
2626
|
+
|
|
2627
|
+
if p_LmIsConstant(p, r):
|
|
2628
|
+
return si2sa(p_GetCoeff(p, r), r,
|
|
2629
|
+
(<NCPolynomialRing_plural>self._parent)._base)
|
|
2630
|
+
return (<NCPolynomialRing_plural>self._parent)._base._zero_element
|
|
2631
|
+
|
|
2632
|
+
cpdef is_constant(self):
|
|
2633
|
+
"""
|
|
2634
|
+
Return ``True`` if this polynomial is constant.
|
|
2635
|
+
|
|
2636
|
+
EXAMPLES::
|
|
2637
|
+
|
|
2638
|
+
sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
|
|
2639
|
+
sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2640
|
+
sage: P.inject_variables()
|
|
2641
|
+
Defining x, z, y
|
|
2642
|
+
sage: x.is_constant()
|
|
2643
|
+
False
|
|
2644
|
+
sage: P(1).is_constant()
|
|
2645
|
+
True
|
|
2646
|
+
"""
|
|
2647
|
+
return bool(p_IsConstant(self._poly, (<NCPolynomialRing_plural>self._parent)._ring))
|
|
2648
|
+
|
|
2649
|
+
def lm(NCPolynomial_plural self):
|
|
2650
|
+
"""
|
|
2651
|
+
Return the lead monomial of ``self`` with respect to the term
|
|
2652
|
+
order of ``self.parent()``.
|
|
2653
|
+
|
|
2654
|
+
In Sage, a monomial is a product of variables in some power
|
|
2655
|
+
without a coefficient.
|
|
2656
|
+
|
|
2657
|
+
EXAMPLES::
|
|
2658
|
+
|
|
2659
|
+
sage: A.<x,y,z> = FreeAlgebra(GF(7), 3)
|
|
2660
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2661
|
+
sage: R.inject_variables()
|
|
2662
|
+
Defining x, y, z
|
|
2663
|
+
sage: f = x^1*y^2 + y^3*z^4
|
|
2664
|
+
sage: f.lm()
|
|
2665
|
+
x*y^2
|
|
2666
|
+
sage: f = x^3*y^2*z^4 + x^3*y^2*z^1
|
|
2667
|
+
sage: f.lm()
|
|
2668
|
+
x^3*y^2*z^4
|
|
2669
|
+
|
|
2670
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
2671
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='deglex')
|
|
2672
|
+
sage: R.inject_variables()
|
|
2673
|
+
Defining x, y, z
|
|
2674
|
+
sage: f = x^1*y^2*z^3 + x^3*y^2*z^0
|
|
2675
|
+
sage: f.lm()
|
|
2676
|
+
x*y^2*z^3
|
|
2677
|
+
sage: f = x^1*y^2*z^4 + x^1*y^1*z^5
|
|
2678
|
+
sage: f.lm()
|
|
2679
|
+
x*y^2*z^4
|
|
2680
|
+
|
|
2681
|
+
sage: A.<x,y,z> = FreeAlgebra(GF(127), 3)
|
|
2682
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='degrevlex')
|
|
2683
|
+
sage: R.inject_variables()
|
|
2684
|
+
Defining x, y, z
|
|
2685
|
+
sage: f = x^1*y^5*z^2 + x^4*y^1*z^3
|
|
2686
|
+
sage: f.lm()
|
|
2687
|
+
x*y^5*z^2
|
|
2688
|
+
sage: f = x^4*y^7*z^1 + x^4*y^2*z^3
|
|
2689
|
+
sage: f.lm()
|
|
2690
|
+
x^4*y^7*z
|
|
2691
|
+
"""
|
|
2692
|
+
cdef poly *_p
|
|
2693
|
+
cdef ring *_ring
|
|
2694
|
+
_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2695
|
+
if self._poly == NULL:
|
|
2696
|
+
return (<NCPolynomialRing_plural>self._parent)._zero_element
|
|
2697
|
+
_p = p_Head(self._poly, _ring)
|
|
2698
|
+
p_SetCoeff(_p, n_Init(1,_ring.cf), _ring)
|
|
2699
|
+
p_Setm(_p,_ring)
|
|
2700
|
+
return new_NCP((<NCPolynomialRing_plural>self._parent), _p)
|
|
2701
|
+
|
|
2702
|
+
def lc(NCPolynomial_plural self):
|
|
2703
|
+
"""
|
|
2704
|
+
Leading coefficient of this polynomial with respect to the
|
|
2705
|
+
term order of ``self.parent()``.
|
|
2706
|
+
|
|
2707
|
+
EXAMPLES::
|
|
2708
|
+
|
|
2709
|
+
sage: A.<x,y,z> = FreeAlgebra(GF(7), 3)
|
|
2710
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2711
|
+
sage: R.inject_variables()
|
|
2712
|
+
Defining x, y, z
|
|
2713
|
+
|
|
2714
|
+
sage: f = 3*x^1*y^2 + 2*y^3*z^4
|
|
2715
|
+
sage: f.lc()
|
|
2716
|
+
3
|
|
2717
|
+
|
|
2718
|
+
sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1
|
|
2719
|
+
sage: f.lc()
|
|
2720
|
+
5
|
|
2721
|
+
"""
|
|
2722
|
+
cdef poly *_p
|
|
2723
|
+
cdef ring *_ring
|
|
2724
|
+
cdef number *_n
|
|
2725
|
+
_ring = (<NCPolynomialRing_plural>self._parent)._ring
|
|
2726
|
+
|
|
2727
|
+
if self._poly == NULL:
|
|
2728
|
+
return (<NCPolynomialRing_plural>self._parent)._base._zero_element
|
|
2729
|
+
|
|
2730
|
+
if _ring != currRing:
|
|
2731
|
+
rChangeCurrRing(_ring)
|
|
2732
|
+
|
|
2733
|
+
_p = p_Head(self._poly, _ring)
|
|
2734
|
+
_n = p_GetCoeff(_p, _ring)
|
|
2735
|
+
|
|
2736
|
+
ret = si2sa(_n, _ring, (<NCPolynomialRing_plural>self._parent)._base)
|
|
2737
|
+
p_Delete(&_p, _ring)
|
|
2738
|
+
return ret
|
|
2739
|
+
|
|
2740
|
+
def lt(NCPolynomial_plural self):
|
|
2741
|
+
"""
|
|
2742
|
+
Return the leading term of this polynomial.
|
|
2743
|
+
|
|
2744
|
+
In Sage, a term is a product of variables in some power and a
|
|
2745
|
+
coefficient.
|
|
2746
|
+
|
|
2747
|
+
EXAMPLES::
|
|
2748
|
+
|
|
2749
|
+
sage: A.<x,y,z> = FreeAlgebra(GF(7), 3)
|
|
2750
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2751
|
+
sage: R.inject_variables()
|
|
2752
|
+
Defining x, y, z
|
|
2753
|
+
|
|
2754
|
+
sage: f = 3*x^1*y^2 + 2*y^3*z^4
|
|
2755
|
+
sage: f.lt()
|
|
2756
|
+
3*x*y^2
|
|
2757
|
+
|
|
2758
|
+
sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1
|
|
2759
|
+
sage: f.lt()
|
|
2760
|
+
-2*x^3*y^2*z^4
|
|
2761
|
+
"""
|
|
2762
|
+
if self._poly == NULL:
|
|
2763
|
+
return (<NCPolynomialRing_plural>self._parent)._zero_element
|
|
2764
|
+
|
|
2765
|
+
return new_NCP((<NCPolynomialRing_plural>self._parent),
|
|
2766
|
+
p_Head(self._poly, (<NCPolynomialRing_plural>self._parent)._ring))
|
|
2767
|
+
|
|
2768
|
+
def is_zero(self):
|
|
2769
|
+
"""
|
|
2770
|
+
Return ``True`` if this polynomial is zero.
|
|
2771
|
+
|
|
2772
|
+
EXAMPLES::
|
|
2773
|
+
|
|
2774
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
2775
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2776
|
+
sage: R.inject_variables()
|
|
2777
|
+
Defining x, z, y
|
|
2778
|
+
|
|
2779
|
+
sage: x.is_zero()
|
|
2780
|
+
False
|
|
2781
|
+
sage: (x-x).is_zero()
|
|
2782
|
+
True
|
|
2783
|
+
"""
|
|
2784
|
+
return self._poly is NULL
|
|
2785
|
+
|
|
2786
|
+
def __bool__(self):
|
|
2787
|
+
"""
|
|
2788
|
+
EXAMPLES::
|
|
2789
|
+
|
|
2790
|
+
sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
|
|
2791
|
+
sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
|
|
2792
|
+
sage: R.inject_variables()
|
|
2793
|
+
Defining x, z, y
|
|
2794
|
+
|
|
2795
|
+
sage: bool(x) # indirect doctest
|
|
2796
|
+
True
|
|
2797
|
+
sage: bool(x-x)
|
|
2798
|
+
False
|
|
2799
|
+
"""
|
|
2800
|
+
return True if self._poly else False
|
|
2801
|
+
|
|
2802
|
+
def __call__(self, *x, **kwds):
|
|
2803
|
+
"""
|
|
2804
|
+
EXAMPLES::
|
|
2805
|
+
|
|
2806
|
+
sage: F.<x,y,z>=FreeAlgebra(QQ,3)
|
|
2807
|
+
sage: G = F.g_algebra({y*x: -x*y})
|
|
2808
|
+
sage: G.inject_variables()
|
|
2809
|
+
Defining x, y, z
|
|
2810
|
+
sage: a = x+y+x*y
|
|
2811
|
+
sage: a.subs(x=0, y=1)
|
|
2812
|
+
1
|
|
2813
|
+
sage: a.subs(x=y,y=x) == x + y - x*y
|
|
2814
|
+
True
|
|
2815
|
+
"""
|
|
2816
|
+
# Modified version of method from algebras/free_algebra_element.py.
|
|
2817
|
+
if isinstance(x[0], tuple):
|
|
2818
|
+
x = x[0]
|
|
2819
|
+
|
|
2820
|
+
if len(x) != self.parent().ngens():
|
|
2821
|
+
raise ValueError("must specify as many values as generators in parent")
|
|
2822
|
+
|
|
2823
|
+
# I don't start with 0, because I don't want to preclude evaluation with
|
|
2824
|
+
# arbitrary objects (e.g. matrices) because of funny coercion.
|
|
2825
|
+
|
|
2826
|
+
result = None
|
|
2827
|
+
for m in self.monomials():
|
|
2828
|
+
c = self.monomial_coefficient(m)
|
|
2829
|
+
summand = None
|
|
2830
|
+
for (elt, pow) in zip(x, m.exponents()[0]):
|
|
2831
|
+
if summand is None:
|
|
2832
|
+
summand = elt**pow
|
|
2833
|
+
else:
|
|
2834
|
+
summand *= elt**pow
|
|
2835
|
+
|
|
2836
|
+
if result is None:
|
|
2837
|
+
result = c*summand
|
|
2838
|
+
else:
|
|
2839
|
+
result += c*summand
|
|
2840
|
+
|
|
2841
|
+
if result is None:
|
|
2842
|
+
return self.parent().zero()
|
|
2843
|
+
return result
|
|
2844
|
+
|
|
2845
|
+
|
|
2846
|
+
#####################################################################
|
|
2847
|
+
|
|
2848
|
+
cdef inline NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent,
|
|
2849
|
+
poly *juice):
|
|
2850
|
+
"""
|
|
2851
|
+
Construct NCPolynomial_plural from parent and SINGULAR poly.
|
|
2852
|
+
|
|
2853
|
+
EXAMPLES::
|
|
2854
|
+
|
|
2855
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
2856
|
+
sage: H = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y})
|
|
2857
|
+
sage: H.gen(2) # indirect doctest
|
|
2858
|
+
z
|
|
2859
|
+
"""
|
|
2860
|
+
cdef NCPolynomial_plural p = NCPolynomial_plural.__new__(NCPolynomial_plural)
|
|
2861
|
+
p._parent = parent
|
|
2862
|
+
p._poly = juice
|
|
2863
|
+
p_Normalize(p._poly, parent._ring)
|
|
2864
|
+
return p
|
|
2865
|
+
|
|
2866
|
+
|
|
2867
|
+
cpdef MPolynomialRing_libsingular new_CRing(RingWrap rw, base_ring):
|
|
2868
|
+
"""
|
|
2869
|
+
Construct ``MPolynomialRing_libsingular`` from ``RingWrap``, assuming the
|
|
2870
|
+
ground field to be ``base_ring``.
|
|
2871
|
+
|
|
2872
|
+
EXAMPLES::
|
|
2873
|
+
|
|
2874
|
+
sage: H.<x,y,z> = PolynomialRing(QQ, 3)
|
|
2875
|
+
sage: from sage.libs.singular.function import singular_function
|
|
2876
|
+
|
|
2877
|
+
sage: ringlist = singular_function('ringlist')
|
|
2878
|
+
sage: ring = singular_function("ring")
|
|
2879
|
+
|
|
2880
|
+
sage: L = ringlist(H, ring=H); L
|
|
2881
|
+
[0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0]]
|
|
2882
|
+
|
|
2883
|
+
sage: len(L)
|
|
2884
|
+
4
|
|
2885
|
+
|
|
2886
|
+
sage: W = ring(L, ring=H); W
|
|
2887
|
+
<RingWrap>
|
|
2888
|
+
|
|
2889
|
+
sage: from sage.rings.polynomial.plural import new_CRing
|
|
2890
|
+
sage: R = new_CRing(W, H.base_ring())
|
|
2891
|
+
sage: R # indirect doctest
|
|
2892
|
+
Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
2893
|
+
|
|
2894
|
+
Check that :issue:`13145` has been resolved::
|
|
2895
|
+
|
|
2896
|
+
sage: h = hash(R.gen() + 1) # sets currRing
|
|
2897
|
+
sage: from sage.libs.singular.ring import ring_refcount_dict, currRing_wrapper
|
|
2898
|
+
sage: curcnt = ring_refcount_dict[currRing_wrapper()]
|
|
2899
|
+
sage: newR = new_CRing(W, H.base_ring())
|
|
2900
|
+
sage: ring_refcount_dict[currRing_wrapper()] - curcnt
|
|
2901
|
+
2
|
|
2902
|
+
|
|
2903
|
+
Check that :issue:`29311` is fixed::
|
|
2904
|
+
|
|
2905
|
+
sage: R.<x,y,z> = QQ[]
|
|
2906
|
+
sage: from sage.libs.singular.function_factory import ff
|
|
2907
|
+
sage: W = ff.ring(ff.ringlist(R), ring=R)
|
|
2908
|
+
sage: C = sage.rings.polynomial.plural.new_CRing(W, R.base_ring())
|
|
2909
|
+
sage: C.one()
|
|
2910
|
+
1
|
|
2911
|
+
"""
|
|
2912
|
+
assert rw.is_commutative()
|
|
2913
|
+
|
|
2914
|
+
cdef MPolynomialRing_libsingular self = <MPolynomialRing_libsingular>MPolynomialRing_libsingular.__new__(MPolynomialRing_libsingular)
|
|
2915
|
+
|
|
2916
|
+
self._ring = rw._ring
|
|
2917
|
+
cdef MPolynomial_libsingular one = new_MP(self, p_ISet(1, self._ring))
|
|
2918
|
+
self._one_element = one
|
|
2919
|
+
self._one_element_poly = one._poly
|
|
2920
|
+
|
|
2921
|
+
wrapped_ring = wrap_ring(self._ring)
|
|
2922
|
+
sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] += 1
|
|
2923
|
+
|
|
2924
|
+
self._ring.ShortOut = 0
|
|
2925
|
+
|
|
2926
|
+
self._ngens = rw.ngens()
|
|
2927
|
+
self._term_order = TermOrder(rw.ordering_string(), force=True)
|
|
2928
|
+
|
|
2929
|
+
names = tuple(rw.var_names())
|
|
2930
|
+
CommutativeRing.__init__(self, base_ring, names, category=Algebras(base_ring),
|
|
2931
|
+
normalize=False)
|
|
2932
|
+
|
|
2933
|
+
self._has_singular = True
|
|
2934
|
+
|
|
2935
|
+
return self
|
|
2936
|
+
|
|
2937
|
+
|
|
2938
|
+
cpdef NCPolynomialRing_plural new_NRing(RingWrap rw, base_ring):
|
|
2939
|
+
"""
|
|
2940
|
+
Construct ``NCPolynomialRing_plural`` from ``RingWrap``, assuming the
|
|
2941
|
+
ground field to be ``base_ring``.
|
|
2942
|
+
|
|
2943
|
+
EXAMPLES::
|
|
2944
|
+
|
|
2945
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
2946
|
+
sage: H = A.g_algebra({y*x:x*y-1})
|
|
2947
|
+
sage: H.inject_variables()
|
|
2948
|
+
Defining x, y, z
|
|
2949
|
+
sage: z*x
|
|
2950
|
+
x*z
|
|
2951
|
+
sage: z*y
|
|
2952
|
+
y*z
|
|
2953
|
+
sage: y*x
|
|
2954
|
+
x*y - 1
|
|
2955
|
+
sage: I = H.ideal([y^2, x^2, z^2-1])
|
|
2956
|
+
sage: I._groebner_basis_libsingular()
|
|
2957
|
+
[1]
|
|
2958
|
+
|
|
2959
|
+
sage: from sage.libs.singular.function import singular_function
|
|
2960
|
+
|
|
2961
|
+
sage: ringlist = singular_function('ringlist')
|
|
2962
|
+
sage: ring = singular_function("ring")
|
|
2963
|
+
|
|
2964
|
+
sage: L = ringlist(H, ring=H); L
|
|
2965
|
+
[
|
|
2966
|
+
[0 1 1]
|
|
2967
|
+
[0 0 1]
|
|
2968
|
+
0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 0 0],
|
|
2969
|
+
<BLANKLINE>
|
|
2970
|
+
[ 0 -1 0]
|
|
2971
|
+
[ 0 0 0]
|
|
2972
|
+
[ 0 0 0]
|
|
2973
|
+
]
|
|
2974
|
+
sage: len(L)
|
|
2975
|
+
6
|
|
2976
|
+
|
|
2977
|
+
sage: W = ring(L, ring=H); W
|
|
2978
|
+
<noncommutative RingWrap>
|
|
2979
|
+
|
|
2980
|
+
sage: from sage.rings.polynomial.plural import new_NRing
|
|
2981
|
+
sage: R = new_NRing(W, H.base_ring())
|
|
2982
|
+
sage: R # indirect doctest
|
|
2983
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over
|
|
2984
|
+
Rational Field, nc-relations: {y*x: x*y - 1}
|
|
2985
|
+
"""
|
|
2986
|
+
assert not rw.is_commutative()
|
|
2987
|
+
|
|
2988
|
+
cdef NCPolynomialRing_plural self = <NCPolynomialRing_plural>NCPolynomialRing_plural.__new__(NCPolynomialRing_plural)
|
|
2989
|
+
self._ring = rw._ring
|
|
2990
|
+
|
|
2991
|
+
wrapped_ring = wrap_ring(self._ring)
|
|
2992
|
+
sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] += 1
|
|
2993
|
+
|
|
2994
|
+
self._ring.ShortOut = 0
|
|
2995
|
+
|
|
2996
|
+
self._ngens = rw.ngens()
|
|
2997
|
+
self._term_order = TermOrder(rw.ordering_string(), force=True)
|
|
2998
|
+
|
|
2999
|
+
Parent.__init__(self, base=base_ring, names=rw.var_names(), category=Algebras(base_ring))
|
|
3000
|
+
|
|
3001
|
+
self._has_singular = True
|
|
3002
|
+
self._relations = self.relations()
|
|
3003
|
+
|
|
3004
|
+
return self
|
|
3005
|
+
|
|
3006
|
+
|
|
3007
|
+
def new_Ring(RingWrap rw, base_ring):
|
|
3008
|
+
"""
|
|
3009
|
+
Construct a Sage ring out of low level ``RingWrap``, which wraps a pointer
|
|
3010
|
+
to a Singular ring.
|
|
3011
|
+
|
|
3012
|
+
The constructed ring is either commutative or noncommutative depending on
|
|
3013
|
+
the Singular ring.
|
|
3014
|
+
|
|
3015
|
+
EXAMPLES::
|
|
3016
|
+
|
|
3017
|
+
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
|
|
3018
|
+
sage: H = A.g_algebra({y*x:x*y-1})
|
|
3019
|
+
sage: H.inject_variables()
|
|
3020
|
+
Defining x, y, z
|
|
3021
|
+
sage: z*x
|
|
3022
|
+
x*z
|
|
3023
|
+
sage: z*y
|
|
3024
|
+
y*z
|
|
3025
|
+
sage: y*x
|
|
3026
|
+
x*y - 1
|
|
3027
|
+
sage: I = H.ideal([y^2, x^2, z^2-1])
|
|
3028
|
+
sage: I._groebner_basis_libsingular()
|
|
3029
|
+
[1]
|
|
3030
|
+
|
|
3031
|
+
sage: from sage.libs.singular.function import singular_function
|
|
3032
|
+
|
|
3033
|
+
sage: ringlist = singular_function('ringlist')
|
|
3034
|
+
sage: ring = singular_function("ring")
|
|
3035
|
+
|
|
3036
|
+
sage: L = ringlist(H, ring=H); L
|
|
3037
|
+
[
|
|
3038
|
+
[0 1 1]
|
|
3039
|
+
[0 0 1]
|
|
3040
|
+
0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 0 0],
|
|
3041
|
+
<BLANKLINE>
|
|
3042
|
+
[ 0 -1 0]
|
|
3043
|
+
[ 0 0 0]
|
|
3044
|
+
[ 0 0 0]
|
|
3045
|
+
]
|
|
3046
|
+
sage: len(L)
|
|
3047
|
+
6
|
|
3048
|
+
|
|
3049
|
+
sage: W = ring(L, ring=H); W
|
|
3050
|
+
<noncommutative RingWrap>
|
|
3051
|
+
|
|
3052
|
+
sage: from sage.rings.polynomial.plural import new_Ring
|
|
3053
|
+
sage: R = new_Ring(W, H.base_ring()); R
|
|
3054
|
+
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - 1}
|
|
3055
|
+
"""
|
|
3056
|
+
# import warnings
|
|
3057
|
+
# warnings.warn("This is a hack. Please, use it on your own risk...")
|
|
3058
|
+
if rw.is_commutative():
|
|
3059
|
+
return new_CRing(rw, base_ring)
|
|
3060
|
+
return new_NRing(rw, base_ring)
|
|
3061
|
+
|
|
3062
|
+
|
|
3063
|
+
def SCA(base_ring, names, alt_vars, order='degrevlex'):
|
|
3064
|
+
"""
|
|
3065
|
+
Return a free graded-commutative algebra.
|
|
3066
|
+
|
|
3067
|
+
This is also known as a free super-commutative algebra.
|
|
3068
|
+
|
|
3069
|
+
INPUT:
|
|
3070
|
+
|
|
3071
|
+
- ``base_ring`` -- the ground field
|
|
3072
|
+
- ``names`` -- list of variable names
|
|
3073
|
+
- ``alt_vars`` -- list of indices of to be anti-commutative variables (odd variables)
|
|
3074
|
+
- ``order`` -- ordering to be used for the constructed algebra
|
|
3075
|
+
|
|
3076
|
+
EXAMPLES::
|
|
3077
|
+
|
|
3078
|
+
sage: from sage.rings.polynomial.plural import SCA
|
|
3079
|
+
sage: E = SCA(QQ, ['x', 'y', 'z'], [0, 1], order = 'degrevlex')
|
|
3080
|
+
sage: E
|
|
3081
|
+
Quotient of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} by the ideal (y^2, x^2)
|
|
3082
|
+
sage: E.inject_variables()
|
|
3083
|
+
Defining xbar, ybar, zbar
|
|
3084
|
+
sage: x,y,z = (xbar,ybar,zbar)
|
|
3085
|
+
sage: y*x
|
|
3086
|
+
-x*y
|
|
3087
|
+
sage: z*x
|
|
3088
|
+
x*z
|
|
3089
|
+
sage: x^2
|
|
3090
|
+
0
|
|
3091
|
+
sage: y^2
|
|
3092
|
+
0
|
|
3093
|
+
sage: z^2
|
|
3094
|
+
z^2
|
|
3095
|
+
sage: E.one()
|
|
3096
|
+
1
|
|
3097
|
+
"""
|
|
3098
|
+
n = len(names)
|
|
3099
|
+
alt_start = min(alt_vars)
|
|
3100
|
+
alt_end = max(alt_vars)
|
|
3101
|
+
assert 0 <= alt_start <= alt_end < n
|
|
3102
|
+
|
|
3103
|
+
relations = {} # {y*x:-x*y}
|
|
3104
|
+
from sage.algebras.free_algebra import FreeAlgebra
|
|
3105
|
+
A = FreeAlgebra(base_ring, n, names)
|
|
3106
|
+
for r in range(0, n-1, 1):
|
|
3107
|
+
for c in range(r+1, n, 1):
|
|
3108
|
+
if r in alt_vars and c in alt_vars:
|
|
3109
|
+
relations[A.gen(c) * A.gen(r)] = - A.gen(r) * A.gen(c)
|
|
3110
|
+
|
|
3111
|
+
cdef NCPolynomialRing_plural H = A.g_algebra(relations=relations,
|
|
3112
|
+
order=order)
|
|
3113
|
+
I = H.ideal([H.gen(i) * H.gen(i) for i in alt_vars]).twostd()
|
|
3114
|
+
return H.quotient(I)
|
|
3115
|
+
|
|
3116
|
+
|
|
3117
|
+
def ExteriorAlgebra(base_ring, names, order='degrevlex'):
|
|
3118
|
+
"""
|
|
3119
|
+
Return the exterior algebra on some generators.
|
|
3120
|
+
|
|
3121
|
+
This is also known as a Grassmann algebra. This is a finite
|
|
3122
|
+
dimensional algebra, where all generators anti-commute.
|
|
3123
|
+
|
|
3124
|
+
See :wikipedia:`Exterior algebra`
|
|
3125
|
+
|
|
3126
|
+
INPUT:
|
|
3127
|
+
|
|
3128
|
+
- ``base_ring`` -- the ground ring
|
|
3129
|
+
- ``names`` -- list of variable names
|
|
3130
|
+
|
|
3131
|
+
EXAMPLES::
|
|
3132
|
+
|
|
3133
|
+
sage: from sage.rings.polynomial.plural import ExteriorAlgebra
|
|
3134
|
+
sage: E = ExteriorAlgebra(QQ, ['x', 'y', 'z']) ; E #random
|
|
3135
|
+
Quotient of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: -x*z, z*y: -y*z, y*x: -x*y} by the ideal (z^2, y^2, x^2)
|
|
3136
|
+
sage: sorted(E.cover().domain().relations().items(), key=str)
|
|
3137
|
+
[(y*x, -x*y), (z*x, -x*z), (z*y, -y*z)]
|
|
3138
|
+
sage: sorted(E.cover().kernel().gens(),key=str)
|
|
3139
|
+
[x^2, y^2, z^2]
|
|
3140
|
+
sage: E.inject_variables()
|
|
3141
|
+
Defining xbar, ybar, zbar
|
|
3142
|
+
sage: x,y,z = (xbar,ybar,zbar)
|
|
3143
|
+
sage: y*x
|
|
3144
|
+
-x*y
|
|
3145
|
+
sage: all(v^2==0 for v in E.gens())
|
|
3146
|
+
True
|
|
3147
|
+
sage: E.one()
|
|
3148
|
+
1
|
|
3149
|
+
"""
|
|
3150
|
+
n = len(names)
|
|
3151
|
+
relations = {} # {y*x:-x*y}
|
|
3152
|
+
from sage.algebras.free_algebra import FreeAlgebra
|
|
3153
|
+
A = FreeAlgebra(base_ring, n, names)
|
|
3154
|
+
for r in range(n-1):
|
|
3155
|
+
for c in range(r+1, n):
|
|
3156
|
+
relations[A.gen(c) * A.gen(r)] = - A.gen(r) * A.gen(c)
|
|
3157
|
+
|
|
3158
|
+
cdef NCPolynomialRing_plural H = A.g_algebra(relations=relations,
|
|
3159
|
+
order=order)
|
|
3160
|
+
I = H.ideal([H.gen(i) * H.gen(i) for i in range(n)]).twostd()
|
|
3161
|
+
return H.quotient(I)
|
|
3162
|
+
|
|
3163
|
+
|
|
3164
|
+
cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring) noexcept:
|
|
3165
|
+
if p_GetExp(tempvector, pos, _ring) < p_GetExp(maxvector, pos, _ring):
|
|
3166
|
+
p_SetExp(tempvector, pos, p_GetExp(tempvector, pos, _ring)+1, _ring)
|
|
3167
|
+
else:
|
|
3168
|
+
p_SetExp(tempvector, pos, 0, _ring)
|
|
3169
|
+
tempvector = addwithcarry(tempvector, maxvector, pos + 1, _ring)
|
|
3170
|
+
p_Setm(tempvector, _ring)
|
|
3171
|
+
return tempvector
|