Ticket #468: 5834.patch

File 5834.patch, 19.7 KB (added by bober, 15 years ago)

This patch should fix this issue.

  • sage/rings/real_rqdf.pxd

    # HG changeset patch
    # User Jonathan Bober <bober@umich.edu>
    # Date 1187892208 14400
    # Node ID 76e3ea40f96aff4022ef96f9ea323fe07f43e3d5
    # Parent  752e1d1cba0d9a3c9e856f5b3eb071395fbf37c6
    Fixes for the quaddouble wrapper so that it always properly resets
    the fpu precision (on x86 machines).
    
    diff -r 752e1d1cba0d -r 76e3ea40f96a sage/rings/real_rqdf.pxd
    a b cdef class RealQuadDoubleField_class(Fie 
    112112    # so it is possible to make weakrefs to this finite field     
    113113    cdef object __weakref__
    114114    # round-to-double bit
    115     cdef unsigned int *cwf
    116115   
    117116cdef class QuadDoubleElement(FieldElement):
    118117    cdef qd *initptr #
    119118    # round-to-double bit
    120     cdef unsigned int *cw
    121119   
    122120    cdef _set(self,x)
    123121    cdef _new(self)
  • sage/rings/real_rqdf.pyx

    diff -r 752e1d1cba0d -r 76e3ea40f96a sage/rings/real_rqdf.pyx
    a b Mixing of symbolic an quad double elemen 
    3333    0.868588963806503655302257837833210164588794011607333132228907565
    3434   
    3535"""
     36
    3637
    3738#*****************************************************************************
    3839#
    from sage.rings.real_mpfr cimport RealNu 
    8485
    8586from sage.structure.parent_base cimport ParentWithBase
    8687from sage.structure.parent_gens cimport ParentWithGens
    87 
    88 cdef extern from "rqdf_fix.h": pass
    8988
    9089cdef qd *qd_from_mpz(mpz_t z):
    9190    cdef double d[4]
    cdef class RealQuadDoubleField_class(Fie 
    148147    """
    149148
    150149    def __init__(self):
    151         fpu_fix_start(self.cwf)       
    152 
     150        pass
     151   
    153152    def __dealloc__(self):
    154         fpu_fix_end(self.cwf)
    155        
     153        pass
     154
    156155    def is_exact(self):
    157156        return False
    158157
    cdef class RealQuadDoubleField_class(Fie 
    315314       
    316315        s = <char*>PyMem_Malloc(63+8) # See docs for write()
    317316        _sig_on
     317        cdef unsigned int cw
     318        fpu_fix_start(&cw)
    318319        z._pi.write(s,63,0,0)
     320        fpu_fix_end(&cw)
    319321        _sig_off
    320322        t = str(s)
    321323        PyMem_Free(s)
    cdef class RealQuadDoubleField_class(Fie 
    331333        """
    332334        cdef qd z
    333335        cdef char *s
     336        cdef unsigned int cw
     337        fpu_fix_start(&cw)
    334338        s = <char*>PyMem_Malloc(63+8) # See docs for write()
    335339        _sig_on
    336340        z._log2.write(s,63,0,0)
    337341        _sig_off
    338342        t = str(s)
    339343        PyMem_Free(s)
     344        fpu_fix_end(&cw)
    340345        return QuadDoubleElement(t)
    341346
    342347    def e(self):
    cdef class RealQuadDoubleField_class(Fie 
    349354        """
    350355        cdef qd z
    351356        cdef char *s
    352        
     357        cdef unsigned int cw
     358        fpu_fix_start(&cw)
    353359        s = <char*>PyMem_Malloc(63+8) # See docs for write()
    354360        _sig_on
    355361        z._e.write(s,63,0,0)
    cdef class RealQuadDoubleField_class(Fie 
    357363        t = str(s)
    358364
    359365        PyMem_Free(s)
     366        fpu_fix_end(&cw)
    360367        return QuadDoubleElement(t)
    361368
    362369    def NaN(self):
    cdef class QuadDoubleElement(FieldElemen 
    405412    cdef _new(self):
    406413        cdef QuadDoubleElement q
    407414        q = PY_NEW(QuadDoubleElement)
    408         fpu_fix_start(self.cw)
    409415        q.initptr = new_qd_real()
    410416        return q
    411417
    412418    cdef _new_c(self, qd a):
    413419        cdef QuadDoubleElement q
    414420        q = PY_NEW(QuadDoubleElement)
    415         fpu_fix_start(self.cw)
    416421        q.initptr =  qd_from_qd(a.x[0],a.x[1],a.x[2],a.x[3])
    417422        return q
    418423
    419424    def __dealloc__(self):
    420         fpu_fix_end(self.cw)
     425        cdef unsigned int cw
     426        fpu_fix_start(&cw)
    421427        delete(self.initptr)
     428        fpu_fix_end(&cw)
     429        pass
    422430       
    423431    def __new__(self, x=None):
    424432        # explicit cast required for C++
    cdef class QuadDoubleElement(FieldElemen 
    456464            sage: RQDF(RR('1091.34342'))
    457465            1091.343420000000000000000000000000000000000000000000000000000000
    458466        """
    459         fpu_fix_start(self.cw)
    460467        self._set(x)
    461                 
     468               
    462469    cdef _set(self, x):
     470        cdef unsigned int cw
     471        fpu_fix_start(&cw)
    463472        cdef qd *n,*d
    464473               
    465474        if PY_TYPE_CHECK(x, RealNumber):
    cdef class QuadDoubleElement(FieldElemen 
    497506            _sig_off
    498507           
    499508        else:
     509            fpu_fix_end(&cw)
    500510            raise TypeError, "Cannot coerce %s (parent %s) into a quad double" % (x, x.parent())
     511        fpu_fix_end(&cw)
    501512
    502513    def get_doubles(self):
    503514        """
    cdef class QuadDoubleElement(FieldElemen 
    648659            if x < 0: return "-inf"
    649660            return "inf"
    650661        if self.is_NaN(): return "NaN"
    651 
    652         if 0.0 == x: return self.__str_no_scientific()
    653         if 1e-12 < x and x < 1e12:
    654             return self.__str_no_scientific()
    655         if -1e-12 > x and x > -1e12:
    656             return self.__str_no_scientific()
    657         return self.__str_scientific()
     662        cdef unsigned int cw
     663        fpu_fix_start(&cw)
     664        if 0.0 == x:
     665            result = self.__str_no_scientific()
     666        elif 1e-12 < x and x < 1e12:
     667            result = self.__str_no_scientific()
     668        elif -1e-12 > x and x > -1e12:
     669            result =  self.__str_no_scientific()
     670        else:
     671            result = self.__str_scientific()
     672        fpu_fix_end(&cw)
     673        return result
    658674       
    659675    def parent(self):
    660676        """
    cdef class QuadDoubleElement(FieldElemen 
    687703             
    688704        """
    689705        if 0 == self: return Integer("0")
    690                
     706        cdef unsigned int cw
     707        fpu_fix_start(&cw)
    691708        s = self.__str_no_scientific()
    692709        num = s.split('.')[0]
    693         return Integer(num)
     710        result = Integer(num)
     711        fpu_fix_end(&cw)
     712        return result
    694713       
    695714    ########################
    696715    #   Basic Arithmetic
    cdef class QuadDoubleElement(FieldElemen 
    705724            3.000000000000000000000000000000000000000000000000000000000000000
    706725        """
    707726        cdef QuadDoubleElement res
    708         res = self._new()
     727        cdef unsigned int cw
     728        fpu_fix_start(&cw)
     729        res = self._new()
    709730        _sig_on
    710731        c_qd_npwr(self.initptr.x,-1,res.initptr.x)
     732        fpu_fix_end(&cw)
    711733        _sig_off
    712734        return res
    713735   
    cdef class QuadDoubleElement(FieldElemen 
    719741            sage: RQDF(1/3) + RQDF(1)
    720742            1.333333333333333333333333333333333333333333333333333333333333333
    721743        """
    722        
    723         cdef QuadDoubleElement res
     744        cdef QuadDoubleElement res
     745        cdef unsigned int cw
     746        fpu_fix_start(&cw)
    724747        res = self._new()
    725748        c_qd_add(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x)
     749        fpu_fix_end(&cw)
    726750        return res
    727751       
    728752    cdef ModuleElement _sub_c_impl(self, ModuleElement right):
    cdef class QuadDoubleElement(FieldElemen 
    734758            -0.666666666666666666666666666666666666666666666666666666666666666
    735759        """
    736760        cdef QuadDoubleElement res
     761        cdef unsigned int cw
     762        fpu_fix_start(&cw)
    737763        res = self._new()
    738764        c_qd_sub(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x)
     765        fpu_fix_end(&cw)
    739766        return res
    740767           
    741768    cdef RingElement _mul_c_impl(self, RingElement right):
    cdef class QuadDoubleElement(FieldElemen 
    747774            13.00000000000000000000000000000000000000000000000000000000000000
    748775        """
    749776        cdef QuadDoubleElement res
     777        cdef unsigned int cw
     778        fpu_fix_start(&cw)
    750779        res = self._new()
    751780        c_qd_mul(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x)
     781        fpu_fix_end(&cw)
    752782        return res
    753783                 
    754784    cdef RingElement _div_c_impl(self, RingElement right):
    cdef class QuadDoubleElement(FieldElemen 
    760790            0.00333333333333333333333333333333333333333333333333333333333333333
    761791        """
    762792        cdef QuadDoubleElement res
     793        cdef unsigned int cw
     794        fpu_fix_start(&cw)
    763795        res = self._new()
    764796        c_qd_div(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x)
     797        fpu_fix_end(&cw)
    765798        return res
    766799       
    767800    cdef ModuleElement _neg_c_impl(self):
    cdef class QuadDoubleElement(FieldElemen 
    773806            -0.0560000000000000000000000000000000000000000000000000000000000000
    774807        """
    775808        cdef QuadDoubleElement res
     809        cdef unsigned int cw
     810        fpu_fix_start(&cw)          # This might not be needed here.
    776811        res = self._new()
    777812        c_qd_neg(self.initptr.x,res.initptr.x)
     813        fpu_fix_end(&cw)
    778814        return res
    779815       
    780816    def __abs__(self):
    781817        """
    782         Negates a quad double number.
     818        Returns the absolute value of a quad double number.
    783819       
    784820        EXAMPLES:
    785821            sage: abs(RQDF('-0.45'))
    786822            0.450000000000000000000000000000000000000000000000000000000000000
    787823        """
    788824        cdef QuadDoubleElement res
     825        cdef unsigned int cw
     826        fpu_fix_start(&cw)
    789827        res = self._new()
    790828        c_qd_abs(self.initptr.x,res.initptr.x)
     829        fpu_fix_end(&cw)
    791830        return res
    792831   
    793832    def __lshift__(self, n):
    cdef class QuadDoubleElement(FieldElemen 
    838877            1.000000000000000000000000000000000000000000000000000000000000000
    839878        """
    840879        cdef QuadDoubleElement res
     880        cdef unsigned int cw
     881        fpu_fix_start(&cw)
    841882        res = self._new()
    842883        if self.frac() < 0.5:
    843884            _sig_on
    844885            c_qd_floor(self.initptr.x,res.initptr.x)
     886            fpu_fix_end(&cw)
    845887            _sig_off
    846888            return res
    847889           
    848890        _sig_on
    849891        c_qd_ceil(self.initptr.x,res.initptr.x)
     892        fpu_fix_end(&cw)
    850893        _sig_off
    851894        return res
    852895       
    cdef class QuadDoubleElement(FieldElemen 
    864907            -3
    865908        """
    866909        cdef QuadDoubleElement res
     910        cdef unsigned int cw
     911        fpu_fix_start(&cw)
    867912        res = self._new()
    868913        c_qd_floor(self.initptr.x,res.initptr.x)
     914        fpu_fix_end(&cw)
    869915        return res.integer_part()
    870916
    871917    def ceil(self):
    cdef class QuadDoubleElement(FieldElemen 
    883929            <type 'sage.rings.integer.Integer'>
    884930        """
    885931        cdef QuadDoubleElement res
     932        cdef unsigned int cw
     933        fpu_fix_start(&cw)
    886934        res = self._new()
    887935        c_qd_ceil(self.initptr.x,res.initptr.x)
     936        fpu_fix_end(&cw)
    888937        return res.integer_part()
    889938
    890939    def ceiling(self):
    cdef class QuadDoubleElement(FieldElemen 
    942991            -23.789999999999999
    943992        """
    944993        cdef double d
     994        cdef unsigned int cw
     995        fpu_fix_start(&cw)
    945996        d = qd_to_double(qd_deref(self.initptr))
     997        fpu_fix_end(&cw)
    946998        return d
    947999   
    9481000    def __int__(self):
    cdef class QuadDoubleElement(FieldElemen 
    9561008            -23
    9571009        """
    9581010        cdef int i
     1011        cdef unsigned int cw
     1012        fpu_fix_start(&cw)
    9591013        i = qd_to_int(qd_deref(self.initptr))
     1014        fpu_fix_end(&cw)
    9601015        return i
    9611016
    9621017    def __long__(self):
    cdef class QuadDoubleElement(FieldElemen 
    12101265            NaN
    12111266        """
    12121267        cdef QuadDoubleElement res
     1268        cdef unsigned int cw
     1269        fpu_fix_start(&cw)
    12131270        res = self._new()
    12141271        if self.initptr.x[0] > 0:
    12151272            c_qd_sqrt(self.initptr.x, res.initptr.x)
     1273            fpu_fix_end(&cw)
    12161274            return res
    12171275        else:
    12181276            res = self._new_c(self.initptr._nan)
     1277            fpu_fix_end(&cw)
    12191278            return res
    12201279       
    12211280    def cube_root(self):
    cdef class QuadDoubleElement(FieldElemen 
    12341293    def nth_root(self, int n):
    12351294        """
    12361295        Returns the $n^{th}$ root of self.
    1237         Returns NaN if self is negative
     1296        Returns NaN if self is negative and $n$ is even.
    12381297
    12391298        EXAMPLES:
    12401299            sage: r = RQDF(125.0); r.nth_root(3)
    cdef class QuadDoubleElement(FieldElemen 
    12471306       
    12481307        cdef QuadDoubleElement res
    12491308        cdef double neg[4]
     1309        cdef unsigned int cw
     1310        fpu_fix_start(&cw)
    12501311        res = self._new()
    12511312        _sig_on
    12521313        if self.initptr.is_negative() and n % 2 == 1:
    cdef class QuadDoubleElement(FieldElemen 
    12551316            c_qd_neg(res.initptr.x, res.initptr.x)
    12561317        else:
    12571318            c_qd_nroot(self.initptr.x, n, res.initptr.x)
     1319        fpu_fix_end(&cw)
    12581320        _sig_off
    12591321        return res
    12601322   
    12611323    def __pow(self, n, modulus):
    12621324        cdef QuadDoubleElement res, n2
     1325        cdef unsigned int cw
     1326        fpu_fix_start(&cw)
    12631327        res = self._new()
    12641328        _sig_on
    12651329        c_qd_npwr(self.initptr.x, n, res.initptr.x)
     1330        fpu_fix_end(&cw)
    12661331        _sig_off
    12671332        return res
    12681333
    cdef class QuadDoubleElement(FieldElemen 
    12791344        """
    12801345        if not isinstance(n,(Integer, int)):
    12811346            res = n * self.log()
    1282             return res.exp()
    1283         return self.__pow(n,d)
     1347            res = res.exp()
     1348        else:
     1349            res = self.__pow(n,d)
     1350        return res
    12841351       
    12851352    def log(self):
    12861353        """
    cdef class QuadDoubleElement(FieldElemen 
    12971364            NaN
    12981365        """
    12991366        cdef QuadDoubleElement res
     1367        cdef unsigned int cw
     1368        fpu_fix_start(&cw)
    13001369        if self.initptr.x[0] < 0.0:
    13011370            res = self._new_c(self.initptr._nan)
    1302             return res
    13031371        elif self.initptr.x[0] == 0.0:
    13041372            res = self._new()
    13051373            res.initptr = qd_from_double(-INFINITY)
    1306             return res
    1307        
    1308         res = self._new()
    1309         _sig_on
    1310         c_qd_log(self.initptr.x,res.initptr.x)
    1311         _sig_off
     1374        else:
     1375            res = self._new()
     1376            _sig_on
     1377            c_qd_log(self.initptr.x,res.initptr.x)
     1378            _sig_off
     1379        fpu_fix_end(&cw)
     1380
    13121381        return res
    13131382     
    13141383    def log10(self):
    cdef class QuadDoubleElement(FieldElemen 
    13271396
    13281397        """
    13291398        cdef QuadDoubleElement res
     1399        cdef unsigned int cw
     1400        fpu_fix_start(&cw)
    13301401        if self.initptr.x[0] < 0.0:
    13311402            res = self._new_c(self.initptr._nan)
    1332             return res
    13331403        elif self.initptr.x[0] == 0.0:
    13341404            res = self._new()
    13351405            res.initptr = qd_from_double(-INFINITY)
    1336             return res
    1337        
    1338         res = self._new()
    1339         _sig_on
    1340         c_qd_log10(self.initptr.x,res.initptr.x)
    1341         _sig_off
     1406        else:
     1407            res = self._new()
     1408            _sig_on
     1409            c_qd_log10(self.initptr.x,res.initptr.x)
     1410            _sig_off
     1411        fpu_fix_end(&cw)
     1412
    13421413        return res
    13431414   
    13441415    def exp(self):
    cdef class QuadDoubleElement(FieldElemen 
    13551426            True
    13561427        """
    13571428        cdef QuadDoubleElement res
     1429        cdef unsigned int cw
     1430        fpu_fix_start(&cw)
    13581431        res = self._new()
    13591432        _sig_on
    13601433        c_qd_exp(self.initptr.x,res.initptr.x)
    13611434        _sig_off
     1435        fpu_fix_end(&cw)
    13621436        return res
    13631437   
    13641438    def cos(self):
    cdef class QuadDoubleElement(FieldElemen 
    13731447            1.000000000000000000000000000000000000000000000000000000000000000
    13741448        """
    13751449        cdef QuadDoubleElement res
     1450        cdef unsigned int cw
     1451        fpu_fix_start(&cw)
    13761452        res = self._new()
    13771453        _sig_on
    13781454        c_qd_cos(self.initptr.x,res.initptr.x)
     1455        fpu_fix_end(&cw)
    13791456        _sig_off
    13801457        return res
    13811458       
    cdef class QuadDoubleElement(FieldElemen 
    13881465            2.29792739447387129688852462923399363132147373173602668183970676e-63
    13891466        """
    13901467        cdef QuadDoubleElement res
     1468        cdef unsigned int cw
     1469        fpu_fix_start(&cw)
    13911470        res = self._new()
    13921471        _sig_on
    13931472        c_qd_sin(self.initptr.x,res.initptr.x)
     1473        fpu_fix_end(&cw)
    13941474        _sig_off
    13951475        return res
    13961476   
    cdef class QuadDoubleElement(FieldElemen 
    14071487            0.577350269189625764509148780501957455647601751270126876018602326
    14081488        """
    14091489        cdef QuadDoubleElement res
     1490        cdef unsigned int cw
     1491        fpu_fix_start(&cw)
    14101492        res = self._new()
    14111493        _sig_on
    14121494        c_qd_tan(self.initptr.x,res.initptr.x)
     1495        fpu_fix_end(&cw)
    14131496        _sig_off
    14141497        return res
    14151498
    cdef class QuadDoubleElement(FieldElemen 
    14371520            1.047197551196597746154214461093167628065723133125035273658314863
    14381521        """
    14391522        cdef QuadDoubleElement res
     1523        cdef unsigned int cw
     1524        fpu_fix_start(&cw)
    14401525        res = self._new()
    14411526        _sig_on
    14421527        c_qd_acos(self.initptr.x,res.initptr.x)
     1528        fpu_fix_end(&cw)
    14431529        _sig_off
    14441530        return res
    14451531
    cdef class QuadDoubleElement(FieldElemen 
    14561542            1.047197551196597746154214461093167628065723133125035273658314863
    14571543        """
    14581544        cdef QuadDoubleElement res
     1545        cdef unsigned int cw
     1546        fpu_fix_start(&cw)
    14591547        res = self._new()
    14601548        _sig_on
    14611549        c_qd_asin(self.initptr.x,res.initptr.x)
     1550        fpu_fix_end(&cw)
    14621551        _sig_off
    14631552        return res
    14641553
    cdef class QuadDoubleElement(FieldElemen 
    14751564            1.047197551196597746154214461093167628065723133125035273658314863
    14761565        """
    14771566        cdef QuadDoubleElement res
     1567        cdef unsigned int cw
     1568        fpu_fix_start(&cw)
    14781569        res = self._new()
    14791570        _sig_on
    14801571        c_qd_atan(self.initptr.x,res.initptr.x)
     1572        fpu_fix_end(&cw)
    14811573        _sig_off
    14821574        return res
    14831575
    cdef class QuadDoubleElement(FieldElemen 
    14911583            1.034465640095510565271865251179886560959831568117717546138668562
    14921584        """
    14931585        cdef QuadDoubleElement res
     1586        cdef unsigned int cw
     1587        fpu_fix_start(&cw)
    14941588        res = self._new()
    14951589        _sig_on
    14961590        c_qd_cosh(self.initptr.x,res.initptr.x)
     1591        fpu_fix_end(&cw)
    14971592        _sig_off
    14981593        return res
    14991594
    cdef class QuadDoubleElement(FieldElemen 
    15071602             -0.264800227602270757698096543949405541727737186661923151601337992
    15081603        """
    15091604        cdef QuadDoubleElement res
     1605        cdef unsigned int cw
     1606        fpu_fix_start(&cw)
    15101607        res = self._new()
    15111608        _sig_on
    15121609        c_qd_sinh(self.initptr.x,res.initptr.x)
     1610        fpu_fix_end(&cw)
    15131611        _sig_off
    15141612        return res
    15151613
    cdef class QuadDoubleElement(FieldElemen 
    15231621            0.255977789245684539459617840766661476446446454939881314446181622
    15241622        """
    15251623        cdef QuadDoubleElement res
     1624        cdef unsigned int cw
     1625        fpu_fix_start(&cw)
    15261626        res = self._new()
    15271627        _sig_on
    15281628        c_qd_tanh(self.initptr.x,res.initptr.x)
     1629        fpu_fix_end(&cw)
    15291630        _sig_off
    15301631        return res
    15311632
    cdef class QuadDoubleElement(FieldElemen 
    15431644            1.570796326794896619231321691639751442098584699687552910487472295
    15441645        """
    15451646        cdef QuadDoubleElement res
     1647        cdef unsigned int cw
     1648        fpu_fix_start(&cw)
    15461649        res = self._new()
    15471650        _sig_on
    15481651        c_qd_acosh(self.initptr.x,res.initptr.x)
     1652        fpu_fix_end(&cw)
    15491653        _sig_off
    15501654        return res
    15511655
    cdef class QuadDoubleElement(FieldElemen 
    15621666            1.570796326794896619231321691639751442098584699687552910487472295
    15631667        """
    15641668        cdef QuadDoubleElement res
     1669        cdef unsigned int cw
     1670        fpu_fix_start(&cw)
    15651671        res = self._new()
    15661672        _sig_on
    15671673        c_qd_asinh(self.initptr.x,res.initptr.x)
     1674        fpu_fix_end(&cw)
    15681675        _sig_off
    15691676        return res
    15701677
    cdef class QuadDoubleElement(FieldElemen 
    15811688            1.570796326794896619231321691639751442098584699687552910487472295
    15821689        """
    15831690        cdef QuadDoubleElement res
     1691        cdef unsigned int cw
     1692        fpu_fix_start(&cw)
    15841693        res = self._new()
    15851694        _sig_on
    15861695        c_qd_atanh(self.initptr.x,res.initptr.x)
     1696        fpu_fix_end(&cw)
    15871697        _sig_off
    15881698        return res
    15891699