4 from basic
import Basic
, Atom
, Singleton
, S
, Memoizer
, MemoizerArg
5 from methods
import NoRelMeths
, RelMeths
, ArithMeths
6 from power
import integer_nthroot
8 @Memoizer((int, long), (int, long))
11 Returns the Greatest Common Divisor, implementing Euclid's algorithm.
17 @Memoizer((int, long), return_value_converter
= lambda d
: d
.copy())
18 def factor_trial_division(n
):
20 Factor any integer into a product of primes, 0, 1, and -1.
21 Returns a dictionary {<prime: exponent>}.
40 while n
> 1 and d
*d
<= n
:
57 class Number(Atom
, RelMeths
, ArithMeths
):
59 Represents any kind of number in sympy.
61 Floating point numbers are represented by the Real class.
62 Integer numbers (of any size), together with rational numbers (again, there
63 is no limit on their size) are represented by the Rational class.
65 If you want to represent for example 1+sqrt(2), then you need to do:
67 Rational(1) + sqrt(Rational(2))
74 def __new__(cls
, *obj
):
75 if len(obj
)==1: obj
=obj
[0]
76 if isinstance(obj
, (int, long)):
78 if isinstance(obj
,tuple) and len(obj
)==2:
80 if isinstance(obj
, (str,float,decimal
.Decimal
)):
82 if isinstance(obj
, Number
):
84 raise TypeError("expected str|int|long|float|Decimal|Number object but got %r" % (obj
))
86 def _eval_evalf(self
):
87 r
= self
._as
_decimal
()
91 return float(self
._as
_decimal
())
93 def _as_decimal(self
):
94 raise NotImplementedError('%s needs ._as_decimal() method' % (self
.__class
__.__name
__))
96 def _eval_derivative(self
, s
):
99 def _eval_conjugate(self
):
102 def _eval_apply(self
, a
):
105 def _eval_order(self
, *symbols
):
106 # Order(5, x, y) -> Order(1,x,y)
107 return Basic
.Order(S
.One
, *symbols
)
109 def sqrt(self
): return Real(decimal_math
.sqrt(self
._as
_decimal
()))
110 def exp(self
): return Real(decimal_math
.exp(self
._as
_decimal
()))
111 def log(self
): return Real(decimal_math
.log(self
._as
_decimal
()))
112 def sin(self
): return Real(decimal_math
.sin(self
._as
_decimal
()))
113 def cos(self
): return Real(decimal_math
.cos(self
._as
_decimal
()))
114 def tan(self
): return Real(decimal_math
.tan(self
._as
_decimal
()))
115 def cot(self
): return Real(decimal_math
.cot(self
._as
_decimal
()))
116 def asin(self
): return Real(decimal_math
.asin(self
._as
_decimal
()))
117 def acos(self
): return Real(decimal_math
.acos(self
._as
_decimal
()))
118 def atan(self
): return Real(decimal_math
.atan(self
._as
_decimal
()))
119 def acot(self
): return Real(decimal_math
.acot(self
._as
_decimal
()))
120 def sinh(self
): return Real(decimal_math
.sinh(self
._as
_decimal
()))
121 def cosh(self
): return Real(decimal_math
.cosh(self
._as
_decimal
()))
122 def tanh(self
): return Real(decimal_math
.tanh(self
._as
_decimal
()))
123 def coth(self
): return Real(decimal_math
.coth(self
._as
_decimal
()))
124 def asinh(self
): return Real(decimal_math
.asinh(self
._as
_decimal
()))
125 def acosh(self
): return Real(decimal_math
.acosh(self
._as
_decimal
()))
126 def atanh(self
): return Real(decimal_math
.atanh(self
._as
_decimal
()))
127 def acoth(self
): return Real(decimal_math
.acoth(self
._as
_decimal
()))
128 def floor(self
): return Real(decimal_math
.floor(self
._as
_decimal
()))
129 def ceiling(self
): return Real(decimal_math
.ceiling(self
._as
_decimal
()))
131 def __eq__(self
, other
):
132 raise NotImplementedError,'%s needs .__eq__() method' % (self
.__class
__.__name
__)
133 def __ne__(self
, other
):
134 raise NotImplementedError,'%s needs .__ne__() method' % (self
.__class
__.__name
__)
135 def __lt__(self
, other
):
136 raise NotImplementedError,'%s needs .__lt__() method' % (self
.__class
__.__name
__)
137 def __le__(self
, other
):
138 raise NotImplementedError,'%s needs .__le__() method' % (self
.__class
__.__name
__)
140 def __gt__(self
, other
):
141 return Basic
.sympify(other
).__lt
__(self
)
142 def __ge__(self
, other
):
143 return Basic
.sympify(other
).__le
__(self
)
145 def as_coeff_terms(self
, x
=None):
149 decimal_to_Number_cls
= {
150 decimal
.Decimal('0').as_tuple():'Zero',
151 decimal
.Decimal('-0').as_tuple():'Zero',
152 decimal
.Decimal('1').as_tuple():'One',
153 decimal
.Decimal('-1').as_tuple():'NegativeOne',
154 decimal
.Decimal('Infinity').as_tuple():'Infinity',
155 decimal
.Decimal('-Infinity').as_tuple():'NegativeInfinity',
156 decimal
.Decimal('NaN').as_tuple():'NaN',
159 def convert_to_Decimal(num
):
160 if isinstance(num
, str):
161 num
= decimal
.Decimal(num
)
162 elif isinstance(num
, float):
163 num
= Real
.float_to_decimal(num
)
168 Represents a floating point number. It is capable of representing
169 arbitrary-precision floating-point numbers
173 Real(3.5) .... 3.5 (the 3.5 was converted from a python float)
174 Real("3.0000000000000005")
178 - Real(x) with x being a Python int/long will return Integer(x)
181 is_irrational
= False
184 @Memoizer(type, MemoizerArg((str, int, long, float, decimal
.Decimal
), convert_to_Decimal
))
185 def __new__(cls
, num
):
186 if isinstance(num
, (int, long)):
189 singleton_cls_name
= decimal_to_Number_cls
.get(num
.as_tuple(), None)
190 if singleton_cls_name
is not None:
191 return getattr(Basic
, singleton_cls_name
)()
192 obj
= Basic
.__new
__(cls
)
197 def float_to_decimal(f
):
198 "Convert a floating point number to a Decimal with no loss of information"
199 # Transform (exactly) a float to a mantissa (0.5 <= abs(m) < 1.0) and an
200 # exponent. Double the mantissa until it is an integer. Use the integer
201 # mantissa and exponent to compute an equivalent Decimal. If this cannot
202 # be done exactly, then retry with more precision.
205 mantissa
, exponent
= math
.frexp(f
)
206 except OverflowError:
209 while mantissa
!= int(mantissa
):
212 mantissa
= int(mantissa
)
214 oldcontext
= decimal
.getcontext()
215 decimal
.setcontext(decimal
.Context(traps
=[decimal
.Inexact
]))
219 return mantissa
* decimal
.Decimal(2) ** exponent
220 except decimal
.Inexact
:
221 decimal
.getcontext().prec
+= 1
223 decimal
.setcontext(oldcontext
)
225 def _hashable_content(self
):
228 def tostr(self
, level
=0):
229 r
= str(self
.num
.normalize())
230 if self
.precedence
<=level
:
235 return '%s(%r)' % (self
.__class
__.__name
__, str(self
.num
))
237 def _eval_is_positive(self
):
238 return self
.num
.as_tuple()[0] == 0
240 def _eval_is_negative(self
):
241 return self
.num
.as_tuple()[0] == 1
243 def _eval_evalf(self
):
246 def _as_decimal(self
):
250 return Real(-self
.num
)
252 def __mul__(self
, other
):
253 other
= Basic
.sympify(other
)
254 if isinstance(other
, Number
):
255 return Real(self
.num
* other
._as
_decimal
())
256 return Number
.__mul
__(self
, other
)
258 def __add__(self
, other
):
259 other
= Basic
.sympify(other
)
260 if isinstance(other
, NaN
) or isinstance(self
, NaN
):
262 if isinstance(other
, Number
):
263 return Real(self
.num
+ other
._as
_decimal
())
264 return Number
.__add
__(self
, other
)
266 def _eval_power(b
, e
):
268 b is Real but not equal to rationals, integers, 0.5, oo, -oo, nan
269 e is symbolic object but not equal to 0, 1
271 (-p) ** r -> exp(r * log(-p)) -> exp(r * (log(p) + I*Pi)) ->
272 -> p ** r * (sin(Pi*r) + cos(Pi*r) * I)
274 if isinstance(e
, Number
):
275 if isinstance(e
, Integer
):
277 return Real(decimal_math
.pow(b
.num
, e
))
280 if b
.is_negative
and not e
.is_integer
:
281 m
= decimal_math
.pow(-b
.num
, e2
)
282 a
= decimal_math
.pi() * e2
283 s
= m
* decimal_math
.sin(a
)
284 c
= m
* decimal_math
.cos(a
)
285 return Real(s
) + Real(c
) * S
.ImaginaryUnit
286 return Real(decimal_math
.pow(b
.num
, e2
))
290 return Real(abs(self
.num
))
296 return float(self
.num
)
298 def __eq__(self
, other
):
299 other
= Basic
.sympify(other
)
300 if isinstance(other
, NumberSymbol
):
301 if other
.is_irrational
: return False
302 return other
.__eq
__(self
)
303 if other
.is_comparable
: other
= other
.evalf()
304 if isinstance(other
, Number
):
305 return bool(self
._as
_decimal
()==other
._as
_decimal
())
306 return RelMeths
.__eq
__(self
, other
)
307 def __ne__(self
, other
):
308 other
= Basic
.sympify(other
)
309 if isinstance(other
, NumberSymbol
):
310 if other
.is_irrational
: return True
311 return other
.__ne
__(self
)
312 if other
.is_comparable
: other
= other
.evalf()
313 if isinstance(other
, Number
):
314 return bool(self
._as
_decimal
()!=other
._as
_decimal
())
315 return RelMeths
.__ne
__(self
, other
)
316 def __lt__(self
, other
):
317 other
= Basic
.sympify(other
)
318 if isinstance(other
, NumberSymbol
):
319 return other
.__ge
__(self
)
320 if other
.is_comparable
: other
= other
.evalf()
321 if isinstance(other
, Number
):
322 return bool(self
._as
_decimal
() < other
._as
_decimal
())
323 return RelMeths
.__lt
__(self
, other
)
324 def __le__(self
, other
):
325 other
= Basic
.sympify(other
)
326 if isinstance(other
, NumberSymbol
):
327 return other
.__gt
__(self
)
328 if other
.is_comparable
: other
= other
.evalf()
329 if isinstance(other
, Number
):
330 return bool(self
._as
_decimal
()<=other
._as
_decimal
())
331 return RelMeths
.__le
__(self
, other
)
333 def epsilon_eq(self
, other
, epsilon
="10e-16"):
334 return abs(self
- other
) < Basic
.Real(epsilon
)
336 def _parse_rational(s
):
337 """Parse rational number from string representation"""
341 return int(p
), int(q
)
348 s
, periodic
= s
.split("[")
349 periodic
= periodic
.rstrip("]")
350 offset
= len(s
) - s
.index(".") - 1
352 n2
= int("9" * len(periodic
))
353 r
= Rational(*_parse_rational(s
)) + Rational(n1
, n2
*10**offset
)
355 # Ordinary decimal string. Use the Decimal class's built-in parser
357 sign
, digits
, expt
= decimal
.Decimal(s
).as_tuple()
358 p
= (1, -1)[sign
] * int("".join(str(x
) for x
in digits
))
360 return p
*(10**expt
), 1
365 class Rational(Number
):
366 """Represents integers and rational numbers (p/q) of any size.
375 You can create a rational from a string:
381 Use square brackets to indicate a recurring decimal:
382 >>> Rational("0.[333]")
384 >>> Rational("1.2[05]")
386 >>> float(Rational(1193,990))
393 @Memoizer(type, (int, long, str), MemoizerArg((int, long, type(None)), name
="q"))
394 def __new__(cls
, p
, q
= None):
396 if isinstance(p
, str):
397 p
, q
= _parse_rational(p
)
401 if p
==0: return S
.NaN
402 if p
<0: return S
.NegativeInfinity
411 if q
==1: return Integer(p
)
412 if p
==1 and q
==2: return S
.Half
413 obj
= Basic
.__new
__(cls
)
418 def _hashable_content(self
):
419 return (self
.p
, self
.q
)
421 def tostr(self
, level
=0):
422 if self
.precedence
<=level
:
423 return '(%s/%s)' % (self
.p
, self
.q
)
424 return '%s/%s' % (self
.p
, self
.q
)
427 return '%s(%r, %r)' % (self
.__class
__.__name
__, self
.p
, self
.q
)
430 def precedence(self
):
432 return Basic
.Add_precedence
433 return Basic
.Mul_precedence
435 def _eval_is_positive(self
):
438 def _eval_is_zero(self
):
441 def __neg__(self
): return Rational(-self
.p
, self
.q
)
443 def __mul__(self
, other
):
444 other
= Basic
.sympify(other
)
445 if isinstance(other
, NaN
) or isinstance(self
, NaN
):
447 if isinstance(other
, Real
):
448 return Real(self
._as
_decimal
() * other
.num
)
449 if isinstance(other
, Rational
):
450 return Rational(self
.p
* other
.p
, self
.q
* other
.q
)
451 return Number
.__mul
__(self
, other
)
453 def __add__(self
, other
):
454 other
= Basic
.sympify(other
)
455 if isinstance(other
, NaN
) or isinstance(self
, NaN
):
457 if isinstance(other
, Real
):
458 return Real(self
._as
_decimal
() + other
.num
)
459 if isinstance(other
, Rational
):
460 if self
.is_unbounded
:
466 if other
.is_unbounded
:
468 return Rational(self
.p
* other
.q
+ self
.q
* other
.p
, self
.q
* other
.q
)
469 return Number
.__add
__(self
, other
)
471 def _eval_power(b
, e
):
472 if isinstance(e
, Number
):
473 if isinstance(e
, NaN
): return S
.NaN
474 if isinstance(e
, Real
):
475 return Real(decimal_math
.pow(b
._as
_decimal
(), e
.num
))
477 # (3/4)**-2 -> (4/3)**2
479 if isinstance(ne
, One
):
480 return Rational(b
.q
, b
.p
)
481 return Rational(b
.q
, b
.p
) ** ne
482 if isinstance(e
, Infinity
):
487 # (-3/2)**oo -> oo + I*oo
488 return S
.Infinity
+ S
.Infinity
* S
.ImaginaryUnit
490 if isinstance(e
, Integer
):
491 # (4/3)**2 -> 4**2 / 3**2
492 return Rational(b
.p
** e
.p
, b
.q
** e
.p
)
493 if isinstance(e
, Rational
):
495 # (4/3)**(5/6) -> 4**(5/6) * 3**(-5/6)
496 return Integer(b
.p
) ** e
* Integer(b
.q
) ** (-e
)
498 x
, xexact
= integer_nthroot(b
.p
, e
.q
)
499 y
, yexact
= integer_nthroot(b
.q
, e
.q
)
500 if xexact
and yexact
:
501 res
= Rational(x
** abs(e
.p
), y
** abs(e
.p
))
506 # Now check also devisors of the exponents denominator
507 # TODO: Check if this slows down to much.
508 for i
in xrange(2, e
.q
/2 + 1):
510 x
, xexact
= integer_nthroot(b
.p
, i
)
511 y
, yexact
= integer_nthroot(b
.q
, i
)
512 if xexact
and yexact
:
513 return Rational(x
, y
)**Rational(e
.p
, e
.q
/i
)
515 # Try to get some part of the base out, if exp > 1
519 return b
**i
* b
**Rational(r
, e
.q
)
521 return (-1)**e
* (-b
)**e
523 c
,t
= b
.as_coeff_terms()
524 if e
.is_even
and isinstance(c
, Basic
.Number
) and c
< 0:
525 return (-c
* Basic
.Mul(*t
)) ** e
529 def _as_decimal(self
):
530 return decimal
.Decimal(self
.p
) / decimal
.Decimal(self
.q
)
533 return Rational(abs(self
.p
), self
.q
)
536 return int(self
.p
//self
.q
)
538 def __eq__(self
, other
):
539 other
= Basic
.sympify(other
)
540 if isinstance(other
, NumberSymbol
):
541 if other
.is_irrational
: return False
542 return other
.__eq
__(self
)
543 from sympy
.core
.function
import FunctionClass
544 if isinstance(self
, Number
) and isinstance(other
, FunctionClass
):
546 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
547 if isinstance(other
, Number
):
548 if isinstance(other
, Real
):
549 return bool(self
._as
_decimal
()==other
._as
_decimal
())
550 return bool(self
.p
==other
.p
and self
.q
==other
.q
)
551 return RelMeths
.__eq
__(self
, other
)
552 def __ne__(self
, other
):
553 other
= Basic
.sympify(other
)
554 if isinstance(other
, NumberSymbol
):
555 if other
.is_irrational
: return True
556 return other
.__ne
__(self
)
557 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
558 if isinstance(other
, Number
):
559 if isinstance(other
, Real
):
560 return bool(self
._as
_decimal
()!=other
._as
_decimal
())
561 return bool(self
.p
!=other
.p
or self
.q
!=other
.q
)
562 return RelMeths
.__ne
__(self
, other
)
563 def __lt__(self
, other
):
564 other
= Basic
.sympify(other
)
565 if isinstance(other
, NumberSymbol
):
566 return other
.__ge
__(self
)
567 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
568 if isinstance(other
, Number
):
569 if isinstance(other
, Real
):
570 return bool(self
._as
_decimal
() < other
._as
_decimal
())
571 return bool(self
.p
* other
.q
< self
.q
* other
.p
)
572 return RelMeths
.__lt
__(self
, other
)
573 def __le__(self
, other
):
574 other
= Basic
.sympify(other
)
575 if isinstance(other
, NumberSymbol
):
576 return other
.__gt
__(self
)
577 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
578 if isinstance(other
, Number
):
579 if isinstance(other
, Real
):
580 return bool(self
._as
_decimal
()<=other
._as
_decimal
())
581 return bool(self
.p
* other
.q
<= self
.q
* other
.p
)
582 return RelMeths
.__le
__(self
, other
)
585 f
= factor_trial_division(self
.p
).copy()
586 for p
,e
in factor_trial_division(self
.q
).items():
588 except KeyError: f
[p
] = -e
590 for p
,e
in f
.items():
595 except KeyError: fi
[e
] = p
597 for e
,p
in fi
.items():
599 if len(f
)>1 and f
.has_key(1): del f
[1]
602 def as_numer_denom(self
):
603 return Integer(self
.p
), Integer(self
.q
)
605 class Integer(Rational
):
610 @Memoizer(type, (int, long))
612 if isinstance(i
, Integer
):
614 if i
==0: return S
.Zero
615 if i
==1: return S
.One
616 if i
==-1: return S
.NegativeOne
617 obj
= Basic
.__new
__(cls
)
621 def _eval_is_odd(self
):
622 return bool(self
.p
% 2)
625 def precedence(self
):
627 return 40 # same as Add
628 return Atom
.precedence
630 def tostr(self
, level
=0):
631 if self
.precedence
<=level
:
632 return '(%s)' % (self
.p
)
636 return '%s(%r)' % (self
.__class
__.__name
__, self
.p
)
638 def _eval_evalf(self
):
641 def _eval_power(b
, e
):
642 if isinstance(e
, Number
):
643 if isinstance(e
, NaN
): return S
.NaN
644 if isinstance(e
, Real
):
645 return Real(decimal_math
.pow(b
._as
_decimal
(), e
.num
))
647 # (3/4)**-2 -> (4/3)**2
649 if isinstance(ne
, One
):
650 return Rational(1, b
.p
)
651 return Rational(1, b
.p
) ** ne
652 if isinstance(e
, Infinity
):
657 # (-3)**oo -> oo + I*oo
658 return S
.Infinity
+ S
.Infinity
* S
.ImaginaryUnit
660 if isinstance(e
, Integer
):
661 # (4/3)**2 -> 4**2 / 3**2
662 return Integer(b
.p
** e
.p
)
663 if isinstance(e
, Rational
):
664 if b
== -1: # any one has tested this ???
665 # calculate the roots of -1
668 r
= cos(pi
/e
.q
) + S
.ImaginaryUnit
*sin(pi
/e
.q
)
671 x
, xexact
= integer_nthroot(b
.p
, e
.q
)
673 res
= Integer(x
** abs(e
.p
))
678 # Now check also devisors of the exponents denominator
679 # TODO: Check if this slows down to much.
680 for i
in xrange(2, e
.q
/2 + 1):
682 x
, xexact
= integer_nthroot(b
.p
, i
)
684 return Integer(x
)**(e
* i
)
685 # Try to get some part of the base out, if exponent > 1
689 return b
**i
* b
**Rational(r
, e
.q
)
692 return (-1)**e
* (-b
)**e
694 c
,t
= b
.as_coeff_terms()
695 if e
.is_even
and isinstance(c
, Basic
.Number
) and c
< 0:
696 return (-c
* Basic
.Mul(*t
)) ** e
700 def _eval_is_prime(self
):
704 def as_numer_denom(self
):
707 def __floordiv__(self
, other
):
708 return Integer(self
.p
// Integer(other
).p
)
710 def __rfloordiv__(self
, other
):
711 return Integer(Integer(other
).p
// self
.p
)
713 class Zero(Singleton
, Integer
):
724 def _eval_power(b
, e
):
730 if isinstance(d
, Number
):
734 coeff
, terms
= e
.as_coeff_terms()
735 if coeff
.is_negative
:
736 return S
.Infinity
** Basic
.Mul(*terms
)
737 if not isinstance(coeff
, Basic
.One
):
738 return b
** Basic
.Mul(*terms
)
740 def _eval_order(self
, *symbols
):
744 class One(Singleton
, Integer
):
751 def _eval_power(b
, e
):
754 def _eval_order(self
, *symbols
):
757 class NegativeOne(Singleton
, Integer
):
762 def _eval_power(b
, e
):
763 if e
.is_odd
: return S
.NegativeOne
764 if e
.is_even
: return S
.One
765 if isinstance(e
, Number
):
766 if isinstance(e
, Real
):
767 a
= e
.num
* decimal_math
.pi()
768 s
= decimal_math
.sin(a
)
769 c
= decimal_math
.cos(a
)
770 return Real(s
) + Real(c
) * S
.ImaginaryUnit
771 if isinstance(e
, NaN
):
773 if isinstance(e
, (Infinity
, NegativeInfinity
)):
775 if isinstance(e
, Half
):
776 return S
.ImaginaryUnit
777 if isinstance(e
, Rational
):
779 return S
.ImaginaryUnit
** Integer(e
.p
)
783 return b
** q
* b
** (e
- q
)
786 class Half(Singleton
, Rational
):
791 class Infinity(Singleton
, Rational
):
796 is_commutative
= True
802 def tostr(self
, level
=0):
805 def _eval_power(b
, e
):
807 e is symbolic object but not equal to 0, 1
810 oo ** (-p) -> 0, p is number, oo
816 if isinstance(e
, Number
):
817 if isinstance(e
, NaN
):
820 if isinstance(d
, Number
):
824 def _as_decimal(self
):
825 return decimal
.Decimal('Infinity')
827 class NegativeInfinity(Singleton
, Rational
):
832 is_commutative
= True
838 precedence
= 40 # same as Add
840 def tostr(self
, level
=0):
843 def _eval_power(b
, e
):
845 e is symbolic object but not equal to 0, 1
849 (-oo) ** (-oo) -> nan
850 (-oo) ** e -> oo, e is positive even integer
851 (-oo) ** o -> -oo, o is positive odd integer
854 if isinstance(e
, Number
):
855 if isinstance(e
, (NaN
, Infinity
, NegativeInfinity
)):
857 if isinstance(e
, Integer
):
860 return S
.NegativeInfinity
862 return S
.NegativeOne
**e
* S
.Infinity
** e
865 def _as_decimal(self
):
866 return decimal
.Decimal('-Infinity')
868 class NaN(Singleton
, Rational
):
873 is_commutative
= True
877 #is_unbounded = False
879 def tostr(self
, level
=0):
882 def _as_decimal(self
):
883 return decimal
.Decimal('NaN')
885 def _eval_power(b
, e
):
886 if isinstance(e
, Basic
.Zero
):
890 class ComplexInfinity(Singleton
, Atom
, NoRelMeths
, ArithMeths
):
892 is_commutative
= True
897 def tostr(self
, level
=0):
900 def _eval_power(b
, e
):
901 if isinstance(e
, Basic
.ComplexInfinity
):
904 if isinstance(e
, Basic
.Number
):
905 if isinstance(e
, Basic
.Zero
):
909 return S
.ComplexInfinity
913 class NumberSymbol(Singleton
, Atom
, RelMeths
, ArithMeths
):
915 is_commutative
= True
920 def approximation(self
, number_cls
):
921 """ Return an interval with number_cls endpoints
922 that contains the value of NumberSymbol.
923 If not implemented, then return None.
926 def _eval_derivative(self
, s
):
928 def __eq__(self
, other
):
929 other
= Basic
.sympify(other
)
930 if self
is other
: return True
931 if isinstance(other
, Number
) and self
.is_irrational
: return False
932 return RelMeths
.__eq
__(self
, other
)
933 def __ne__(self
, other
):
934 other
= Basic
.sympify(other
)
935 if self
is other
: return False
936 if isinstance(other
, Number
) and self
.is_irrational
: return True
937 return RelMeths
.__ne
__(self
, other
)
938 def __lt__(self
, other
):
939 other
= Basic
.sympify(other
)
940 if self
is other
: return False
941 if isinstance(other
, Number
):
942 approx
= self
.approximation_interval(other
.__class
__)
943 if approx
is not None:
945 if other
< l
: return False
946 if other
> u
: return True
947 return self
.evalf()<other
948 if other
.is_comparable
:
949 other
= other
.evalf()
950 return self
.evalf()<other
951 return RelMeths
.__lt
__(self
, other
)
952 def __le__(self
, other
):
953 other
= Basic
.sympify(other
)
954 if self
is other
: return True
955 if other
.is_comparable
: other
= other
.evalf()
956 if isinstance(other
, Number
):
957 return self
.evalf()<=other
958 return RelMeths
.__le
__(self
, other
)
959 def __gt__(self
, other
):
960 return (-self
) < (-other
)
961 def __ge__(self
, other
):
962 return (-self
) <= (-other
)
965 class Exp1(NumberSymbol
):
969 is_negative
= False # XXX Forces is_negative/is_nonnegative
972 def tostr(self
, level
=0):
975 def _eval_evalf(self
):
976 return Real(decimal_math
.e())
978 def approximation_interval(self
, number_cls
):
979 if issubclass(number_cls
,Integer
):
980 return (Integer(2),Integer(3))
981 elif issubclass(number_cls
,Rational
):
984 def _eval_power(self
, exp
):
985 return Basic
.exp(exp
)
987 class Pi(NumberSymbol
):
994 def _eval_evalf(self
):
995 return Real(decimal_math
.pi())
997 def approximation_interval(self
, number_cls
):
998 if issubclass(number_cls
, Integer
):
999 return (Integer(3), Integer(4))
1000 elif issubclass(number_cls
, Rational
):
1001 return (Rational(223,71), Rational(22,7))
1003 def tostr(self
, level
=0):
1006 class GoldenRatio(NumberSymbol
):
1011 is_irrational
= True
1013 def _eval_evalf(self
):
1014 return Real(decimal_math
.golden_ratio())
1016 def _eval_expand_func(self
, *args
):
1017 return S
.Half
+ S
.Half
*S
.Sqrt(5)
1019 def approximation_interval(self
, number_cls
):
1020 if issubclass(number_cls
, Integer
):
1021 return (S
.One
, Rational(2))
1022 elif issubclass(number_cls
, Rational
):
1025 def tostr(self
, level
=0):
1026 return 'GoldenRatio'
1028 class EulerGamma(NumberSymbol
):
1033 is_irrational
= None
1035 def _eval_evalf(self
):
1038 def approximation_interval(self
, number_cls
):
1039 if issubclass(number_cls
, Integer
):
1040 return (S
.Zero
, S
.One
)
1041 elif issubclass(number_cls
, Rational
):
1042 return (S
.Half
, Rational(3, 5))
1044 def tostr(self
, level
=0):
1047 class Catalan(NumberSymbol
):
1052 is_irrational
= None
1054 def _eval_evalf(self
):
1057 def approximation_interval(self
, number_cls
):
1058 if issubclass(number_cls
, Integer
):
1059 return (S
.Zero
, S
.One
)
1060 elif issubclass(number_cls
, Rational
):
1061 return (Rational(9, 10), S
.One
)
1063 def tostr(self
, level
=0):
1066 class ImaginaryUnit(Singleton
, Atom
, RelMeths
, ArithMeths
):
1068 is_commutative
= True
1073 def tostr(self
, level
=0):
1076 def _eval_conjugate(self
):
1077 return -S
.ImaginaryUnit
1079 def _eval_derivative(self
, s
):
1082 def _eval_power(b
, e
):
1085 e is symbolic object but not equal to 0, 1
1087 I ** r -> (-1)**(r/2) -> exp(r/2 * Pi * I) -> sin(Pi*r/2) + cos(Pi*r/2) * I, r is decimal
1095 if isinstance(e
, Number
):
1096 #if isinstance(e, Decimal):
1097 # a = decimal_math.pi() * exponent.num / 2
1098 # return Decimal(decimal_math.sin(a) + decimal_math.cos(a) * ImaginaryUnit())
1099 if isinstance(e
, Integer
):
1101 if e
==0: return S
.One
1102 if e
==1: return S
.ImaginaryUnit
1103 if e
==2: return -S
.One
1104 return -S
.ImaginaryUnit
1105 return (-S
.One
) ** (e
* S
.Half
)
1108 def as_base_exp(self
):
1109 return -S
.One
, S
.Half
1111 Basic
.singleton
['E'] = Exp1
1112 Basic
.singleton
['pi'] = Pi
1113 Basic
.singleton
['I'] = ImaginaryUnit
1114 Basic
.singleton
['oo'] = Infinity
1115 Basic
.singleton
['nan'] = NaN
1117 Basic
.singleton
['zoo'] = ComplexInfinity
1119 Basic
.singleton
['GoldenRatio'] = GoldenRatio
1120 Basic
.singleton
['EulerGamma'] = EulerGamma
1121 Basic
.singleton
['Catalan'] = Catalan