From 2e88a318efb9803e27b8ab253b9b4a4f3f6ee611 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 3 Dec 2024 23:51:46 +0700 Subject: [PATCH 01/17] Allow more rings to be used with libsingular --- src/sage/libs/singular/ring.pyx | 223 +++++++++++++++++++++----------- 1 file changed, 144 insertions(+), 79 deletions(-) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index f770cc483a5..f87f1b097ec 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -19,7 +19,7 @@ AUTHORS: from sage.cpython.string cimport str_to_bytes, bytes_to_str from sage.libs.gmp.types cimport __mpz_struct -from sage.libs.gmp.mpz cimport mpz_init_set_ui +from sage.libs.gmp.mpz cimport mpz_init_set from sage.libs.singular.decl cimport ring, currRing from sage.libs.singular.decl cimport rChangeCurrRing, rComplete, rDelete, idInit @@ -31,6 +31,7 @@ from sage.libs.singular.decl cimport n_coeffType from sage.libs.singular.decl cimport rDefault, GFInfo, ZnmInfo, nInitChar, AlgExtInfo, TransExtInfo +from sage.rings.integer cimport Integer from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.integer_ring import ZZ import sage.rings.abc @@ -80,7 +81,7 @@ if bytes_to_str(rSimpleOrdStr(ringorder_ip)) == "rp": ############################################################################# cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: - """ + r""" Create a new Singular ring over the ``base_ring`` in ``n`` variables with the names ``names`` and the term order ``term_order``. @@ -159,17 +160,118 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: sage: R. = F[] sage: from sage.libs.singular.function import singular_function sage: sing_print = singular_function('print') - sage: sing_print(R) - 'polynomial ring, over a field, global ordering\n// coefficients: ZZ/7(a, b)\n// number of vars : 3\n// block 1 : ordering dp\n// : names x y z\n// block 2 : ordering C' + sage: print(sing_print(R)) + polynomial ring, over a field, global ordering + // coefficients: ZZ/7(a, b) + // number of vars : 3 + // block 1 : ordering dp + // : names x y z + // block 2 : ordering C :: sage: F = PolynomialRing(QQ, 's,t').fraction_field() sage: R. = F[] sage: from sage.libs.singular.function import singular_function - sage: sing_print = singular_function('print') - sage: sing_print(R) - 'polynomial ring, over a field, global ordering\n// coefficients: QQ(s, t)\n// number of vars : 3\n// block 1 : ordering dp\n// : names x y z\n// block 2 : ordering C' + sage: print(sing_print(R)) + polynomial ring, over a field, global ordering + // coefficients: QQ(s, t) + // number of vars : 3 + // block 1 : ordering dp + // : names x y z + // block 2 : ordering C + + Small primes:: + + sage: R = PolynomialRing(GF(2), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a field, global ordering + // coefficients: ZZ/2 + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + sage: R = PolynomialRing(GF(3), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a field, global ordering + // coefficients: ZZ/3 + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + sage: R = PolynomialRing(GF(1000000007), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a field, global ordering + // coefficients: ZZ/1000000007 + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + + Large prime (note that the print is wrong, the field in fact doesn't have zero-divisors):: + + sage: R = PolynomialRing(GF(2^128+51), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a ring (with zero-divisors), global ordering + // coefficients: ZZ/(bigint(340282366920938463463374607431768211507)^1) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + + Finite field with large degree (note that if stack size is too small and the exponent is too large + a stack overflow may happen inside libsingular):: + + sage: R = PolynomialRing(GF(2^160), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a field, global ordering + // coefficients: ZZ/2[z160]/(z160^160+z160^159+z160^155+z160^154+z160^153+z160^152+z160^151+z160^149+z160^148+z160^147+z160^146+z160^145+z160^144+z160^143+z160^141+z160^139+z160^137+z160^131+z160^129+z160^128+z160^127+z160^126+z160^123+z160^122+z160^121+z160^117+z160^116+z160^115+z160^113+z160^111+z160^110+z160^108+z160^106+z160^102+z160^100+z160^99+z160^97+z160^96+z160^95+z160^94+z160^93+z160^92+z160^91+z160^87+z160^86+z160^82+z160^80+z160^79+z160^78+z160^74+z160^73+z160^72+z160^71+z160^70+z160^67+z160^66+z160^65+z160^62+z160^59+z160^58+z160^57+z160^55+z160^54+z160^53+z160^52+z160^51+z160^49+z160^47+z160^44+z160^40+z160^35+z160^32+z160^30+z160^28+z160^27+z160^26+z160^24+z160^23+z160^21+z160^20+z160^18+z160^16+z160^11+z160^10+z160^8+z160^7+1) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + + Integer modulo small power of 2:: + + sage: R = PolynomialRing(Zmod(2^32), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a ring (with zero-divisors), global ordering + // coefficients: ZZ/(2^32) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + + Integer modulo large power of 2:: + + sage: R = PolynomialRing(Zmod(2^1000), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a ring (with zero-divisors), global ordering + // coefficients: ZZ/(bigint(2)^1000) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + + Integer modulo large power of odd prime:: + + sage: R = PolynomialRing(Zmod(3^300), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a ring (with zero-divisors), global ordering + // coefficients: ZZ/(bigint(3)^300) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + + Integer modulo non-prime:: + + sage: R = PolynomialRing(Zmod(15^20), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a ring (with zero-divisors), global ordering + // coefficients: ZZ/bigint(332525673007965087890625) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + + Non-prime finite field with large characteristic (not supported, see :issue:`33319`):: + + sage: PolynomialRing(GF((2^31+11)^2), ("a", "b"), implementation="singular") + Traceback (most recent call last): + ... + TypeError: characteristic must be <= 2147483647. """ cdef long cexponent cdef GFInfo* _param @@ -182,7 +284,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: cdef int offset cdef int nvars cdef int characteristic - cdef int modbase + cdef Integer ch, modbase cdef int ringorder_column_pos cdef int ringorder_column_asc @@ -377,21 +479,45 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _cf = nInitChar( n_Z, NULL) # integer coefficient ring _ring = rDefault (_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) - elif (isinstance(base_ring, FiniteField_generic) and base_ring.is_prime_field()): - if base_ring.characteristic() <= 2147483647: + elif isinstance(base_ring, sage.rings.abc.IntegerModRing): + + ch = base_ring.characteristic() + if ch < 2: + raise NotImplementedError(f"polynomials over {base_ring} are not supported in Singular") + + isprime = ch.is_prime() + + if isprime and ch <= 2147483647: + assert isinstance(base_ring, FiniteField_generic) characteristic = base_ring.characteristic() + + # example for simpler ring creation interface without monomial orderings: + #_ring = rDefault(characteristic, nvars, _names) + + _ring = rDefault(characteristic, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + else: - raise TypeError("Characteristic p must be <= 2147483647.") + modbase, cexponent = ch.perfect_power() - # example for simpler ring creation interface without monomial orderings: - #_ring = rDefault(characteristic, nvars, _names) + if modbase == 2: + _cf = nInitChar(n_Z2m, cexponent) - _ring = rDefault(characteristic, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + elif modbase.is_prime(): + _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) + mpz_init_set(_info.base, modbase.value) + _info.exp = cexponent + _cf = nInitChar( n_Znm, &_info ) + + else: + _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) + mpz_init_set(_info.base, ch.value) + _info.exp = 1 + _cf = nInitChar( n_Zn, &_info ) + _ring = rDefault(_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, FiniteField_generic): - if base_ring.characteristic() <= 2147483647: - characteristic = -base_ring.characteristic() # note the negative characteristic - else: + assert not base_ring.is_prime_field() # would have been handled above + if base_ring.characteristic() > 2147483647: raise TypeError("characteristic must be <= 2147483647.") # TODO: This is lazy, it should only call Singular stuff not PolynomialRing() @@ -399,17 +525,10 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: name=base_ring.variable_name(), order='lex', implementation='singular') minpoly = base_ring.polynomial()(k.gen()) - ch = base_ring.characteristic() - F = ch.factor() - assert(len(F)==1) - - modbase = F[0][0] - cexponent = F[0][1] - _ext_names = omAlloc0(sizeof(char*)) _name = str_to_bytes(k._names[0]) _ext_names[0] = omStrDup(_name) - _cfr = rDefault( modbase, 1, _ext_names ) + _cfr = rDefault( base_ring.characteristic(), 1, _ext_names ) _cfr.qideal = idInit(1,1) rComplete(_cfr, 1) @@ -422,60 +541,6 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _ring = rDefault (_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) - elif isinstance(base_ring, sage.rings.abc.IntegerModRing): - - ch = base_ring.characteristic() - if ch < 2: - raise NotImplementedError(f"polynomials over {base_ring} are not supported in Singular") - - isprime = ch.is_prime() - - if not isprime and ch.is_power_of(2): - exponent = ch.nbits() -1 - cexponent = exponent - - if exponent <= 30: - ringtype = n_Z2m - else: - ringtype = n_Znm - - if ringtype == n_Znm: - F = ch.factor() - - modbase = F[0][0] - cexponent = F[0][1] - - _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) - mpz_init_set_ui(_info.base, modbase) - _info.exp = cexponent - _cf = nInitChar(ringtype, &_info) - else: # ringtype == n_Z2m - _cf = nInitChar(ringtype, cexponent) - - elif not isprime and ch.is_prime_power() and ch < ZZ(2)**160: - F = ch.factor() - assert(len(F)==1) - - modbase = F[0][0] - cexponent = F[0][1] - - _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) - mpz_init_set_ui(_info.base, modbase) - _info.exp = cexponent - _cf = nInitChar( n_Znm, &_info ) - - else: - try: - characteristic = ch - except OverflowError: - raise NotImplementedError("Characteristic %d too big." % ch) - - _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) - mpz_init_set_ui(_info.base, characteristic) - _info.exp = 1 - _cf = nInitChar( n_Zn, &_info ) - _ring = rDefault(_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) - else: raise NotImplementedError(f"polynomials over {base_ring} are not supported in Singular") From 88bb9957bfcf450f6cc0f23ec45c5be6ccd66355 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 00:57:58 +0700 Subject: [PATCH 02/17] Fix overflow in conversion int to singular number --- src/sage/libs/singular/singular.pyx | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 9c7b4078583..e3996a711b8 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -886,7 +886,7 @@ cdef number *sa2si_QQ(Rational r, ring *_ring) noexcept: - ``r`` -- a sage rational number - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -916,7 +916,7 @@ cdef number *sa2si_GFqGivaro(int quo, ring *_ring) noexcept: - ``quo`` -- sage integer - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -984,7 +984,7 @@ cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring) noexcept: - ``elem`` -- a sage element of a ntl_gf2e finite field - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -1049,7 +1049,7 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring) noexcept: - ``elem`` -- a sage element of a generic finite field - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -1075,6 +1075,9 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring) noexcept: cdef number *coeff cdef number *apow1 cdef number *apow2 + + if _ring.cf.type in (n_Zn, n_Znm): + return sa2si_ZZmod(elem, _ring) elem = elem.polynomial() if _ring != currRing: rChangeCurrRing(_ring) @@ -1115,7 +1118,7 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring) noexcept: - ``elem`` -- a sage element of a FractionField of polynomials over the rationals - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -1265,7 +1268,7 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring) noexcept: - ``elem`` -- a sage element of a FractionField of polynomials over the rationals - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -1365,7 +1368,7 @@ cdef number *sa2si_NF(object elem, ring *_ring) noexcept: - ``elem`` -- a sage element of a NumberField - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -1457,7 +1460,7 @@ cdef number *sa2si_ZZ(Integer d, ring *_ring) noexcept: - ``elem`` -- a sage Integer - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live OUTPUT: @@ -1488,7 +1491,7 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring) noexcept: - ``elem`` -- a sage IntegerMod - - ``_ ring`` -- a (pointer to) a singular ring, where the resul will live + - ``_ ring`` -- a (pointer to) a singular ring, where the result will live TESTS:: @@ -1534,6 +1537,9 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring) noexcept: cdef nMapFunc nMapFuncPtr = NULL + if _ring.cf.type == n_unknown: + return n_Init(int(d),_ring.cf) + if _ring.cf.type == n_Z2m: _d = long(d) return nr2mMapZp(_d, currRing.cf, _ring.cf) @@ -1628,7 +1634,8 @@ cdef number *sa2si(Element elem, ring * _ring) noexcept: a (pointer to) a singular number """ cdef int i = 0 - if isinstance(elem._parent, FiniteField_prime_modn): + + if isinstance(elem._parent, FiniteField_prime_modn) and _ring.cf.type == n_Zp: return n_Init(int(elem),_ring.cf) elif isinstance(elem._parent, RationalField): @@ -1649,8 +1656,6 @@ cdef number *sa2si(Element elem, ring * _ring) noexcept: elif isinstance(elem._parent, NumberField) and elem._parent.is_absolute(): return sa2si_NF(elem, _ring) elif isinstance(elem._parent, IntegerModRing_generic): - if _ring.cf.type == n_unknown: - return n_Init(int(elem),_ring.cf) return sa2si_ZZmod(elem, _ring) elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)): if isinstance(elem._parent.base().base_ring(), RationalField): From 67084194ed376369935eb48801b3f2dfc8751078 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 01:09:37 +0700 Subject: [PATCH 03/17] Fix a wrong assertion --- src/sage/libs/singular/ring.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index f87f1b097ec..a60fb08ec47 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -488,7 +488,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: isprime = ch.is_prime() if isprime and ch <= 2147483647: - assert isinstance(base_ring, FiniteField_generic) + # base_ring might be an instance of FiniteField_generic (but Zmod(5) is not) characteristic = base_ring.characteristic() # example for simpler ring creation interface without monomial orderings: From 0764f2941a14af721a31119ff79895634393f177 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 01:24:37 +0700 Subject: [PATCH 04/17] Use different Singular type for Zmod versus FiniteField --- src/sage/libs/singular/ring.pyx | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index a60fb08ec47..b24d93eaea6 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -205,11 +205,29 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: // : names a b // block 2 : ordering C + When ``Zmod`` is used, use a different Singular type + (note that the print is wrong, the field in fact doesn't have zero-divisors):: + + sage: R = PolynomialRing(Zmod(2), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a ring (with zero-divisors), global ordering + // coefficients: ZZ/(2) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + sage: R = PolynomialRing(Zmod(3), ("a", "b"), implementation="singular"); print(sing_print(R)) + polynomial ring, over a ring (with zero-divisors), global ordering + // coefficients: ZZ/(3) + // number of vars : 2 + // block 1 : ordering dp + // : names a b + // block 2 : ordering C + Large prime (note that the print is wrong, the field in fact doesn't have zero-divisors):: sage: R = PolynomialRing(GF(2^128+51), ("a", "b"), implementation="singular"); print(sing_print(R)) polynomial ring, over a ring (with zero-divisors), global ordering - // coefficients: ZZ/(bigint(340282366920938463463374607431768211507)^1) + // coefficients: ZZ/bigint(340282366920938463463374607431768211507) // number of vars : 2 // block 1 : ordering dp // : names a b @@ -487,8 +505,8 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: isprime = ch.is_prime() - if isprime and ch <= 2147483647: - # base_ring might be an instance of FiniteField_generic (but Zmod(5) is not) + if isprime and ch <= 2147483647 and isinstance(base_ring, FiniteField_generic): + # don't use this branch for e.g. Zmod(5) characteristic = base_ring.characteristic() # example for simpler ring creation interface without monomial orderings: @@ -499,10 +517,10 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: else: modbase, cexponent = ch.perfect_power() - if modbase == 2: + if modbase == 2 and cexponent > 1: _cf = nInitChar(n_Z2m, cexponent) - elif modbase.is_prime(): + elif modbase.is_prime() and cexponent > 1: _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) mpz_init_set(_info.base, modbase.value) _info.exp = cexponent From 3aeab0ec01076d6fb8e0c502c9e01e249d7d2fe4 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 01:40:53 +0700 Subject: [PATCH 05/17] Fix (mostly) innocuous test failures --- src/sage/libs/singular/singular.pyx | 2 +- src/sage/rings/polynomial/multi_polynomial_element.py | 6 +++--- src/sage/rings/polynomial/multi_polynomial_ideal.py | 3 +-- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 6 +++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index e3996a711b8..4d59795b347 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -1515,7 +1515,7 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring) noexcept: sage: P. = Integers(2^32)[] sage: P(2^32-1) - 4294967295 + -1 sage: P(3) 3 diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 3e00ef62991..793b63c059b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -636,12 +636,12 @@ def degree(self, x=None, std_grading=False): sage: GF(3037000453)['x','y'].gen(0).degree(x0) # needs sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: x must canonically coerce to parent + TypeError: argument is not coercible to the parent sage: GF(3037000453)['x','y'].gen(0).degree(x^2) # needs sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: x must be one of the generators of the parent + TypeError: argument is not a generator TESTS:: @@ -817,7 +817,7 @@ def monomial_coefficients(self): ``dict`` is an alias:: - sage: f.dict() # needs sage.rings.number_field + sage: f.dict() # needs sage.rings.number_field {(1, 5, 2): 1, (2, 0, 1): 1, (4, 1, 3): 1} """ return self.element().dict() diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index d06f07d722e..f716563b22f 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -4527,8 +4527,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal sage: R. = PolynomialRing(Zmod(2233497349584)) sage: I = R.ideal([z*(x-3*y), 3^2*x^2-y*z, z^2+y^2]) sage: I.groebner_basis() - [2*z^4, y*z^2 + 81*z^3, 248166372176*z^3, 9*x^2 - y*z, y^2 + z^2, x*z + - 2233497349581*y*z, 248166372176*y*z] + [2*z^4, y*z^2 + 81*z^3, 248166372176*z^3, 9*x^2 + 2233497349583*y*z, y^2 + z^2, x*z + 2233497349581*y*z, 248166372176*y*z] Sage also supports local orderings:: diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 72b4aea43ce..0b8b25f0c4d 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -65,7 +65,7 @@ We show how to construct various multivariate polynomial rings:: sage: P. = Zmod(25213521351515232)[]; P Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232 sage: type(P) - + We construct the Frobenius morphism on `\GF{5}[x,y,z]` over `\GF{5}`:: @@ -340,11 +340,11 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232 sage: type(P) - + sage: P. = PolynomialRing(Integers(2^32), order='lex') sage: P(2^32-1) - 4294967295 + -1 TESTS: From f85e29146dc758269ca6e71a01aee63d589960c9 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 02:10:29 +0700 Subject: [PATCH 06/17] Fix another overflow by modifying si2sa_* accordingly --- src/sage/libs/singular/singular.pyx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 4d59795b347..417efe71e4f 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -302,6 +302,9 @@ cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): cdef object ret cdef ring *cfRing = _ring.cf.extRing + if _ring.cf.type in (n_Zn, n_Znm): + return si2sa_ZZmod(n, _ring, base) + if _ring.cf.cfIsZero(n,_ring.cf): return base.zero() elif _ring.cf.cfIsOne(n,_ring.cf): @@ -1583,7 +1586,7 @@ cdef object si2sa(number *n, ring *_ring, object base): An element of ``base`` """ - if isinstance(base, FiniteField_prime_modn): + if isinstance(base, FiniteField_prime_modn) and _ring.cf.type == n_Zp: return base(_ring.cf.cfInt(n, _ring.cf)) elif isinstance(base, RationalField): @@ -1611,8 +1614,6 @@ cdef object si2sa(number *n, ring *_ring, object base): return si2sa_transext_FF(n, _ring, base) elif isinstance(base, IntegerModRing_generic): - if _ring.cf.type == n_unknown: - return base(_ring.cf.cfInt(n, _ring.cf)) return si2sa_ZZmod(n, _ring, base) else: From 75a21e60bd0b1f100b17a58fee46d25456a38ace Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 08:37:07 +0700 Subject: [PATCH 07/17] Fix affected functions and some cleanup --- src/sage/libs/singular/function.pyx | 14 +- src/sage/libs/singular/singular.pxd | 7 + src/sage/libs/singular/singular.pyx | 56 +++- .../multi_polynomial_libsingular.pyx | 266 ++++++++++++++---- src/sage/rings/quotient_ring.py | 2 +- 5 files changed, 287 insertions(+), 58 deletions(-) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 7bf2afafbe8..753427621c5 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -97,7 +97,7 @@ from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence_g from sage.libs.singular.decl cimport * from sage.libs.singular.option import opt_ctx from sage.libs.singular.polynomial cimport singular_vector_maximal_component -from sage.libs.singular.singular cimport sa2si, si2sa, si2sa_intvec, si2sa_bigintvec +from sage.libs.singular.singular cimport sa2si, si2sa, si2sa_intvec, si2sa_bigintvec, start_catch_error, check_error from sage.libs.singular.singular import error_messages from sage.interfaces.singular import get_docstring @@ -1453,7 +1453,6 @@ cdef inline call_function(SingularFunction self, tuple args, object R, bint sign global errorreported global currentVoice global myynest - global error_messages cdef ring *si_ring if isinstance(R, MPolynomialRing_libsingular): @@ -1474,10 +1473,7 @@ cdef inline call_function(SingularFunction self, tuple args, object R, bint sign currentVoice = NULL myynest = 0 - errorreported = 0 - - while error_messages: - error_messages.pop() + start_catch_error() with opt_ctx: # we are preserving the global options state here if signal_handler: @@ -1493,10 +1489,10 @@ cdef inline call_function(SingularFunction self, tuple args, object R, bint sign if currentVoice: currentVoice = NULL - if errorreported: - errorreported = 0 + s = check_error() + if s: raise RuntimeError("error in Singular function call %r:\n%s" % - (self._name, "\n".join(error_messages))) + (self._name, "\n".join(s))) res = argument_list.to_python(_res) diff --git a/src/sage/libs/singular/singular.pxd b/src/sage/libs/singular/singular.pxd index 9d764b51a6f..a0019fe4ede 100644 --- a/src/sage/libs/singular/singular.pxd +++ b/src/sage/libs/singular/singular.pxd @@ -55,6 +55,13 @@ cdef number *sa2si_NF(object element, ring *_ring) noexcept # dispatches to all the above. cdef number *sa2si(Element elem, ring * _ring) noexcept +# ============== +# Error handling +# ============== + +cdef int start_catch_error() except -1 +cdef object check_error() + # ============== # Initialisation # ============== diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 417efe71e4f..77f39d77d47 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -25,6 +25,7 @@ cdef extern from "limits.h": long INT_MIN import os +from warnings import warn from libc.stdint cimport int64_t from sage.libs.singular.decl cimport * @@ -1812,10 +1813,63 @@ saved_PATH = os.environ["PATH"] init_libsingular() os.environ["PATH"] = saved_PATH +cdef bint catching_error = False + cdef void libsingular_error_callback(const_char_ptr s) noexcept: _s = char_to_str(s) - error_messages.append(_s) + if catching_error: + error_messages.append(_s) + else: + warn(f"error in Singular ignored: {_s}") + +cdef int start_catch_error() except -1: + """ + Helper function to convert Singular errors to Python exceptions. + + Must be used as follows:: + + start_catch_error() + ... + s = check_error() # nonempty tuple[str, ...] (error messages) or None + if s: + # at this point global variable ``error_messages`` is cleared + raise RuntimeError(...) + + Return value is ignored, only used for exception handling. + Note that :func:`check_error` can only be called exactly once. + """ + global errorreported, catching_error, error_messages + if catching_error: + raise RuntimeError("internal error: previous start_catch_error not ended with check_error") + catching_error = True + + if errorreported: + warn(f"error in Singular ignored: {', '.join(error_messages)}") + errorreported = False + error_messages.clear() + else: + assert not error_messages + return 0 + +cdef object check_error(): + """ + See :func:`start_catch_error`. + """ + global errorreported, catching_error, error_messages + if not catching_error: + raise RuntimeError("check_error must be preceded with start_catch_error") + catching_error = False + + if errorreported: + result = tuple(error_messages) + assert result + errorreported = False + error_messages.clear() + return result + else: + assert not error_messages + return None def get_resource(id): """ diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 0b8b25f0c4d..6ccfedf34ab 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -198,7 +198,7 @@ from sage.libs.singular.decl cimport ( prCopyR, prCopyR_NoSort) # singular conversion routines -from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check +from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check, start_catch_error, check_error # singular poly arith from sage.libs.singular.polynomial cimport ( @@ -212,6 +212,8 @@ from sage.libs.singular.polynomial cimport ( # singular rings from sage.libs.singular.ring cimport singular_ring_new, singular_ring_reference, singular_ring_delete +from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn + # polynomial imports from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict, MPolynomialRing_polydict_domain from sage.rings.polynomial.multi_polynomial_ring_base import BooleanPolynomialRing_base @@ -4151,6 +4153,37 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): True sage: p*q//p == q True + + Test many base rings:: + + sage: R.=GF(2^32+15)[] + sage: ((x+y)^3+x+z)//(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented. + sage: R.=Zmod(2^29-3)[] + sage: ((x+y)^3+x+z)//(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented. + sage: R.=GF(2^29+11)[] + sage: ((x+y)^3+x+z)//(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29+10)[] + sage: ((x+y)^3+x+z)//(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=GF((2^29-3)^2)[] + sage: ((x+y)^3+x+z)//(x+y) + x^2 + 2*x*y + y^2 + sage: R.=Zmod(7^2)[] + sage: ((x+y)^3+x+z)//(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented. """ cdef MPolynomialRing_libsingular parent = self._parent cdef MPolynomial_libsingular _right = right @@ -4461,6 +4494,35 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: N = -a^4*z^8 + 2*a^2*b^2*z^8 - b^4*z^8 - 16*a^3*b*z^7 + 16*a*b^3*z^7 + 28*a^4*z^6 - 56*a^2*b^2*z^6 + 28*b^4*z^6 + 112*a^3*b*z^5 - 112*a*b^3*z^5 - 70*a^4*z^4 + 140*a^2*b^2*z^4 - 70*b^4*z^4 - 112*a^3*b*z^3 + 112*a*b^3*z^3 + 28*a^4*z^2 - 56*a^2*b^2*z^2 + 28*b^4*z^2 + 16*a^3*b*z - 16*a*b^3*z - a^4 + 2*a^2*b^2 - b^4 sage: N.factor() (-1) * (-a + b) * (a + b) * (-z^4*a + z^4*b - 4*z^3*a - 4*z^3*b + 6*z^2*a - 6*z^2*b + 4*z*a + 4*z*b - a + b) * (z^4*a + z^4*b - 4*z^3*a + 4*z^3*b - 6*z^2*a - 6*z^2*b + 4*z*a - 4*z*b + a + b) + + Test many base rings:: + + sage: R.=GF(2^32+15)[] + sage: ((x+y)^2*(x+z)^3).factor() + Traceback (most recent call last): + ... + NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29-3)[] + sage: ((x+y)^2*(x+z)^3).factor() + (x + y)^2 * (x + z)^3 + sage: R.=GF(2^29+11)[] + sage: ((x+y)^2*(x+z)^3).factor() + Traceback (most recent call last): + ... + NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29+10)[] + sage: ((x+y)^2*(x+z)^3).factor() + Traceback (most recent call last): + ... + NotImplementedError: Factorization of multivariate polynomials over Ring of integers modulo 536870922 is not implemented. + sage: R.=GF((2^29-3)^2)[] + sage: ((x+y)^2*(x+z)^3).factor() + (x + y)^2 * (x + z)^3 + sage: R.=Zmod(7^2)[] + sage: ((x+y)^2*(x+z)^3).factor() + Traceback (most recent call last): + ... + NotImplementedError: Factorization of multivariate polynomials over Ring of integers modulo 49 is not implemented. """ cdef ring *_ring = self._parent_ring cdef poly *ptemp @@ -4485,31 +4547,31 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): except Exception: raise NotImplementedError("Factorization of multivariate polynomials over %s is not implemented."%self._parent._base) - if n_GetChar(_ring.cf) > 1<<29: - raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - - # I make a temporary copy of the poly in self because singclap_factorize appears to modify it's parameter - ptemp = p_Copy(self._poly, _ring) iv = NULL - sig_on() if _ring != currRing: rChangeCurrRing(_ring) # singclap_factorize - I = singclap_factorize(ptemp, &iv, 0, _ring) + start_catch_error() + sig_on() + I = singclap_factorize(p_Copy(self._poly, _ring), &iv, 0, _ring) sig_off() - ivv = iv.ivGetVec() - v = [(new_MP(parent, p_Copy(I.m[i], _ring)), ivv[i]) - for i in range(1, I.ncols)] - v = [(f, m) for f, m in v if f != 0] # we might have zero in there - unit = new_MP(parent, p_Copy(I.m[0], _ring)) + try: + if check_error(): + raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - F = Factorization(v, unit) - F.sort() + ivv = iv.ivGetVec() + v = [(new_MP(parent, p_Copy(I.m[i], _ring)), ivv[i]) + for i in range(1, I.ncols)] + v = [(f, m) for f, m in v if f != 0] # we might have zero in there + unit = new_MP(parent, p_Copy(I.m[0], _ring)) - del iv - id_Delete(&I, _ring) + F = Factorization(v, unit) + F.sort() + return F + finally: + del iv + id_Delete(&I, _ring) - return F def lift(self, I): """ @@ -4731,7 +4793,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): id_Delete(&_I,r) return new_MP(parent,res) - def divides(self, other): + @coerce_binop + def divides(self, MPolynomial_libsingular other): """ Return ``True`` if this polynomial divides ``other``. @@ -4763,27 +4826,19 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): rChangeCurrRing(r) _I = idInit(1, 1) - if not (isinstance(other,MPolynomial_libsingular) - and (other)._parent is parent): - try: - other = parent.coerce(other) - except TypeError as msg: - id_Delete(&_I,r) - raise TypeError(msg) - _I.m[0] = p_Copy(self._poly, r) if r != currRing: rChangeCurrRing(r) sig_on() - rem = kNF(_I, NULL, (other)._poly, 0, 1) + rem = kNF(_I, NULL, other._poly, 0, 1) sig_off() id_Delete(&_I, r) res = new_MP(parent, rem).is_zero() return res @coerce_binop - def gcd(self, right, algorithm=None, **kwds): + def gcd(self, MPolynomial_libsingular right, algorithm=None, **kwds): """ Return the greatest common divisor of ``self`` and ``right``. @@ -4858,10 +4913,40 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: q = -3*x^2*y^7*z + 2*x*y^6*z^3 + 2*x^2*y^3*z^4 + x^2*y^5 - 7*x*y^5*z sage: (21^3*p^2*q).gcd(35^2*p*q^2) == -49*p*q True + + Test many base rings:: + + sage: R.=GF(2^32+15)[] + sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + NotImplementedError: GCD over rings not implemented. + sage: R.=Zmod(2^29-3)[] + sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + NotImplementedError: GCD over rings not implemented. + sage: R.=GF(2^29+11)[] + sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + NotImplementedError: GCD of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29+10)[] + sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + NotImplementedError: GCD over rings not implemented. + sage: R.=GF((2^29-3)^2)[] + sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) + x^2 + 2*x*y + y^2 + sage: R.=Zmod(7^2)[] + sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + NotImplementedError: GCD over rings not implemented. """ cdef poly *_res cdef ring *_ring = self._parent_ring - cdef MPolynomial_libsingular _right = right if algorithm is None or algorithm == "modular": On(SW_USE_CHINREM_GCD) @@ -4872,13 +4957,13 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): else: raise TypeError("algorithm %s not supported" % algorithm) - if _right._poly == NULL: + if right._poly == NULL: return self elif self._poly == NULL: return right elif p_IsOne(self._poly, _ring): return self - elif p_IsOne(_right._poly, _ring): + elif p_IsOne(right._poly, _ring): return right if _ring.cf.type != n_unknown: @@ -4889,10 +4974,10 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): raise NotImplementedError("GCD of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") cdef int count = singular_polynomial_length_bounded(self._poly, 20) \ - + singular_polynomial_length_bounded(_right._poly,20) + + singular_polynomial_length_bounded(right._poly,20) if count >= 20: sig_on() - _res = singclap_gcd(p_Copy(self._poly, _ring), p_Copy(_right._poly, _ring), _ring ) + _res = singclap_gcd(p_Copy(self._poly, _ring), p_Copy(right._poly, _ring), _ring ) if count >= 20: sig_off() @@ -4944,6 +5029,37 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): 2*x*y sage: lcm(2*x, 2*x*y) 2*x*y + + Test many base rings:: + + sage: R.=GF(2^32+15)[] + sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + TypeError: LCM over non-integral domains not available. + sage: R.=Zmod(2^29-3)[] + sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + TypeError: LCM over non-integral domains not available. + sage: R.=GF(2^29+11)[] + sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + NotImplementedError: LCM of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29+10)[] + sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + TypeError: LCM over non-integral domains not available. + sage: R.=GF((2^29-3)^2)[] + sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) + x^6*y^5 + 3*x^5*y^6 + 3*x^4*y^7 + x^3*y^8 + 5*x^6*y^4*z + 18*x^5*y^5*z + 24*x^4*y^6*z + 14*x^3*y^7*z + 3*x^2*y^8*z + 10*x^6*y^3*z^2 + 45*x^5*y^4*z^2 + 78*x^4*y^5*z^2 + 64*x^3*y^6*z^2 + 24*x^2*y^7*z^2 + 3*x*y^8*z^2 + 10*x^6*y^2*z^3 + 60*x^5*y^3*z^3 + 135*x^4*y^4*z^3 + 146*x^3*y^5*z^3 + 78*x^2*y^6*z^3 + 18*x*y^7*z^3 + y^8*z^3 + 5*x^6*y*z^4 + 45*x^5*y^2*z^4 + 135*x^4*y^3*z^4 + 190*x^3*y^4*z^4 + 135*x^2*y^5*z^4 + 45*x*y^6*z^4 + 5*y^7*z^4 + x^6*z^5 + 18*x^5*y*z^5 + 78*x^4*y^2*z^5 + 146*x^3*y^3*z^5 + 135*x^2*y^4*z^5 + 60*x*y^5*z^5 + 10*y^6*z^5 + 3*x^5*z^6 + 24*x^4*y*z^6 + 64*x^3*y^2*z^6 + 78*x^2*y^3*z^6 + 45*x*y^4*z^6 + 10*y^5*z^6 + 3*x^4*z^7 + 14*x^3*y*z^7 + 24*x^2*y^2*z^7 + 18*x*y^3*z^7 + 5*y^4*z^7 + x^3*z^8 + 3*x^2*y*z^8 + 3*x*y^2*z^8 + y^3*z^8 + sage: R.=Zmod(7^2)[] + sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) + Traceback (most recent call last): + ... + TypeError: LCM over non-integral domains not available. """ cdef ring *_ring = self._parent_ring cdef poly *ret @@ -5026,6 +5142,35 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... ZeroDivisionError + + Test many base rings:: + + sage: R.=GF(2^32+15)[] + sage: ((x+y)^3+x+z).quo_rem(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29-3)[] + sage: ((x+y)^3+x+z).quo_rem(x+y) + (x^2 + 2*x*y + y^2, x + z) + sage: R.=GF(2^29+11)[] + sage: ((x+y)^3+x+z).quo_rem(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29+10)[] + sage: ((x+y)^3+x+z).quo_rem(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=GF((2^29-3)^2)[] + sage: ((x+y)^3+x+z).quo_rem(x+y) + (x^2 + 2*x*y + y^2, x + z) + sage: R.=Zmod(7^2)[] + sage: ((x+y)^3+x+z).quo_rem(x+y) + Traceback (most recent call last): + ... + NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented. """ cdef poly *quo cdef poly *rem @@ -5041,14 +5186,14 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): py_rem = self - right*py_quo return py_quo, py_rem - if n_GetChar(r.cf) > 1<<29: - raise NotImplementedError("Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - cdef int count = singular_polynomial_length_bounded(self._poly, 15) if count >= 15: # note that _right._poly must be of shorter length than self._poly for us to care about this call sig_on() if r!=currRing: rChangeCurrRing(r) # singclap_pdivide + start_catch_error() quo = singclap_pdivide( self._poly, right._poly, r ) + if check_error(): + raise NotImplementedError("Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") rem = p_Add_q(p_Copy(self._poly, r), p_Neg(pp_Mult_qq(right._poly, quo, r), r), r) if count >= 15: sig_off() @@ -5424,6 +5569,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): _p = p_Add_q(_p, mon, _ring) return new_MP(self._parent, _p) + @coerce_binop def resultant(self, MPolynomial_libsingular other, variable=None): """ Compute the resultant of this polynomial and the first @@ -5479,31 +5625,50 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: g=y^2+x sage: f.resultant(g,y) x^2 + x + + sage: R.=GF(2^32+15)[] + sage: (x-z).resultant(y-z,z) + Traceback (most recent call last): + ... + NotImplementedError: Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29-3)[] + sage: (x-z).resultant(y-z,z) + x + 536870908*y + sage: R.=GF(2^29+11)[] + sage: (x-z).resultant(y-z,z) + Traceback (most recent call last): + ... + NotImplementedError: Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + sage: R.=Zmod(2^29+10)[] + sage: (x-z).resultant(y-z,z) + Traceback (most recent call last): + ... + NotImplementedError: Resultants require base fields or integer base ring. + sage: R.=GF((2^29-3)^2)[] + sage: (x-z).resultant(y-z,z) + x - y + sage: R.=Zmod(7^2)[] + sage: (x-z).resultant(y-z,z) + Traceback (most recent call last): + ... + NotImplementedError: Resultants require base fields or integer base ring. """ cdef ring *_ring = self._parent_ring cdef poly *rt if variable is None: variable = self.parent().gen(0) - - if self._parent is not other._parent: - raise TypeError("first parameter needs to be an element of self.parent()") - - if not variable.parent() is self.parent(): + elif variable.parent() is not self.parent(): raise TypeError("second parameter needs to be an element of self.parent() or None") - if n_GetChar(_ring.cf) > 1<<29: - raise NotImplementedError("Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - if isinstance(self._parent._base, IntegerRing_class): ret = self.change_ring(QQ).resultant(other.change_ring(QQ), variable.change_ring(QQ)) return ret.change_ring(ZZ) - elif not self._parent._base.is_field(): - raise ValueError("Resultants require base fields or integer base ring.") cdef int count = singular_polynomial_length_bounded(self._poly, 20) \ + singular_polynomial_length_bounded(other._poly,20) + start_catch_error() if count >= 20: sig_on() if _ring != currRing: rChangeCurrRing(_ring) # singclap_resultant @@ -5513,6 +5678,13 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): _ring) if count >= 20: sig_off() + + if check_error(): + if isinstance(self._parent._base, FiniteField_prime_modn): + raise NotImplementedError("Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") + else: + raise NotImplementedError("Resultants require base fields or integer base ring.") + return new_MP(self._parent, rt) def coefficients(self): diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index c867ba41bbc..7e3dd8c6d53 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -502,7 +502,7 @@ def __init__(self, R, I, names, category=None): # However, we don't just want to use the given category without mixing in # some quotient stuff - unless Parent.__init__ was called # previously, in which case the quotient ring stuff is just - # a vaste of time. This is the case for FiniteField_prime_modn. + # a waste of time. This is the case for FiniteField_prime_modn. if not self._is_category_initialized(): if category is None: try: From abf390e8360ca55880fdb651d708872ed96c8a69 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 11:09:16 +0700 Subject: [PATCH 08/17] Fix lint --- src/sage/libs/singular/singular.pyx | 1 + src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 77f39d77d47..9bc4d012102 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -1871,6 +1871,7 @@ cdef object check_error(): assert not error_messages return None + def get_resource(id): """ Return a Singular "resource". diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 6ccfedf34ab..9fea9c93a94 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4572,7 +4572,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): del iv id_Delete(&I, _ring) - def lift(self, I): """ Given an ideal ``I = (f_1,...,f_r)`` and some ``g (== self)`` in ``I``, From f17d29680d36a80ee142106456fb2c84f0c01d0e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:21:50 +0700 Subject: [PATCH 09/17] Modify existing error detection code as needed --- .../polynomial/multi_polynomial_libsingular.pyx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 9fea9c93a94..0edfa009867 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -170,6 +170,8 @@ AUTHORS: # * pNext and pIter don't need currRing # * p_Normalize apparently needs currRing +from warnings import warn + from cpython.object cimport Py_NE from cysignals.memory cimport sig_malloc, sig_free from cysignals.signals cimport sig_on, sig_off @@ -183,7 +185,6 @@ from sage.libs.singular.decl cimport (ring, poly, ideal, intvec, number, # singular functions from sage.libs.singular.decl cimport ( - errorreported, n_Invers, n_GetChar, p_ISet, rChangeCurrRing, p_Copy, p_Init, p_SetCoeff, p_Setm, p_SetExp, p_Add_q, p_NSet, p_GetCoeff, p_Delete, p_GetExp, pNext, rRingVar, omAlloc0, omStrDup, @@ -4635,8 +4636,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: foo[0][0] Ideal (x1 + 1, x2^2 - 3) of Multivariate Polynomial Ring in x1, x2 over Rational Field """ - global errorreported - cdef ideal *fI = idInit(1, 1) cdef ideal *_I cdef MPolynomialRing_libsingular parent = self._parent @@ -4667,15 +4666,15 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if r != currRing: rChangeCurrRing(r) # idLift + start_catch_error() sig_on() res = idLift(_I, fI, NULL, 0, 0, 0) sig_off() - if errorreported != 0: - errorcode = errorreported - errorreported = 0 - if errorcode == 1: - raise ValueError("polynomial is not in the ideal") - raise RuntimeError + s = check_error() + if s: + if s != ('2nd module does not lie in the first',): + warn(f'unexpected error from singular: {s}') + raise ValueError("polynomial is not in the ideal") l = [] for i from 0 <= i < IDELEMS(res): From fabaea20979ad9f1ddeb0cf61d12dc47640c43c4 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:52:45 +0700 Subject: [PATCH 10/17] Fix alarms --- src/sage/libs/singular/singular.pyx | 41 +++- .../multi_polynomial_libsingular.pyx | 193 +++++++++++++----- 2 files changed, 178 insertions(+), 56 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 9bc4d012102..4a7a5d29d91 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -1838,10 +1838,47 @@ cdef int start_catch_error() except -1: Return value is ignored, only used for exception handling. Note that :func:`check_error` can only be called exactly once. + + Note that this *must not* be used in conjunction with :func:`sig_on` as follows:: + + start_catch_error() + sig_on() + ... + sig_off() + if check_error(): + raise RuntimeError(...) + + because if the code is interrupted, then :func:`check_error` is never called. + + Use the following instead:: + + start_catch_error() + try: + sig_on() + ... # long time + sig_off() + finally: + if check_error(): + raise RuntimeError(...) + + If the code inside (marked `# long time`) can also raise a Python exception, + the above is still wrong --- :func:`sig_off` may not be called. In this case + use a nested ``try`` as suggested in ``cysignals`` documentation:: + + start_catch_error() + try: + sig_on() # This must be OUTSIDE the inner try + try: + ... # long time + finally: + sig_off() + finally: + if check_error(): + raise RuntimeError(...) """ global errorreported, catching_error, error_messages if catching_error: - raise RuntimeError("internal error: previous start_catch_error not ended with check_error") + warn("internal error: previous start_catch_error not ended with check_error") catching_error = True if errorreported: @@ -1858,7 +1895,7 @@ cdef object check_error(): """ global errorreported, catching_error, error_messages if not catching_error: - raise RuntimeError("check_error must be preceded with start_catch_error") + warn("internal error: check_error not preceded with start_catch_error") catching_error = False if errorreported: diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 0edfa009867..c17ed18a405 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4524,12 +4524,29 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... NotImplementedError: Factorization of multivariate polynomials over Ring of integers modulo 49 is not implemented. + + Ensure interrupt does not make the internal state inconsistent:: + + sage: R. = QQ[] + sage: n = 11 # chosen so that the computation takes > 1 second but not excessively long. + ....: # when Singular improves the algorithm or hardware gets faster, increase n. + sage: alarm(0.5); h = (x^2^n-y^2^n).factor() + Traceback (most recent call last): + ... + AlarmInterrupt + sage: alarm(0.5); h = (x^2^n-y^2^n).factor() + Traceback (most recent call last): + ... + AlarmInterrupt + sage: h = (x^2^n-y^2^n).factor() + sage: h + (x - y) * (x + y) * (x^2 + y^2) * (x^4 + y^4) * (x^8 + y^8) * (x^16 + y^16) * (x^32 + y^32) * (x^64 + y^64) * (x^128 + y^128) * (x^256 + y^256) * (x^512 + y^512) * (x^1024 + y^1024) """ cdef ring *_ring = self._parent_ring cdef poly *ptemp cdef intvec *iv cdef int *ivv - cdef ideal *I + cdef ideal *I = NULL cdef MPolynomialRing_libsingular parent = self._parent cdef int i @@ -4552,13 +4569,14 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if _ring != currRing: rChangeCurrRing(_ring) # singclap_factorize start_catch_error() - sig_on() - I = singclap_factorize(p_Copy(self._poly, _ring), &iv, 0, _ring) - sig_off() - try: - if check_error(): - raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") + try: + sig_on() + I = singclap_factorize(p_Copy(self._poly, _ring), &iv, 0, _ring) + sig_off() + finally: + if check_error(): + raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") ivv = iv.ivGetVec() v = [(new_MP(parent, p_Copy(I.m[i], _ring)), ivv[i]) @@ -4621,7 +4639,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: M [y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 + y^4] - TESTS: Check that :issue:`13714` is fixed:: @@ -4635,6 +4652,24 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: foo = I.complete_primary_decomposition() # indirect doctest sage: foo[0][0] Ideal (x1 + 1, x2^2 - 3) of Multivariate Polynomial Ring in x1, x2 over Rational Field + + Ensure interrupt does not make the internal state inconsistent:: + + sage: R. = QQ[] + sage: n = 15 # chosen so that the computation takes > 1 second but not excessively long. + ....: # when Singular improves the algorithm or hardware gets faster, increase n. + sage: I = R.ideal([(x-i)*(y-j) for i in (0..n) for j in (0..n)]) + sage: f = prod((x-i)*(y-j) for i in (0..n) for j in (0..n)) + sage: alarm(0.5); f.lift(I) + Traceback (most recent call last): + ... + AlarmInterrupt + sage: alarm(0.5); f.lift(I) + Traceback (most recent call last): + ... + AlarmInterrupt + sage: f.lift(I) + Polynomial Sequence with 256 Polynomials in 2 Variables """ cdef ideal *fI = idInit(1, 1) cdef ideal *_I @@ -4642,7 +4677,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cdef int i = 0 cdef int j cdef ring *r = self._parent_ring - cdef ideal *res + cdef ideal *res = NULL if isinstance(I, MPolynomialIdeal): I = I.gens() @@ -4666,24 +4701,27 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if r != currRing: rChangeCurrRing(r) # idLift - start_catch_error() - sig_on() - res = idLift(_I, fI, NULL, 0, 0, 0) - sig_off() - s = check_error() - if s: - if s != ('2nd module does not lie in the first',): - warn(f'unexpected error from singular: {s}') - raise ValueError("polynomial is not in the ideal") - - l = [] - for i from 0 <= i < IDELEMS(res): - for j from 1 <= j <= IDELEMS(_I): - l.append( new_MP(parent, pTakeOutComp(&res.m[i], 1)) ) - - id_Delete(&fI, r) - id_Delete(&_I, r) - id_Delete(&res, r) + try: + start_catch_error() + try: + sig_on() + res = idLift(_I, fI, NULL, 0, 0, 0) + sig_off() + finally: + s = check_error() + if s: + if s != ('2nd module does not lie in the first',): + warn(f'unexpected error from singular: {s}') + raise ValueError("polynomial is not in the ideal") + + l = [] + for i from 0 <= i < IDELEMS(res): + for j from 1 <= j <= IDELEMS(_I): + l.append( new_MP(parent, pTakeOutComp(&res.m[i], 1)) ) + finally: + id_Delete(&fI, r) + id_Delete(&_I, r) + id_Delete(&res, r) return Sequence(l, check=False, immutable=True) def reduce(self, I): @@ -4828,10 +4866,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if r != currRing: rChangeCurrRing(r) - sig_on() - rem = kNF(_I, NULL, other._poly, 0, 1) - sig_off() - id_Delete(&_I, r) + try: + sig_on() + rem = kNF(_I, NULL, other._poly, 0, 1) + sig_off() + finally: + id_Delete(&_I, r) res = new_MP(parent, rem).is_zero() return res @@ -5169,6 +5209,27 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented. + + Ensure interrupt does not make the internal state inconsistent:: + + sage: R. = PolynomialRing(QQ, order="lex") + sage: n = 250 # chosen so that the computation takes > 1 second but not excessively long. + ....: # when Singular improves the algorithm or hardware gets faster, increase n. + sage: f = z^n-2 + sage: g = z^2-z-x^2*y-x*y^3 + sage: alarm(0.5); f.quo_rem(g) + Traceback (most recent call last): + ... + AlarmInterrupt + sage: alarm(0.5); f.quo_rem(g) + Traceback (most recent call last): + ... + AlarmInterrupt + sage: h = f.quo_rem(g) + sage: len(dict(h)) + Traceback (most recent call last): + ... + ValueError: dictionary update sequence element #0 has length 658875; 2 is required """ cdef poly *quo cdef poly *rem @@ -5184,17 +5245,16 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): py_rem = self - right*py_quo return py_quo, py_rem - cdef int count = singular_polynomial_length_bounded(self._poly, 15) - if count >= 15: # note that _right._poly must be of shorter length than self._poly for us to care about this call - sig_on() if r!=currRing: rChangeCurrRing(r) # singclap_pdivide start_catch_error() - quo = singclap_pdivide( self._poly, right._poly, r ) - if check_error(): - raise NotImplementedError("Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - rem = p_Add_q(p_Copy(self._poly, r), p_Neg(pp_Mult_qq(right._poly, quo, r), r), r) - if count >= 15: + try: + sig_on() + quo = singclap_pdivide( self._poly, right._poly, r ) sig_off() + finally: + if check_error(): + raise NotImplementedError("Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") + rem = p_Add_q(p_Copy(self._poly, r), p_Neg(pp_Mult_qq(right._poly, quo, r), r), r) return new_MP(parent, quo), new_MP(parent, rem) def _singular_init_(self, singular=None): @@ -5650,6 +5710,34 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... NotImplementedError: Resultants require base fields or integer base ring. + + Sometimes simple-looking computations can take a long time:: + + sage: R. = QQ[] + sage: n = 21 # chosen so that the computation takes > 1 second but not excessively long. + ....: # when Singular improves the algorithm or hardware gets faster, increase n. + sage: f = x^n+y^(n-1)+z^(n-2)+y^3*z^2 + sage: g = x^(n-3)+y^(n-4)+z^(n-5)+y*z + sage: h = f.resultant(g, x) + sage: len(dict(h)) + 1308 + + As such we test the computation is interruptible (previously it wasn't):: + + sage: alarm(1); h = f.resultant(g, x) + Traceback (most recent call last): + ... + AlarmInterrupt + + Test again to ensure interrupt does not make the internal state inconsistent:: + + sage: alarm(0.5); h = f.resultant(g, x); cancel_alarm() + Traceback (most recent call last): + ... + AlarmInterrupt + sage: h = f.resultant(g, x) + sage: len(dict(h)) + 1308 """ cdef ring *_ring = self._parent_ring cdef poly *rt @@ -5664,24 +5752,21 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): variable.change_ring(QQ)) return ret.change_ring(ZZ) - cdef int count = singular_polynomial_length_bounded(self._poly, 20) \ - + singular_polynomial_length_bounded(other._poly,20) start_catch_error() - if count >= 20: + try: sig_on() - if _ring != currRing: rChangeCurrRing(_ring) # singclap_resultant - rt = singclap_resultant(p_Copy(self._poly, _ring), - p_Copy(other._poly, _ring), - p_Copy((variable)._poly, _ring ), - _ring) - if count >= 20: + if _ring != currRing: rChangeCurrRing(_ring) # singclap_resultant + rt = singclap_resultant(p_Copy(self._poly, _ring), + p_Copy(other._poly, _ring), + p_Copy((variable)._poly, _ring ), + _ring) sig_off() - - if check_error(): - if isinstance(self._parent._base, FiniteField_prime_modn): - raise NotImplementedError("Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - else: - raise NotImplementedError("Resultants require base fields or integer base ring.") + finally: + if check_error(): + if isinstance(self._parent._base, FiniteField_prime_modn): + raise NotImplementedError("Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") + else: + raise NotImplementedError("Resultants require base fields or integer base ring.") return new_MP(self._parent, rt) From 287cb943005ebf66bf5452a6b223889c8c0e6938 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 5 Dec 2024 08:02:49 +0700 Subject: [PATCH 11/17] Fix interruption of singular call_function --- src/sage/libs/singular/function.pyx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 753427621c5..2e35e86e99e 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1477,11 +1477,15 @@ cdef inline call_function(SingularFunction self, tuple args, object R, bint sign with opt_ctx: # we are preserving the global options state here if signal_handler: - sig_on() - _res = self.call_handler.handle_call(argument_list, si_ring) - sig_off() + try: + sig_on() + _res = self.call_handler.handle_call(argument_list, si_ring) + sig_off() + finally: + s = check_error() else: _res = self.call_handler.handle_call(argument_list, si_ring) + s = check_error() if myynest: myynest = 0 @@ -1489,7 +1493,6 @@ cdef inline call_function(SingularFunction self, tuple args, object R, bint sign if currentVoice: currentVoice = NULL - s = check_error() if s: raise RuntimeError("error in Singular function call %r:\n%s" % (self._name, "\n".join(s))) From 23654283885203d074162fec0645330521e4e4d0 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 5 Dec 2024 08:58:40 +0700 Subject: [PATCH 12/17] Increase n to make test pass --- .../rings/polynomial/multi_polynomial_libsingular.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index c17ed18a405..08f94b1caf5 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -5714,17 +5714,17 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Sometimes simple-looking computations can take a long time:: sage: R. = QQ[] - sage: n = 21 # chosen so that the computation takes > 1 second but not excessively long. + sage: n = 22 # chosen so that the computation takes > 1 second but not excessively long. ....: # when Singular improves the algorithm or hardware gets faster, increase n. sage: f = x^n+y^(n-1)+z^(n-2)+y^3*z^2 sage: g = x^(n-3)+y^(n-4)+z^(n-5)+y*z sage: h = f.resultant(g, x) sage: len(dict(h)) - 1308 + 89 As such we test the computation is interruptible (previously it wasn't):: - sage: alarm(1); h = f.resultant(g, x) + sage: alarm(0.5); h = f.resultant(g, x) Traceback (most recent call last): ... AlarmInterrupt @@ -5737,7 +5737,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): AlarmInterrupt sage: h = f.resultant(g, x) sage: len(dict(h)) - 1308 + 89 """ cdef ring *_ring = self._parent_ring cdef poly *rt From 282d52e8161b5c44888a3c072c9a4adef3daf481 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 7 Dec 2024 23:26:04 +0700 Subject: [PATCH 13/17] Apply suggestions from code review Co-authored-by: Martin Rubey --- src/sage/libs/singular/function.pyx | 6 +- src/sage/libs/singular/ring.pyx | 13 ++- src/sage/libs/singular/singular.pyx | 7 +- .../multi_polynomial_libsingular.pyx | 106 +++++++++--------- 4 files changed, 64 insertions(+), 68 deletions(-) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 2e35e86e99e..766eb8826e1 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1450,7 +1450,6 @@ EXAMPLES:: cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None): global currRingHdl - global errorreported global currentVoice global myynest @@ -1487,15 +1486,14 @@ cdef inline call_function(SingularFunction self, tuple args, object R, bint sign _res = self.call_handler.handle_call(argument_list, si_ring) s = check_error() - if myynest: - myynest = 0 + myynest = 0 if currentVoice: currentVoice = NULL if s: raise RuntimeError("error in Singular function call %r:\n%s" % - (self._name, "\n".join(s))) + (self._name, "\n".join(s))) res = argument_list.to_python(_res) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index b24d93eaea6..fa7343f8dca 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -521,16 +521,16 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _cf = nInitChar(n_Z2m, cexponent) elif modbase.is_prime() and cexponent > 1: - _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) + _info.base = <__mpz_struct *>omAlloc(sizeof(__mpz_struct)) mpz_init_set(_info.base, modbase.value) _info.exp = cexponent - _cf = nInitChar( n_Znm, &_info ) + _cf = nInitChar(n_Znm, &_info) else: - _info.base = <__mpz_struct*>omAlloc(sizeof(__mpz_struct)) + _info.base = <__mpz_struct *>omAlloc(sizeof(__mpz_struct)) mpz_init_set(_info.base, ch.value) _info.exp = 1 - _cf = nInitChar( n_Zn, &_info ) + _cf = nInitChar(n_Zn, &_info) _ring = rDefault(_cf, nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) elif isinstance(base_ring, FiniteField_generic): @@ -540,13 +540,14 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: # TODO: This is lazy, it should only call Singular stuff not PolynomialRing() k = PolynomialRing(base_ring.prime_subfield(), - name=base_ring.variable_name(), order='lex', implementation='singular') + name=base_ring.variable_name(), order='lex', + implementation='singular') minpoly = base_ring.polynomial()(k.gen()) _ext_names = omAlloc0(sizeof(char*)) _name = str_to_bytes(k._names[0]) _ext_names[0] = omStrDup(_name) - _cfr = rDefault( base_ring.characteristic(), 1, _ext_names ) + _cfr = rDefault(base_ring.characteristic(), 1, _ext_names) _cfr.qideal = idInit(1,1) rComplete(_cfr, 1) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 4a7a5d29d91..9e665e481be 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -1542,7 +1542,7 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring) noexcept: cdef nMapFunc nMapFuncPtr = NULL if _ring.cf.type == n_unknown: - return n_Init(int(d),_ring.cf) + return n_Init(int(d), _ring.cf) if _ring.cf.type == n_Z2m: _d = long(d) @@ -1904,9 +1904,8 @@ cdef object check_error(): errorreported = False error_messages.clear() return result - else: - assert not error_messages - return None + assert not error_messages + return None def get_resource(id): diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 08f94b1caf5..fddb8234e11 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4157,30 +4157,30 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Test many base rings:: - sage: R.=GF(2^32+15)[] + sage: R. = GF(2^32+15)[] sage: ((x+y)^3+x+z)//(x+y) Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented. - sage: R.=Zmod(2^29-3)[] + sage: R. = Zmod(2^29-3)[] sage: ((x+y)^3+x+z)//(x+y) Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented. - sage: R.=GF(2^29+11)[] + sage: R. = GF(2^29+11)[] sage: ((x+y)^3+x+z)//(x+y) Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29+10)[] + sage: R. = Zmod(2^29+10)[] sage: ((x+y)^3+x+z)//(x+y) Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=GF((2^29-3)^2)[] + sage: R. = GF((2^29-3)^2)[] sage: ((x+y)^3+x+z)//(x+y) x^2 + 2*x*y + y^2 - sage: R.=Zmod(7^2)[] + sage: R. = Zmod(7^2)[] sage: ((x+y)^3+x+z)//(x+y) Traceback (most recent call last): ... @@ -4498,28 +4498,28 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Test many base rings:: - sage: R.=GF(2^32+15)[] + sage: R. = GF(2^32+15)[] sage: ((x+y)^2*(x+z)^3).factor() Traceback (most recent call last): ... NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29-3)[] + sage: R. = Zmod(2^29-3)[] sage: ((x+y)^2*(x+z)^3).factor() (x + y)^2 * (x + z)^3 - sage: R.=GF(2^29+11)[] + sage: R. = GF(2^29+11)[] sage: ((x+y)^2*(x+z)^3).factor() Traceback (most recent call last): ... NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29+10)[] + sage: R. = Zmod(2^29+10)[] sage: ((x+y)^2*(x+z)^3).factor() Traceback (most recent call last): ... NotImplementedError: Factorization of multivariate polynomials over Ring of integers modulo 536870922 is not implemented. - sage: R.=GF((2^29-3)^2)[] + sage: R. = GF((2^29-3)^2)[] sage: ((x+y)^2*(x+z)^3).factor() (x + y)^2 * (x + z)^3 - sage: R.=Zmod(7^2)[] + sage: R. = Zmod(7^2)[] sage: ((x+y)^2*(x+z)^3).factor() Traceback (most recent call last): ... @@ -4579,9 +4579,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") ivv = iv.ivGetVec() - v = [(new_MP(parent, p_Copy(I.m[i], _ring)), ivv[i]) - for i in range(1, I.ncols)] - v = [(f, m) for f, m in v if f != 0] # we might have zero in there + v = [(f, ivv[i]) for i in range(1, I.ncols) + if (f := new_MP(parent, p_Copy(I.m[i], _ring)))] unit = new_MP(parent, p_Copy(I.m[0], _ring)) F = Factorization(v, unit) @@ -4714,10 +4713,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): warn(f'unexpected error from singular: {s}') raise ValueError("polynomial is not in the ideal") - l = [] - for i from 0 <= i < IDELEMS(res): - for j from 1 <= j <= IDELEMS(_I): - l.append( new_MP(parent, pTakeOutComp(&res.m[i], 1)) ) + l = [new_MP(parent, pTakeOutComp(&res.m[i], 1)) + for i in range(IDELEMS(res)) for _ in range(IDELEMS(_I))] finally: id_Delete(&fI, r) id_Delete(&_I, r) @@ -4954,30 +4951,30 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Test many base rings:: - sage: R.=GF(2^32+15)[] + sage: R. = GF(2^32+15)[] sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) Traceback (most recent call last): ... NotImplementedError: GCD over rings not implemented. - sage: R.=Zmod(2^29-3)[] + sage: R. = Zmod(2^29-3)[] sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) Traceback (most recent call last): ... NotImplementedError: GCD over rings not implemented. - sage: R.=GF(2^29+11)[] + sage: R. = GF(2^29+11)[] sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) Traceback (most recent call last): ... NotImplementedError: GCD of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29+10)[] + sage: R. = Zmod(2^29+10)[] sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) Traceback (most recent call last): ... NotImplementedError: GCD over rings not implemented. - sage: R.=GF((2^29-3)^2)[] + sage: R. = GF((2^29-3)^2)[] sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) x^2 + 2*x*y + y^2 - sage: R.=Zmod(7^2)[] + sage: R. = Zmod(7^2)[] sage: ((x+y)^2*(x+z)^3).gcd((x+y)^3*(y+z)^5) Traceback (most recent call last): ... @@ -5012,10 +5009,10 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): raise NotImplementedError("GCD of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") cdef int count = singular_polynomial_length_bounded(self._poly, 20) \ - + singular_polynomial_length_bounded(right._poly,20) + + singular_polynomial_length_bounded(right._poly, 20) if count >= 20: sig_on() - _res = singclap_gcd(p_Copy(self._poly, _ring), p_Copy(right._poly, _ring), _ring ) + _res = singclap_gcd(p_Copy(self._poly, _ring), p_Copy(right._poly, _ring), _ring) if count >= 20: sig_off() @@ -5070,30 +5067,30 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Test many base rings:: - sage: R.=GF(2^32+15)[] + sage: R. = GF(2^32+15)[] sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) Traceback (most recent call last): ... TypeError: LCM over non-integral domains not available. - sage: R.=Zmod(2^29-3)[] + sage: R. = Zmod(2^29-3)[] sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) Traceback (most recent call last): ... TypeError: LCM over non-integral domains not available. - sage: R.=GF(2^29+11)[] + sage: R. = GF(2^29+11)[] sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) Traceback (most recent call last): ... NotImplementedError: LCM of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29+10)[] + sage: R. = Zmod(2^29+10)[] sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) Traceback (most recent call last): ... TypeError: LCM over non-integral domains not available. - sage: R.=GF((2^29-3)^2)[] + sage: R. = GF((2^29-3)^2)[] sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) x^6*y^5 + 3*x^5*y^6 + 3*x^4*y^7 + x^3*y^8 + 5*x^6*y^4*z + 18*x^5*y^5*z + 24*x^4*y^6*z + 14*x^3*y^7*z + 3*x^2*y^8*z + 10*x^6*y^3*z^2 + 45*x^5*y^4*z^2 + 78*x^4*y^5*z^2 + 64*x^3*y^6*z^2 + 24*x^2*y^7*z^2 + 3*x*y^8*z^2 + 10*x^6*y^2*z^3 + 60*x^5*y^3*z^3 + 135*x^4*y^4*z^3 + 146*x^3*y^5*z^3 + 78*x^2*y^6*z^3 + 18*x*y^7*z^3 + y^8*z^3 + 5*x^6*y*z^4 + 45*x^5*y^2*z^4 + 135*x^4*y^3*z^4 + 190*x^3*y^4*z^4 + 135*x^2*y^5*z^4 + 45*x*y^6*z^4 + 5*y^7*z^4 + x^6*z^5 + 18*x^5*y*z^5 + 78*x^4*y^2*z^5 + 146*x^3*y^3*z^5 + 135*x^2*y^4*z^5 + 60*x*y^5*z^5 + 10*y^6*z^5 + 3*x^5*z^6 + 24*x^4*y*z^6 + 64*x^3*y^2*z^6 + 78*x^2*y^3*z^6 + 45*x*y^4*z^6 + 10*y^5*z^6 + 3*x^4*z^7 + 14*x^3*y*z^7 + 24*x^2*y^2*z^7 + 18*x*y^3*z^7 + 5*y^4*z^7 + x^3*z^8 + 3*x^2*y*z^8 + 3*x*y^2*z^8 + y^3*z^8 - sage: R.=Zmod(7^2)[] + sage: R. = Zmod(7^2)[] sage: ((x+y)^2*(x+z)^3).lcm((x+y)^3*(y+z)^5) Traceback (most recent call last): ... @@ -5183,28 +5180,28 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Test many base rings:: - sage: R.=GF(2^32+15)[] + sage: R. = GF(2^32+15)[] sage: ((x+y)^3+x+z).quo_rem(x+y) Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29-3)[] + sage: R. = Zmod(2^29-3)[] sage: ((x+y)^3+x+z).quo_rem(x+y) (x^2 + 2*x*y + y^2, x + z) - sage: R.=GF(2^29+11)[] + sage: R. = GF(2^29+11)[] sage: ((x+y)^3+x+z).quo_rem(x+y) Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29+10)[] + sage: R. = Zmod(2^29+10)[] sage: ((x+y)^3+x+z).quo_rem(x+y) Traceback (most recent call last): ... NotImplementedError: Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=GF((2^29-3)^2)[] + sage: R. = GF((2^29-3)^2)[] sage: ((x+y)^3+x+z).quo_rem(x+y) (x^2 + 2*x*y + y^2, x + z) - sage: R.=Zmod(7^2)[] + sage: R. = Zmod(7^2)[] sage: ((x+y)^3+x+z).quo_rem(x+y) Traceback (most recent call last): ... @@ -5245,11 +5242,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): py_rem = self - right*py_quo return py_quo, py_rem - if r!=currRing: rChangeCurrRing(r) # singclap_pdivide + if r != currRing: + rChangeCurrRing(r) # singclap_pdivide start_catch_error() try: sig_on() - quo = singclap_pdivide( self._poly, right._poly, r ) + quo = singclap_pdivide(self._poly, right._poly, r) sig_off() finally: if check_error(): @@ -5684,28 +5682,28 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f.resultant(g,y) x^2 + x - sage: R.=GF(2^32+15)[] + sage: R. = GF(2^32+15)[] sage: (x-z).resultant(y-z,z) Traceback (most recent call last): ... NotImplementedError: Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29-3)[] + sage: R. = Zmod(2^29-3)[] sage: (x-z).resultant(y-z,z) x + 536870908*y - sage: R.=GF(2^29+11)[] + sage: R. = GF(2^29+11)[] sage: (x-z).resultant(y-z,z) Traceback (most recent call last): ... NotImplementedError: Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - sage: R.=Zmod(2^29+10)[] + sage: R. = Zmod(2^29+10)[] sage: (x-z).resultant(y-z,z) Traceback (most recent call last): ... NotImplementedError: Resultants require base fields or integer base ring. - sage: R.=GF((2^29-3)^2)[] + sage: R. = GF((2^29-3)^2)[] sage: (x-z).resultant(y-z,z) x - y - sage: R.=Zmod(7^2)[] + sage: R. = Zmod(7^2)[] sage: (x-z).resultant(y-z,z) Traceback (most recent call last): ... @@ -5755,18 +5753,18 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): start_catch_error() try: sig_on() - if _ring != currRing: rChangeCurrRing(_ring) # singclap_resultant - rt = singclap_resultant(p_Copy(self._poly, _ring), - p_Copy(other._poly, _ring), - p_Copy((variable)._poly, _ring ), - _ring) + if _ring != currRing: + rChangeCurrRing(_ring) # singclap_resultant + rt = singclap_resultant(p_Copy(self._poly, _ring), + p_Copy(other._poly, _ring), + p_Copy((variable)._poly, _ring), + _ring) sig_off() finally: if check_error(): if isinstance(self._parent._base, FiniteField_prime_modn): raise NotImplementedError("Resultants of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - else: - raise NotImplementedError("Resultants require base fields or integer base ring.") + raise NotImplementedError("Resultants require base fields or integer base ring.") return new_MP(self._parent, rt) From 55b698f511cd1cd943a955c8d1f7172a053cd3f8 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 8 Dec 2024 02:15:19 +0700 Subject: [PATCH 14/17] Fix a test failure Co-authored-by: Martin Rubey --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index fddb8234e11..adc8f503f6c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4579,8 +4579,9 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") ivv = iv.ivGetVec() - v = [(f, ivv[i]) for i in range(1, I.ncols) - if (f := new_MP(parent, p_Copy(I.m[i], _ring)))] + v = [(new_MP(parent, p_Copy(I.m[i], _ring)), ivv[i]) + for i in range(1, I.ncols)] + v = [(f, m) for f, m in v if f != 0] # we might have zero in there unit = new_MP(parent, p_Copy(I.m[0], _ring)) F = Factorization(v, unit) From f6c5a149238e50d9cb4a25e23c52d9808f070ab5 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 8 Dec 2024 10:52:19 +0700 Subject: [PATCH 15/17] Fix a doctest --- .../rings/polynomial/multi_polynomial_libsingular.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index adc8f503f6c..faf1cf0c0fd 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -5223,11 +5223,11 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... AlarmInterrupt - sage: h = f.quo_rem(g) - sage: len(dict(h)) - Traceback (most recent call last): - ... - ValueError: dictionary update sequence element #0 has length 658875; 2 is required + sage: q, r = f.quo_rem(g) + sage: len(dict(q)) + 178748 + sage: len(dict(r)) + 7993 """ cdef poly *quo cdef poly *rem From 10b31b3de29abfe8775802a4dae58307fed144d1 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 19 Dec 2024 07:55:14 +0700 Subject: [PATCH 16/17] Increase n in several places to make tests pass on faster computer --- .../rings/polynomial/multi_polynomial_libsingular.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 7834e4d93c0..6b7a519cf9b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4656,7 +4656,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Ensure interrupt does not make the internal state inconsistent:: sage: R. = QQ[] - sage: n = 15 # chosen so that the computation takes > 1 second but not excessively long. + sage: n = 17 # chosen so that the computation takes > 1 second but not excessively long. ....: # when Singular improves the algorithm or hardware gets faster, increase n. sage: I = R.ideal([(x-i)*(y-j) for i in (0..n) for j in (0..n)]) sage: f = prod((x-i)*(y-j) for i in (0..n) for j in (0..n)) @@ -5211,7 +5211,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Ensure interrupt does not make the internal state inconsistent:: sage: R. = PolynomialRing(QQ, order="lex") - sage: n = 250 # chosen so that the computation takes > 1 second but not excessively long. + sage: n = 300 # chosen so that the computation takes > 1 second but not excessively long. ....: # when Singular improves the algorithm or hardware gets faster, increase n. sage: f = z^n-2 sage: g = z^2-z-x^2*y-x*y^3 @@ -5225,9 +5225,9 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): AlarmInterrupt sage: q, r = f.quo_rem(g) sage: len(dict(q)) - 178748 + 307638 sage: len(dict(r)) - 7993 + 11409 """ cdef poly *quo cdef poly *rem From 963dde640e4f630ea135c05ac1ab20a78c1e866d Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:01:18 +0700 Subject: [PATCH 17/17] Fix tests --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 6b7a519cf9b..0d2cf86deeb 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4669,7 +4669,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): ... AlarmInterrupt sage: f.lift(I) - Polynomial Sequence with 256 Polynomials in 2 Variables + Polynomial Sequence with 324 Polynomials in 2 Variables """ cdef ideal *fI = idInit(1, 1) cdef ideal *_I