Ticket #9880: trac_9880_pynac_infinities.patch

File trac_9880_pynac_infinities.patch, 8.9 KB (added by vbraun, 10 years ago)

Fixed commit message.

  • sage/libs/ginac/decl.pxi

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1308339384 25200
    # Node ID fdef57fec9f9c8be1f947b8a717438c48f6e21c4
    # Parent  0266011b7d8b8c2b6b7e3d98cf68702493e76d5c
    Trac #9880: Changed for the modified pynac infinities.
    
    diff --git a/sage/libs/ginac/decl.pxi b/sage/libs/ginac/decl.pxi
    a b  
    1616    void ginac_pyinit_Float(object)
    1717    void ginac_pyinit_I(object)
    1818   
     19    # forward declaration of GEx
     20    ctypedef struct GEx "ex"
     21
    1922    ctypedef struct GBasic "basic":
    2023        unsigned int gethash()
    2124        int compare(GBasic other)
     
    2326    ctypedef struct GConstant "constant":
    2427        unsigned get_serial()
    2528
     29    ctypedef struct GInfinity "infinity":
     30        bint is_unsigned_infinity()
     31        bint is_plus_infinity()
     32        bint is_minus_infinity()
     33        GEx get_direction()
     34        GEx conjugate()
     35        GEx real_part()
     36        GEx imag_part()
    2637
    2738    ctypedef struct GSymbol "symbol":
    2839        unsigned get_domain()
     
    4051    ctypedef struct GExMap "exmap":
    4152        void insert(GExPair e)
    4253
    43     # forward declaration of GEx
    44     ctypedef struct GEx "ex"
    45 
    4654    ctypedef struct GExListIter "GiNaC::lst::const_iterator":
    4755        void inc "operator++" ()
    4856        GEx obj "operator*" ()
     
    8290        GEx real_part()               except +
    8391        GEx imag_part()               except +
    8492        bint info(unsigned)           except +
     93        void dbgprint()
     94        void dbgprinttree()
    8595
    8696    GExPair make_pair "std::make_pair" (GEx, GEx)
    8797
     
    148158    GEx g_Pi "Pi"
    149159    GEx g_Catalan "Catalan"
    150160    GEx g_Euler "Euler"
    151     GEx g_UnsignedInfinity "UnsignedInfinity"
    152     GEx g_Infinity "Infinity"
    153     GEx g_mInfinity "-Infinity"
    154161
    155162    GConstant* GConstant_construct(void *mem, char* name, char* texname, unsigned domain)
    156163    bint is_a_constant "is_a<constant>" (GEx e)
     
    158165    GConstant* GConstant_construct_str "Construct_p<constant, char*>" \
    159166            (void *mem, char* name) except +
    160167
     168    # Infinities
     169    bint is_a_infinity "is_a<infinity>" (GEx e)
     170    GEx g_UnsignedInfinity "UnsignedInfinity"
     171    GEx g_Infinity "Infinity"
     172    GEx g_mInfinity "-Infinity"
     173    GInfinity ex_to_infinity "ex_to<infinity>" (GEx e)
    161174
    162175    # I is not a constant, but a numeric object
    163176    # we declare it here for easy reference
  • sage/symbolic/expression.pxd

    diff --git a/sage/symbolic/expression.pxd b/sage/symbolic/expression.pxd
    a b  
    99    cpdef object _convert(self, R)
    1010    cpdef bint is_polynomial(self, var)
    1111    cpdef bint is_relational(self)
     12    cpdef bint is_infinity(self)
    1213    cpdef object pyobject(self)
    1314    cpdef Expression _subs_expr(self, expr)
    1415    cpdef int _cmp_add(left, CommutativeRingElement right) except -2
  • sage/symbolic/expression.pyx

    diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
    a b  
    145145from sage.symbolic.function import get_sfunction_from_serial, SymbolicFunction
    146146from sage.rings.rational import Rational  # Used for sqrt.
    147147from sage.misc.derivative import multi_derivative
    148 from sage.rings.infinity import AnInfinity
     148from sage.rings.infinity import AnInfinity, infinity, minus_infinity, unsigned_infinity
    149149from sage.misc.decorators import rename_keyword
    150150from sage.misc.misc import deprecated_function_alias
    151151
     
    203203cdef class Expression(CommutativeRingElement):
    204204    cpdef object pyobject(self):
    205205        """
    206         Get the underlying Python object corresponding to this
    207         expression, assuming this expression is a single numerical
    208         value.   Otherwise, a TypeError is raised.
     206        Get the underlying Python object.
     207
     208        OUTPUT:
     209
     210        The python object corresponding to this expression, assuming
     211        this expression is a single numerical value. Otherwise, a
     212        TypeError is raised.
    209213
    210214        EXAMPLES::
    211215       
     
    217221            -17/3
    218222            sage: a.pyobject() is b
    219223            True
     224           
     225        TESTS::
     226       
     227            sage: SR(oo).pyobject()
     228            +Infinity
     229            sage: SR(-oo).pyobject()
     230            -Infinity
     231            sage: SR(unsigned_infinity).pyobject()
     232            Infinity
     233            sage: SR(I*oo).pyobject()
     234            Traceback (most recent call last):
     235            ...
     236            ValueError: Python infinity cannot have complex phase.
    220237        """
    221238        cdef GConstant* c
    222239        if is_a_constant(self._gobj):
    223240            from sage.symbolic.constants import constants_name_table
    224241            return constants_name_table[GEx_to_str(&self._gobj)]
     242
     243        if is_a_infinity(self._gobj):
     244            if (ex_to_infinity(self._gobj).is_unsigned_infinity()): return unsigned_infinity
     245            if (ex_to_infinity(self._gobj).is_plus_infinity()):     return infinity
     246            if (ex_to_infinity(self._gobj).is_minus_infinity()):    return minus_infinity
     247            raise TypeError('Python infinity cannot have complex phase.')
     248           
    225249        if not is_a_numeric(self._gobj):
    226250            raise TypeError, "self must be a numeric expression"
    227251        return py_object_from_numeric(self._gobj)
     
    340364        """
    341365        return new_Expression_from_GEx(self._parent, self._gobj)
    342366
     367    def _dbgprint(self):
     368        r"""
     369        Print pynac debug output.
     370       
     371        EXAMPLES::
     372       
     373            sage: (1+x)._dbgprint()
     374            x + 1
     375        """
     376        self._gobj.dbgprint();
     377
     378    def _dbgprinttree(self):
     379        r"""
     380        Print pynac debug output.
     381       
     382        EXAMPLES::
     383       
     384            sage: (1+x+exp(x+1))._dbgprinttree()    # random output
     385            add @0x65e5960, hash=0x4727e01a, flags=0x3, nops=3
     386                x (symbol) @0x6209150, serial=6, hash=0x2057b15e, flags=0xf, domain=0
     387                1 (numeric) @0x3474cf0, hash=0x0, flags=0x7
     388                -----
     389                function exp @0x24835d0, hash=0x765c2165, flags=0xb, nops=1
     390                    add @0x65df570, hash=0x420740d2, flags=0xb, nops=2
     391                        x (symbol) @0x6209150, serial=6, hash=0x2057b15e, flags=0xf, domain=0
     392                        1 (numeric) @0x3474cf0, hash=0x0, flags=0x7
     393                        -----
     394                        overall_coeff
     395                        1 (numeric) @0x65e4df0, hash=0x7fd3, flags=0x7
     396                        =====
     397                    =====
     398                1 (numeric) @0x3474cf0, hash=0x0, flags=0x7
     399                -----
     400                overall_coeff
     401                1 (numeric) @0x663cc40, hash=0x7fd3, flags=0x7
     402                =====
     403        """
     404        self._gobj.dbgprinttree();
     405
    343406    def _repr_(self):
    344407        """
    345408        Return string representation of this symbolic expression.
     
    16191682        """
    16201683        return is_a_relational(self._gobj)
    16211684
     1685    cpdef bint is_infinity(self):
     1686        """
     1687        Return True if self is a infinite expression.
     1688
     1689        EXAMPLES::
     1690       
     1691            sage: SR(oo).is_infinity()
     1692            True
     1693            sage: x.is_infinity()
     1694            False
     1695        """
     1696        return is_a_infinity(self._gobj)
     1697
    16221698    def left_hand_side(self):
    16231699        """
    16241700        If self is a relational expression, return the left hand side
     
    17801856            sage: bool(x != y) # The same comment as above applies here as well
    17811857            True
    17821858            sage: forget()
     1859
     1860        Comparisons of infinities::
     1861
     1862            sage: assert( (1+I)*oo == (2+2*I)*oo )
     1863            sage: assert( SR(unsigned_infinity) == SR(unsigned_infinity) )
     1864            sage: assert( SR(I*oo) == I*oo )
     1865            sage: assert( SR(-oo) <= SR(oo) )
     1866            sage: assert( SR(oo) >= SR(-oo) )
     1867            sage: assert( SR(oo) != SR(-oo) )
     1868            sage: assert( sqrt(2)*oo != I*oo )
    17831869        """
    17841870        if self.is_relational():
    1785             #If both the left hand side and right hand side are wrappers
    1786             #around Sage objects, then we should do the comparison directly
    1787             #with those objects
     1871            # constants are wrappers around Sage objects, compare directly
    17881872            if is_a_constant(self._gobj.lhs()) and is_a_constant(self._gobj.rhs()):
    17891873                return self.operator()(self.lhs().pyobject(), self.rhs().pyobject())
    17901874
    1791             res = relational_to_bool(self._gobj)
    1792             if res:
     1875            pynac_result = relational_to_bool(self._gobj)
     1876
     1877            # pynac is guaranteed to give the correct answer for comparing infinities
     1878            if is_a_infinity(self._gobj.lhs()) or is_a_infinity(self._gobj.rhs()):
     1879                return pynac_result
     1880
     1881            if pynac_result:
    17931882                if self.operator() == operator.ne: # this hack is necessary to catch the case where the operator is != but is False because of assumptions made
    17941883                    m = self._maxima_()
    17951884                    s = m.parent()._eval_line('is (notequal(%s,%s))'%(repr(m.lhs()),repr(m.rhs())))