Ticket #12718: trac_12718_singular_overflow.patch
File trac_12718_singular_overflow.patch, 17.2 KB (added by , 11 years ago) |
---|
-
sage/libs/singular/groebner_strategy.pyx
# HG changeset patch # User Martin Albrecht <martinralbrecht@googlemail.com> # Date 1333205273 -3600 # Node ID 2d9acd46755346446eae1fa51831786b0c30d326 # Parent 0d2c447f209a5a59d842c45824173c9968bcfd76 #12718 catch overflows in f.subst() diff --git a/sage/libs/singular/groebner_strategy.pyx b/sage/libs/singular/groebner_strategy.pyx
a b 279 279 if unlikely(self._parent._ring != currRing): 280 280 rChangeCurrRing(self._parent._ring) 281 281 282 cdef int max_ind 282 cdef int max_ind = 0 283 283 cdef poly *_p = redNF(p_Copy(p._poly, self._parent._ring), max_ind, 0, self._strat) 284 284 if likely(_p!=NULL): 285 285 _p = redtailBba(_p, max_ind, self._strat) -
sage/libs/singular/polynomial.pxd
diff --git a/sage/libs/singular/polynomial.pxd b/sage/libs/singular/polynomial.pxd
a b 24 24 cdef int singular_polynomial_mul (poly **ret, poly *p, poly *q, ring *r) except -1 25 25 cdef int singular_polynomial_sub (poly **ret, poly *p, poly *q, ring *r) 26 26 cdef int singular_polynomial_div_coeff (poly **ret, poly *p, poly *q, ring *r) except -1 27 cdef int singular_polynomial_pow (poly **ret, poly *p, long exp, ring *r) except -127 cdef int singular_polynomial_pow (poly **ret, poly *p, unsigned long exp, ring *r) except -1 28 28 cdef int singular_polynomial_neg(poly **ret, poly *p, ring *r) 29 29 30 30 cdef object singular_polynomial_latex(poly *p, ring *r, object base, object latex_gens) … … 34 34 35 35 cdef inline int singular_polynomial_length_bounded(poly *p, int bound) 36 36 cdef int singular_vector_maximal_component(poly *v, ring *r) except -1 37 cdef int singular_polynomial_subst(poly **p, int var_index, poly *value, ring *r) except -1 -
sage/libs/singular/polynomial.pyx
diff --git a/sage/libs/singular/polynomial.pyx b/sage/libs/singular/polynomial.pyx
a b 26 26 from sage.libs.singular.decl cimport n_Delete, idInit, fast_map, id_Delete 27 27 from sage.libs.singular.decl cimport omAlloc0, omStrDup, omFree 28 28 from sage.libs.singular.decl cimport p_GetComp, p_SetComp 29 from sage.libs.singular.decl cimport pSubst 29 30 30 31 31 32 from sage.libs.singular.singular cimport sa2si, si2sa, overflow_check … … 288 289 n_Delete(&n, r) 289 290 return 0 290 291 291 cdef int singular_polynomial_pow(poly **ret, poly *p, long exp, ring *r) except -1:292 cdef int singular_polynomial_pow(poly **ret, poly *p, unsigned long exp, ring *r) except -1: 292 293 """ 293 294 ``ret[0] = p**exp`` where ``p`` in ``r`` and ``exp`` > 0. 294 295 … … 318 319 """ 319 320 cdef unsigned long v = p_GetMaxExp(p, r) 320 321 v = v * exp 321 322 322 overflow_check(v, r) 323 323 324 324 if(r != currRing): rChangeCurrRing(r) … … 405 405 \left(z + 1\right) v w - z w^{2} + z v + \left(-z - 1\right) w + z + 1 406 406 """ 407 407 poly = "" 408 cdef long e,j408 cdef unsigned long e,j 409 409 cdef int n = r.N 410 410 cdef int atomic_repr = base.is_atomic_repr() 411 411 while p: … … 517 517 returns the maximal module component of the vector ``v``. 518 518 INPUT: 519 519 520 521 520 - ``v`` - a polynomial/vector 521 - ``r`` - a ring 522 522 """ 523 523 cdef int res=0 524 524 while v!=NULL: 525 525 res=max(p_GetComp(v, r), res) 526 526 v = pNext(v) 527 527 return res 528 529 cdef int singular_polynomial_subst(poly **p, int var_index, poly *value, ring *r) except -1: 530 """ 531 Substitute variable ``var_index`` with ``value`` in ``p``. 532 533 INPUT: 534 535 - ``p`` - a polynomial 536 - ``var_index`` - an integer < ngens (zero based indexing) 537 - ``value`` - a polynomial 538 - ``r`` - a ring 539 """ 540 if p_IsConstant(value, r): 541 p[0] = pSubst(p[0], var_index+1, value) 542 return 0 543 544 cdef unsigned long exp = p_GetExp(p[0], var_index+1, r) * p_GetMaxExp(value, r) 545 546 overflow_check(exp, r) 547 if(r != currRing): 548 rChangeCurrRing(r) 549 550 cdef int count = singular_polynomial_length_bounded(p[0], 15) 551 if unlikely(count >= 15 or exp > 15): sig_on() 552 p[0] = pSubst(p[0], var_index+1, value) 553 if unlikely(count >= 15 or exp > 15): sig_off() 554 return 0 555 556 -
sage/libs/singular/ring.pyx
diff --git a/sage/libs/singular/ring.pyx b/sage/libs/singular/ring.pyx
a b 69 69 - ``base_ring`` - a Sage ring 70 70 71 71 - ``n`` - the number of variables (> 0) 72 72 73 73 - ``names`` - a list of names of length ``n`` 74 74 75 75 - ``term_order`` - a term ordering -
sage/libs/singular/singular.pxd
diff --git a/sage/libs/singular/singular.pxd b/sage/libs/singular/singular.pxd
a b 56 56 cdef inline int overflow_check(long e, ring *_ring) except -1 57 57 58 58 cdef init_libsingular() 59 cdef inline unsigned long get_max_exponent_size()60 59 61 60 61 -
sage/libs/singular/singular.pyx
diff --git a/sage/libs/singular/singular.pyx b/sage/libs/singular/singular.pyx
a b 573 573 raise ValueError, "cannot convert from SINGULAR number" 574 574 575 575 cdef number *sa2si(Element elem, ring * _ring): 576 cdef int i 576 cdef int i = 0 577 577 if PY_TYPE_CHECK(elem._parent, FiniteField_prime_modn): 578 578 return n_Init(int(elem),_ring) 579 579 … … 625 625 cdef long RTLD_LAZY 626 626 cdef long RTLD_GLOBAL 627 627 628 # Our attempt at avoiding exponent overflows.629 cdef unsigned int max_exponent_size630 631 628 cdef inline int overflow_check(long e, ring *_ring) except -1: 632 629 """ 633 Raises an ``OverflowError`` if e is > ``max_exponent_size``,630 Raises an ``OverflowError`` if e is > max degree per variable, 634 631 or if it is not acceptable for Singular as exponent of the 635 632 given ring. 636 633 … … 664 661 OverflowError: Exponent overflow (1073741824). # 32-bit 665 662 666 663 """ 667 if unlikely(e > min(max_exponent_size,max(_ring.N,_ring.bitmask))): 664 # 2^31 (pPower takes ints) 665 if unlikely(e >= _ring.bitmask or e >= 2**31): 668 666 raise OverflowError("Exponent overflow (%d)."%(e)) 669 667 return 0 670 668 … … 681 679 """ 682 680 global singular_options 683 681 global singular_verbose_options 684 global max_exponent_size685 682 global WerrorS_callback 686 683 global error_messages 687 684 … … 715 712 On(SW_USE_EZGCD) 716 713 Off(SW_USE_NTL_SORT) 717 714 718 if is_64_bit:719 max_exponent_size = 1<<31-1;720 else:721 max_exponent_size = 1<<16-1;722 723 715 WerrorS_callback = libsingular_error_callback 724 716 725 717 error_messages = [] 726 718 727 cdef inline unsigned long get_max_exponent_size():728 global max_exponent_size729 return max_exponent_size730 731 719 # call the init routine 732 720 init_libsingular() 733 721 -
sage/rings/polynomial/multi_polynomial_libsingular.pyx
diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
a b 176 176 p_NSet, p_GetCoeff, p_Delete, p_GetExp, pNext, rRingVar, omAlloc0, omStrDup, 177 177 omFree, pDivide, p_SetCoeff0, n_Init, p_DivisibleBy, pLcm, p_LmDivisibleBy, 178 178 pDivide, p_IsConstant, p_ExpVectorEqual, p_String, p_LmInit, n_Copy, 179 p_IsUnit, pInvers, p_Head, pSubst,idInit, fast_map, id_Delete,179 p_IsUnit, pInvers, p_Head, idInit, fast_map, id_Delete, 180 180 pIsHomogeneous, pHomogen, p_Totaldegree, singclap_pdivide, singclap_factorize, 181 181 delete, idLift, IDELEMS, On, Off, SW_USE_CHINREM_GCD, SW_USE_EZGCD, 182 182 p_LmIsConstant, pTakeOutComp1, singclap_gcd, pp_Mult_qq, p_GetMaxExp, … … 194 194 singular_polynomial_mul, singular_polynomial_div_coeff, singular_polynomial_pow, 195 195 singular_polynomial_str, singular_polynomial_latex, 196 196 singular_polynomial_str_with_changed_varnames, singular_polynomial_deg, 197 singular_polynomial_length_bounded )197 singular_polynomial_length_bounded, singular_polynomial_subst ) 198 198 199 199 # singular rings 200 200 from sage.libs.singular.ring cimport singular_ring_new, singular_ring_reference, singular_ring_delete … … 276 276 - ``n`` - number of variables (must be at least 1) 277 277 278 278 - ``names`` - names of ring variables, may be string of list/tuple 279 279 280 280 - ``order`` - term order (default: ``degrevlex``) 281 281 282 282 EXAMPLES:: … … 3142 3142 sage: f = y 3143 3143 sage: f.subs({y:x}).subs({x:z}) 3144 3144 z 3145 3146 We are catching overflows:: 3147 3148 sage: R.<x,y> = QQ[] 3149 sage: n=1000; f = x^n; f.subs(x = x^n) 3150 x^1000000 3151 3152 sage: n=100000; f = x^n; f.subs(x = x^n) 3153 Traceback (most recent call last): 3154 ... 3155 OverflowError: Exponent overflow (10000000000). 3145 3156 """ 3146 3157 cdef int mi, i, need_map, try_symbolic 3147 3158 cdef unsigned long degree = 0 3148 3159 cdef MPolynomialRing_libsingular parent = self._parent 3149 3160 cdef ring *_ring = parent._ring 3150 3161 … … 3169 3180 mi = i 3170 3181 break 3171 3182 if i > _ring.N: 3172 raise TypeError, "key does not match" 3183 id_Delete(&to_id, _ring) 3184 p_Delete(&_p, _ring) 3185 raise TypeError("key does not match") 3173 3186 else: 3174 raise TypeError, "keys do not match self's parent" 3187 id_Delete(&to_id, _ring) 3188 p_Delete(&_p, _ring) 3189 raise TypeError("keys do not match self's parent") 3175 3190 try: 3176 3191 v = parent._coerce_c(v) 3177 3192 except TypeError: … … 3179 3194 break 3180 3195 _f = (<MPolynomial_libsingular>v)._poly 3181 3196 if p_IsConstant(_f, _ring): 3182 if(_ring != currRing): rChangeCurrRing(_ring) 3183 _p = pSubst(_p, mi, _f) 3197 singular_polynomial_subst(&_p, mi-1, _f, _ring) 3184 3198 else: 3185 3199 need_map = 1 3200 degree = <unsigned long>p_GetExp(_p, mi, _ring) * <unsigned long>p_GetMaxExp(_f, _ring) 3201 if degree > _ring.bitmask: 3202 id_Delete(&to_id, _ring) 3203 p_Delete(&_p, _ring) 3204 raise OverflowError("Exponent overflow (%d)."%(degree)) 3186 3205 to_id.m[mi-1] = p_Copy(_f, _ring) 3187 3206 3188 3207 if not try_symbolic: … … 3194 3213 mi = i 3195 3214 break 3196 3215 if i > _ring.N: 3197 raise TypeError, "key does not match" 3216 id_Delete(&to_id, _ring) 3217 p_Delete(&_p, _ring) 3218 raise TypeError("key does not match") 3198 3219 try: 3199 3220 v = parent._coerce_c(v) 3200 3221 except TypeError: … … 3202 3223 break 3203 3224 _f = (<MPolynomial_libsingular>v)._poly 3204 3225 if p_IsConstant(_f, _ring): 3205 if(_ring != currRing): rChangeCurrRing(_ring) 3206 _p = pSubst(_p, mi, _f) 3226 singular_polynomial_subst(&_p, mi-1, _f, _ring) 3207 3227 else: 3208 3228 if to_id.m[mi-1] != NULL: 3209 3229 p_Delete(&to_id.m[mi-1],_ring) 3210 3230 to_id.m[mi-1] = p_Copy(_f, _ring) 3231 degree = <unsigned long>p_GetExp(_p, mi, _ring) * <unsigned long>p_GetMaxExp(_f, _ring) 3232 if degree > _ring.bitmask: 3233 id_Delete(&to_id, _ring) 3234 p_Delete(&_p, _ring) 3235 raise OverflowError("Exponent overflow (%d)."%(degree)) 3211 3236 need_map = 1 3212 3237 3213 3238 if need_map: -
sage/rings/polynomial/polynomial_ring_constructor.py
diff --git a/sage/rings/polynomial/polynomial_ring_constructor.py b/sage/rings/polynomial/polynomial_ring_constructor.py
a b 16 16 17 17 ################################################################# 18 18 # 19 # Sage: System for Algebra and Geometry Experimentation 19 # Sage: System for Algebra and Geometry Experimentation 20 20 # 21 21 # Copyright (C) 2006 William Stein <wstein@gmail.com> 22 22 # … … 82 82 - ``sparse`` -- bool (default: False), whether or not elements are sparse 83 83 - ``order`` -- string or 84 84 :class:`~sage.rings.polynomial.term_order.TermOrder` object, e.g., 85 85 86 86 - ``'degrevlex'`` (default) -- degree reverse lexicographic 87 87 - ``'lex'`` -- lexicographic 88 88 - ``'deglex'`` -- degree lexicographic … … 102 102 the argument ``sparse=False`` is silently ignored in that case. 103 103 - If the given implementation does not exist for rings with the given number 104 104 of generators and the given sparsity, then an error results. 105 105 106 106 OUTPUT: 107 107 108 108 ``PolynomialRing(base_ring, name, sparse=False)`` returns a univariate 109 109 polynomial ring; also, PolynomialRing(base_ring, names, sparse=False) 110 yields a univariate polynomial ring, if names is a list or tuple 111 providing exactly one name. All other input formats return a 112 multivariate polynomial ring. 110 yields a univariate polynomial ring, if names is a list or tuple 111 providing exactly one name. All other input formats return a 112 multivariate polynomial ring. 113 113 114 114 UNIQUENESS and IMMUTABILITY: In Sage there is exactly one 115 115 single-variate polynomial ring over each base ring in each choice … … 139 139 140 140 sage: with localvars(R, ['z','w']): 141 141 ... print f 142 ... 142 ... 143 143 z^2 - 2*w^2 144 144 145 145 After the ``with`` block the names revert to what they were before. … … 147 147 148 148 sage: print f 149 149 x^2 - 2*y^2 150 150 151 151 152 152 SQUARE BRACKETS NOTATION: You can alternatively create a single or 153 153 multivariate polynomial ring over a ring `R` by writing ``R['varname']`` or 154 154 ``R['var1,var2,var3,...']``. This square brackets notation doesn't allow 155 for setting any of the optional arguments. 155 for setting any of the optional arguments. 156 156 157 157 EXAMPLES: 158 158 159 159 1. ``PolynomialRing(base_ring, name, sparse=False)`` 160 160 161 161 :: 162 162 163 163 sage: PolynomialRing(QQ, 'w') … … 169 169 sage: R.<w> = PolynomialRing(QQ) 170 170 sage: (1 + w)^3 171 171 w^3 + 3*w^2 + 3*w + 1 172 172 173 173 You must specify a name:: 174 174 175 175 sage: PolynomialRing(QQ) … … 207 207 208 208 sage: QQ['x'] == QQ['y'] 209 209 False 210 210 211 211 Sage has two implementations of univariate polynomials over the 212 212 integers, one based on NTL and one based on FLINT. The default 213 213 is FLINT. Note that FLINT uses a "more dense" representation for … … 272 272 sage: R == S 273 273 False 274 274 275 Note that a univariate polynomial ring is returned, if the list 276 of names is of length one. If it is of length zero, a multivariate 275 Note that a univariate polynomial ring is returned, if the list 276 of names is of length one. If it is of length zero, a multivariate 277 277 polynomial ring with no variables is returned. 278 278 279 279 :: 280 280 281 281 sage: PolynomialRing(QQ,["x"]) 282 282 Univariate Polynomial Ring in x over Rational Field 283 283 sage: PolynomialRing(QQ,[]) … … 292 292 293 293 sage: PolynomialRing(QQ, 'x', 10) 294 294 Multivariate Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field 295 295 296 296 sage: PolynomialRing(GF(7), 'y', 5) 297 297 Multivariate Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7 298 298 … … 303 303 explicit number is given. 304 304 305 305 :: 306 306 307 307 sage: PolynomialRing(QQ,"x",1) 308 308 Multivariate Polynomial Ring in x over Rational Field 309 309 sage: PolynomialRing(QQ,"x",0) … … 321 321 method, all those variable names are available for interactive use:: 322 322 323 323 sage: R.inject_variables() 324 Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 324 Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 325 325 sage: (x2 + x41 + x71)^2 326 326 x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2 327 327 … … 409 409 n = len(names) 410 410 R = _multi_variate(base_ring, names, n, sparse, order, implementation) 411 411 elif isinstance(arg1, (list, tuple)): 412 # PolynomialRing(base_ring, names (list or tuple), order='degrevlex'): 412 # PolynomialRing(base_ring, names (list or tuple), order='degrevlex'): 413 413 names = arg1 414 414 n = len(names) 415 R = _multi_variate(base_ring, names, n, sparse, order, implementation) 415 R = _multi_variate(base_ring, names, n, sparse, order, implementation) 416 416 417 417 if arg1 is None and arg2 is None: 418 418 raise TypeError, "you *must* specify the indeterminates (as not None)." … … 487 487 else: 488 488 R = m.PolynomialRing_commutative(base_ring, name, sparse) 489 489 else: 490 R = m.PolynomialRing_general(base_ring, name, sparse) 490 R = m.PolynomialRing_general(base_ring, name, sparse) 491 491 492 492 if hasattr(R, '_implementation_names'): 493 493 for name in R._implementation_names: