Ticket #12718: trac_12718_singular_overflow.patch

File trac_12718_singular_overflow.patch, 17.2 KB (added by malb, 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  
    279279        if unlikely(self._parent._ring != currRing):
    280280            rChangeCurrRing(self._parent._ring)
    281281
    282         cdef int max_ind
     282        cdef int max_ind = 0
    283283        cdef poly *_p = redNF(p_Copy(p._poly, self._parent._ring), max_ind, 0, self._strat)
    284284        if likely(_p!=NULL):
    285285            _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  
    2424cdef int singular_polynomial_mul (poly **ret, poly *p, poly *q, ring *r) except -1
    2525cdef int singular_polynomial_sub (poly **ret, poly *p, poly *q, ring *r)
    2626cdef 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 -1
     27cdef int singular_polynomial_pow (poly **ret, poly *p, unsigned long exp, ring *r) except -1
    2828cdef int singular_polynomial_neg(poly **ret, poly *p, ring *r)
    2929
    3030cdef object singular_polynomial_latex(poly *p, ring *r, object base, object latex_gens)
     
    3434
    3535cdef inline int singular_polynomial_length_bounded(poly *p, int bound)
    3636cdef int singular_vector_maximal_component(poly *v, ring *r) except -1
     37cdef 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  
    2626from sage.libs.singular.decl cimport n_Delete, idInit, fast_map, id_Delete
    2727from sage.libs.singular.decl cimport omAlloc0, omStrDup, omFree
    2828from sage.libs.singular.decl cimport p_GetComp, p_SetComp
     29from sage.libs.singular.decl cimport pSubst
    2930
    3031
    3132from sage.libs.singular.singular cimport sa2si, si2sa, overflow_check
     
    288289    n_Delete(&n, r)
    289290    return 0
    290291   
    291 cdef int singular_polynomial_pow(poly **ret, poly *p, long exp, ring *r) except -1:
     292cdef int singular_polynomial_pow(poly **ret, poly *p, unsigned long exp, ring *r) except -1:
    292293    """
    293294    ``ret[0] = p**exp`` where ``p`` in ``r`` and ``exp`` > 0.
    294295
     
    318319    """
    319320    cdef unsigned long v = p_GetMaxExp(p, r)
    320321    v = v * exp
    321 
    322322    overflow_check(v, r)
    323323
    324324    if(r != currRing): rChangeCurrRing(r)
     
    405405        \left(z + 1\right) v w - z w^{2} + z v + \left(-z - 1\right) w + z + 1
    406406    """
    407407    poly = ""
    408     cdef long e,j
     408    cdef unsigned long e,j
    409409    cdef int n = r.N
    410410    cdef int atomic_repr = base.is_atomic_repr()
    411411    while p:
     
    517517    returns the maximal module component of the vector ``v``.
    518518    INPUT:
    519519
    520        - ``v`` - a polynomial/vector
    521        - ``r`` - a ring
     520    - ``v`` - a polynomial/vector
     521    - ``r`` - a ring
    522522    """
    523523    cdef int res=0
    524524    while v!=NULL:
    525525        res=max(p_GetComp(v, r), res)
    526526        v = pNext(v)
    527527    return res
     528
     529cdef 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  
    6969    - ``base_ring`` - a Sage ring
    7070
    7171    - ``n`` - the number of variables (> 0)
    72    
     72
    7373    - ``names`` - a list of names of length ``n``
    7474
    7575    - ``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  
    5656cdef inline int overflow_check(long e, ring *_ring) except -1
    5757
    5858cdef init_libsingular()
    59 cdef inline unsigned long get_max_exponent_size()
    6059
    6160
     61
  • sage/libs/singular/singular.pyx

    diff --git a/sage/libs/singular/singular.pyx b/sage/libs/singular/singular.pyx
    a b  
    573573        raise ValueError, "cannot convert from SINGULAR number"
    574574
    575575cdef number *sa2si(Element elem, ring * _ring):
    576     cdef int i
     576    cdef int i = 0
    577577    if PY_TYPE_CHECK(elem._parent, FiniteField_prime_modn):
    578578        return n_Init(int(elem),_ring)
    579579
     
    625625    cdef long RTLD_LAZY
    626626    cdef long RTLD_GLOBAL
    627627
    628 # Our attempt at avoiding exponent overflows.
    629 cdef unsigned int max_exponent_size
    630 
    631628cdef inline int overflow_check(long e, ring *_ring) except -1:
    632629    """
    633     Raises an ``OverflowError`` if e is > ``max_exponent_size``,
     630    Raises an ``OverflowError`` if e is > max degree per variable,
    634631    or if it is not acceptable for Singular as exponent of the
    635632    given ring.
    636633
     
    664661        OverflowError: Exponent overflow (1073741824). # 32-bit
    665662
    666663    """
    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):
    668666        raise OverflowError("Exponent overflow (%d)."%(e))
    669667    return 0
    670668
     
    681679    """
    682680    global singular_options
    683681    global singular_verbose_options
    684     global max_exponent_size
    685682    global WerrorS_callback
    686683    global error_messages
    687684
     
    715712    On(SW_USE_EZGCD)
    716713    Off(SW_USE_NTL_SORT)
    717714
    718     if is_64_bit:
    719         max_exponent_size = 1<<31-1;
    720     else:
    721         max_exponent_size = 1<<16-1;
    722 
    723715    WerrorS_callback = libsingular_error_callback
    724716
    725717    error_messages = []
    726718
    727 cdef inline unsigned long get_max_exponent_size():
    728     global max_exponent_size
    729     return max_exponent_size
    730 
    731719# call the init routine
    732720init_libsingular()
    733721
  • 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  
    176176    p_NSet, p_GetCoeff, p_Delete, p_GetExp, pNext, rRingVar, omAlloc0, omStrDup,
    177177    omFree, pDivide, p_SetCoeff0, n_Init, p_DivisibleBy, pLcm, p_LmDivisibleBy,
    178178    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,
    180180    pIsHomogeneous, pHomogen, p_Totaldegree, singclap_pdivide, singclap_factorize,
    181181    delete, idLift, IDELEMS, On, Off, SW_USE_CHINREM_GCD, SW_USE_EZGCD,
    182182    p_LmIsConstant, pTakeOutComp1, singclap_gcd, pp_Mult_qq, p_GetMaxExp,
     
    194194    singular_polynomial_mul, singular_polynomial_div_coeff, singular_polynomial_pow,
    195195    singular_polynomial_str, singular_polynomial_latex,
    196196    singular_polynomial_str_with_changed_varnames, singular_polynomial_deg,
    197     singular_polynomial_length_bounded )
     197    singular_polynomial_length_bounded, singular_polynomial_subst )
    198198
    199199# singular rings
    200200from sage.libs.singular.ring cimport singular_ring_new, singular_ring_reference, singular_ring_delete
     
    276276        - ``n`` - number of variables (must be at least 1)
    277277
    278278        - ``names`` - names of ring variables, may be string of list/tuple
    279        
     279
    280280        - ``order`` - term order (default: ``degrevlex``)
    281281
    282282        EXAMPLES::
     
    31423142            sage: f = y
    31433143            sage: f.subs({y:x}).subs({x:z})
    31443144            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).
    31453156        """
    31463157        cdef int mi, i, need_map, try_symbolic
    3147        
     3158        cdef unsigned long degree = 0
    31483159        cdef MPolynomialRing_libsingular parent = self._parent
    31493160        cdef ring *_ring = parent._ring
    31503161
     
    31693180                            mi = i
    31703181                            break
    31713182                    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")
    31733186                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")
    31753190                try:
    31763191                    v = parent._coerce_c(v)
    31773192                except TypeError:
     
    31793194                    break
    31803195                _f = (<MPolynomial_libsingular>v)._poly
    31813196                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)
    31843198                else:
    31853199                    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))
    31863205                    to_id.m[mi-1] = p_Copy(_f, _ring)
    31873206
    31883207        if not try_symbolic:
     
    31943213                        mi = i
    31953214                        break
    31963215                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")
    31983219                try:
    31993220                    v = parent._coerce_c(v)
    32003221                except TypeError:
     
    32023223                    break
    32033224                _f = (<MPolynomial_libsingular>v)._poly
    32043225                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)
    32073227                else:
    32083228                    if to_id.m[mi-1] != NULL:
    32093229                        p_Delete(&to_id.m[mi-1],_ring)
    32103230                    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))
    32113236                    need_map = 1
    32123237
    32133238            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  
    1616
    1717#################################################################
    1818#
    19 #   Sage: System for Algebra and Geometry Experimentation   
     19#   Sage: System for Algebra and Geometry Experimentation
    2020#
    2121#       Copyright (C) 2006 William Stein <wstein@gmail.com>
    2222#
     
    8282    - ``sparse`` -- bool (default: False), whether or not elements are sparse
    8383    - ``order`` -- string or
    8484      :class:`~sage.rings.polynomial.term_order.TermOrder` object, e.g.,
    85        
     85
    8686      - ``'degrevlex'`` (default) -- degree reverse lexicographic
    8787      - ``'lex'``  -- lexicographic
    8888      - ``'deglex'`` -- degree lexicographic
     
    102102      the argument ``sparse=False`` is silently ignored in that case.
    103103    - If the given implementation does not exist for rings with the given number
    104104      of generators and the given sparsity, then an error results.
    105                  
     105
    106106    OUTPUT:
    107107
    108108    ``PolynomialRing(base_ring, name, sparse=False)`` returns a univariate
    109109    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.
    113113
    114114    UNIQUENESS and IMMUTABILITY: In Sage there is exactly one
    115115    single-variate polynomial ring over each base ring in each choice
     
    139139
    140140            sage: with localvars(R, ['z','w']):
    141141            ...     print f
    142             ...     
     142            ...
    143143            z^2 - 2*w^2
    144144
    145145        After the ``with`` block the names revert to what they were before.
     
    147147
    148148            sage: print f
    149149            x^2 - 2*y^2
    150            
     150
    151151
    152152    SQUARE BRACKETS NOTATION: You can alternatively create a single or
    153153    multivariate polynomial ring over a ring `R` by writing ``R['varname']`` or
    154154    ``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.
    156156
    157157    EXAMPLES:
    158158
    159159    1. ``PolynomialRing(base_ring, name,    sparse=False)``
    160    
     160
    161161       ::
    162162
    163163        sage: PolynomialRing(QQ, 'w')
     
    169169        sage: R.<w> = PolynomialRing(QQ)
    170170        sage: (1 + w)^3
    171171        w^3 + 3*w^2 + 3*w + 1
    172        
     172
    173173       You must specify a name::
    174174
    175175        sage: PolynomialRing(QQ)
     
    207207
    208208        sage: QQ['x'] == QQ['y']
    209209        False
    210        
     210
    211211       Sage has two implementations of univariate polynomials over the
    212212       integers, one based on NTL and one based on FLINT.  The default
    213213       is FLINT. Note that FLINT uses a "more dense" representation for
     
    272272        sage: R == S
    273273        False
    274274
    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
    277277       polynomial ring with no variables is returned.
    278278
    279279       ::
    280        
     280
    281281        sage: PolynomialRing(QQ,["x"])
    282282        Univariate Polynomial Ring in x over Rational Field
    283283        sage: PolynomialRing(QQ,[])
     
    292292
    293293        sage: PolynomialRing(QQ, 'x', 10)
    294294        Multivariate Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field
    295        
     295
    296296        sage: PolynomialRing(GF(7), 'y', 5)
    297297        Multivariate Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7
    298298
     
    303303       explicit number is given.
    304304
    305305       ::
    306    
     306
    307307        sage: PolynomialRing(QQ,"x",1)
    308308        Multivariate Polynomial Ring in x over Rational Field
    309309        sage: PolynomialRing(QQ,"x",0)
     
    321321       method, all those variable names are available for interactive use::
    322322
    323323        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
    325325        sage: (x2 + x41 + x71)^2
    326326        x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2
    327327
     
    409409            n = len(names)
    410410            R = _multi_variate(base_ring, names, n, sparse, order, implementation)
    411411    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'):
    413413            names = arg1
    414414            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)
    416416
    417417    if arg1 is None and arg2 is None:
    418418        raise TypeError, "you *must* specify the indeterminates (as not None)."
     
    487487        else:
    488488            R = m.PolynomialRing_commutative(base_ring, name, sparse)
    489489    else:
    490         R = m.PolynomialRing_general(base_ring, name, sparse)       
     490        R = m.PolynomialRing_general(base_ring, name, sparse)
    491491
    492492    if hasattr(R, '_implementation_names'):
    493493        for name in R._implementation_names: