# HG changeset patch
# User Volker Braun <vbraun@stp.dias.ie>
# Date 1308339384 25200
# Node ID 765a4b54b75306e2e72c2a44c751025eb06b8ec3
# Parent d84392d4da573c5dd59d339214b0a9fa1f750580
Changes for the modified pynac infinities.
diff --git a/sage/libs/ginac/decl.pxi b/sage/libs/ginac/decl.pxi
a
|
b
|
|
18 | 18 | void ginac_pyinit_Float(object) |
19 | 19 | void ginac_pyinit_I(object) |
20 | 20 | |
| 21 | # forward declaration of GEx |
| 22 | ctypedef struct GEx "ex" |
| 23 | |
21 | 24 | ctypedef struct GBasic "basic": |
22 | 25 | unsigned int gethash() |
23 | 26 | int compare(GBasic other) |
… |
… |
|
25 | 28 | ctypedef struct GConstant "constant": |
26 | 29 | unsigned get_serial() |
27 | 30 | |
| 31 | ctypedef struct GInfinity "infinity": |
| 32 | bint is_unsigned_infinity() |
| 33 | bint is_plus_infinity() |
| 34 | bint is_minus_infinity() |
| 35 | GEx get_direction() |
| 36 | GEx conjugate() |
| 37 | GEx real_part() |
| 38 | GEx imag_part() |
28 | 39 | |
29 | 40 | ctypedef struct GSymbol "symbol": |
30 | 41 | unsigned get_domain() |
… |
… |
|
43 | 54 | ctypedef struct GExMap "exmap": |
44 | 55 | void insert(GExPair e) |
45 | 56 | |
46 | | # forward declaration of GEx |
47 | | ctypedef struct GEx "ex" |
48 | | |
49 | 57 | ctypedef struct GExListIter "GiNaC::lst::const_iterator": |
50 | 58 | void inc "operator++" () |
51 | 59 | GEx obj "operator*" () |
… |
… |
|
161 | 169 | GEx g_Pi "Pi" |
162 | 170 | GEx g_Catalan "Catalan" |
163 | 171 | GEx g_Euler "Euler" |
164 | | GEx g_UnsignedInfinity "UnsignedInfinity" |
165 | | GEx g_Infinity "Infinity" |
166 | | GEx g_mInfinity "-Infinity" |
167 | 172 | |
168 | 173 | GConstant* GConstant_construct(void *mem, char* name, char* texname, unsigned domain) |
169 | 174 | bint is_a_constant "is_a<constant>" (GEx e) |
… |
… |
|
171 | 176 | GConstant* GConstant_construct_str "Construct_p<constant, char*>" \ |
172 | 177 | (void *mem, char* name) except + |
173 | 178 | |
| 179 | # Infinities |
| 180 | bint is_a_infinity "is_a<infinity>" (GEx e) |
| 181 | GEx g_UnsignedInfinity "UnsignedInfinity" |
| 182 | GEx g_Infinity "Infinity" |
| 183 | GEx g_mInfinity "-Infinity" |
| 184 | GInfinity ex_to_infinity "ex_to<infinity>" (GEx e) |
174 | 185 | |
175 | 186 | # I is not a constant, but a numeric object |
176 | 187 | # we declare it here for easy reference |
diff --git a/sage/symbolic/expression.pxd b/sage/symbolic/expression.pxd
a
|
b
|
|
10 | 10 | cpdef object _convert(self, R) |
11 | 11 | cpdef bint is_polynomial(self, var) |
12 | 12 | cpdef bint is_relational(self) |
| 13 | cpdef bint is_infinity(self) |
13 | 14 | cpdef object pyobject(self) |
14 | 15 | cpdef Expression _subs_expr(self, expr) |
15 | 16 | |
diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
a
|
b
|
|
145 | 145 | from sage.symbolic.function import get_sfunction_from_serial, SymbolicFunction |
146 | 146 | from sage.rings.rational import Rational # Used for sqrt. |
147 | 147 | from sage.misc.derivative import multi_derivative |
148 | | from sage.rings.infinity import AnInfinity |
| 148 | from sage.rings.infinity import AnInfinity, infinity, minus_infinity, unsigned_infinity |
149 | 149 | from sage.misc.decorators import rename_keyword |
150 | 150 | from sage.misc.misc import deprecated_function_alias |
151 | 151 | |
… |
… |
|
203 | 203 | cdef class Expression(CommutativeRingElement): |
204 | 204 | cpdef object pyobject(self): |
205 | 205 | """ |
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. |
209 | 213 | |
210 | 214 | EXAMPLES:: |
211 | 215 | |
… |
… |
|
217 | 221 | -17/3 |
218 | 222 | sage: a.pyobject() is b |
219 | 223 | 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. |
220 | 237 | """ |
221 | 238 | cdef GConstant* c |
222 | 239 | if is_a_constant(self._gobj): |
223 | 240 | from sage.symbolic.constants import constants_name_table |
224 | 241 | 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 | |
225 | 249 | if not is_a_numeric(self._gobj): |
226 | 250 | raise TypeError, "self must be a numeric expression" |
227 | 251 | return py_object_from_numeric(self._gobj) |
… |
… |
|
1660 | 1684 | """ |
1661 | 1685 | return is_a_relational(self._gobj) |
1662 | 1686 | |
| 1687 | cpdef bint is_infinity(self): |
| 1688 | """ |
| 1689 | Return True if self is a infinite expression. |
| 1690 | |
| 1691 | EXAMPLES:: |
| 1692 | |
| 1693 | sage: SR(oo).is_infinity() |
| 1694 | True |
| 1695 | sage: x.is_infinity() |
| 1696 | False |
| 1697 | """ |
| 1698 | return is_a_infinity(self._gobj) |
| 1699 | |
1663 | 1700 | def left_hand_side(self): |
1664 | 1701 | """ |
1665 | 1702 | If self is a relational expression, return the left hand side |
… |
… |
|
1859 | 1896 | sage: bool(x != y) # The same comment as above applies here as well |
1860 | 1897 | True |
1861 | 1898 | sage: forget() |
| 1899 | |
| 1900 | Comparisons of infinities:: |
| 1901 | |
| 1902 | sage: assert( (1+I)*oo == (2+2*I)*oo ) |
| 1903 | sage: assert( SR(unsigned_infinity) == SR(unsigned_infinity) ) |
| 1904 | sage: assert( SR(I*oo) == I*oo ) |
| 1905 | sage: assert( SR(-oo) <= SR(oo) ) |
| 1906 | sage: assert( SR(oo) >= SR(-oo) ) |
| 1907 | sage: assert( SR(oo) != SR(-oo) ) |
| 1908 | sage: assert( sqrt(2)*oo != I*oo ) |
1862 | 1909 | """ |
1863 | 1910 | if self.is_relational(): |
1864 | | #If both the left hand side and right hand side are wrappers |
1865 | | #around Sage objects, then we should do the comparison directly |
1866 | | #with those objects |
| 1911 | # constants are wrappers around Sage objects, compare directly |
1867 | 1912 | if is_a_constant(self._gobj.lhs()) and is_a_constant(self._gobj.rhs()): |
1868 | 1913 | return self.operator()(self.lhs().pyobject(), self.rhs().pyobject()) |
1869 | 1914 | |
1870 | | res = relational_to_bool(self._gobj) |
1871 | | if res: |
| 1915 | pynac_result = relational_to_bool(self._gobj) |
| 1916 | |
| 1917 | # pynac is guaranteed to give the correct answer for comparing infinities |
| 1918 | if is_a_infinity(self._gobj.lhs()) or is_a_infinity(self._gobj.rhs()): |
| 1919 | return pynac_result |
| 1920 | |
| 1921 | if pynac_result: |
1872 | 1922 | if self.operator() == operator.ne: # this hack is necessary to catch the case where the operator is != but is False because of assumptions made |
1873 | 1923 | m = self._maxima_() |
1874 | 1924 | s = m.parent()._eval_line('is (notequal(%s,%s))'%(repr(m.lhs()),repr(m.rhs()))) |