Changeset 7467:16f7b7ad64c3


Ignore:
Timestamp:
12/01/07 09:09:29 (5 years ago)
Author:
dmharvey@…
Branch:
default
Message:

fixed #1211 (NTL crash in polynomial remainder over ZZ)

Location:
sage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sage/libs/ntl/decl.pxi

    r7264 r7467  
    174174    ZZX_c* ZZX_construct "Construct<ZZX>"(void *mem) 
    175175    void ZZX_destruct "Destruct<ZZX>"(ZZX_c *mem) 
     176    void ZZX_swap "swap"(ZZX_c x, ZZX_c y) 
    176177    void ZZX_delete "Delete<ZZX>"(ZZX_c *mem) 
    177178    void ZZX_from_str "_from_str<ZZX>"(ZZX_c* dest, char* s) 
  • sage/rings/polynomial/polynomial_integer_dense_ntl.pyx

    r7284 r7467  
    317317    def quo_rem(self, right): 
    318318        r""" 
    319         Returns a tuple (quotient, remainder) where 
    320             self = quotient*other + remainder. 
    321  
    322         If the quotient and remainder are not integral, 
    323         an exception is raised. 
    324  
     319        Attempts to divide self by right, and return a quotient and remainder. 
     320 
     321        If right is monic, then it returns (q, r) where 
     322            self = q * right + r 
     323        and deg(r) < deg(right). 
     324 
     325        If right is not monic, then it returns (q, 0) where q = self/right 
     326        if right exactly divides self, otherwise it raises an exception. 
     327         
    325328        EXAMPLES: 
    326329            sage: R.<x> = PolynomialRing(ZZ) 
     
    331334            sage: q*g + r == f 
    332335            True 
     336 
     337            sage: f = x^2 
     338            sage: f.quo_rem(0) 
     339            Traceback (most recent call last): 
     340            ... 
     341            ArithmeticError: division by zero polynomial 
     342 
     343            sage: f = (x^2 + 3) * (2*x - 1) 
     344            sage: f.quo_rem(2*x - 1) 
     345            (x^2 + 3, 0) 
     346 
     347            sage: f = x^2 
     348            sage: f.quo_rem(2*x - 1) 
     349            Traceback (most recent call last): 
     350            ... 
     351            ArithmeticError: division not exact in Z[x] (consider coercing to Q[x] first) 
     352             
    333353        """ 
    334354        if not isinstance(right, Polynomial_integer_dense_ntl): 
     
    337357            raise TypeError 
    338358 
    339         # ugggh this isn't pretty. Lots of unnecessary copies. 
    340         cdef ZZX_c *r, *q 
    341         ZZX_quo_rem(&self.__poly, &(<Polynomial_integer_dense_ntl>right).__poly, &r, &q) 
     359        cdef Polynomial_integer_dense_ntl _right = <Polynomial_integer_dense_ntl> right 
     360 
     361        if ZZX_IsZero(_right.__poly): 
     362            raise ArithmeticError, "division by zero polynomial" 
     363 
     364        cdef ZZX_c *q, *r 
     365        cdef Polynomial_integer_dense_ntl qq = self._new() 
    342366        cdef Polynomial_integer_dense_ntl rr = self._new() 
    343         cdef Polynomial_integer_dense_ntl qq = self._new() 
    344         rr.__poly = r[0] 
    345         qq.__poly = q[0] 
    346         ZZX_delete(&r[0]) 
    347         ZZX_delete(&q[0]) 
    348         return (qq, rr) 
     367        cdef int divisible 
     368 
     369        if ZZ_IsOne(ZZX_LeadCoeff(_right.__poly)): 
     370            # divisor is monic. Just do the division and remainder 
     371            ZZX_quo_rem(&self.__poly, &_right.__poly, &r, &q) 
     372            ZZX_swap(qq.__poly, q[0]) 
     373            ZZX_swap(rr.__poly, r[0]) 
     374            ZZX_delete(q) 
     375            ZZX_delete(r) 
     376        else: 
     377            # Non-monic divisor. Check whether it divides exactly. 
     378            q = ZZX_div(&self.__poly, &_right.__poly, &divisible) 
     379            if divisible: 
     380                # exactly divisible 
     381                ZZX_swap(q[0], qq.__poly) 
     382                ZZX_delete(q) 
     383            else: 
     384                # division failed: clean up and raise exception 
     385                ZZX_delete(q) 
     386                raise ArithmeticError, "division not exact in Z[x] (consider coercing to Q[x] first)" 
     387             
     388        return qq, rr 
     389 
    349390 
    350391         
Note: See TracChangeset for help on using the changeset viewer.