2 import sympy
.mpmath
as mpmath
3 import sympy
.mpmath
.lib
as mlib
4 import sympy
.mpmath
.libmpc
as mlibc
7 rnd
= mlib
.round_nearest
9 from basic
import Basic
, Atom
, S
, C
, SingletonMeta
, Memoizer
, MemoizerArg
10 from sympify
import _sympify
, SympifyError
, _sympifyit
11 from power
import integer_nthroot
13 # from mul import Mul /cyclic/
14 # from power import Pow /cyclic/
15 # from function import FunctionClass /cyclic/
20 # TODO caching with decorator, but not to degrade performance
22 """Computes integer greates common divisor of two numbers.
24 The algorithm is based on the well known Euclid's algorithm. To
25 improve speed igcd() has its own caching mechanizm implemented.
28 return _gcdcache
[(a
,b
)]
43 """Computes integer least common multiple of two numbers. """
47 return a
* b
/ igcd(a
, b
)
50 """Returns x, y, g such that g = x*a + y*b = gcd(a, b).
57 >>> x, y, g = igcdex(100, 2004)
64 if (not a
) and (not b
):
68 return (0, b
/abs(b
), abs(b
))
70 return (a
/abs(a
), 0, abs(a
))
82 x
, y
, r
, s
= 1, 0, 0, 1
85 (c
, q
) = (a
% b
, a
/ b
)
86 (a
, b
, r
, s
, x
, y
) = (b
, c
, x
-q
*r
, y
-q
*s
, r
, s
)
88 return (x
*x_sign
, y
*y_sign
, a
)
90 @Memoizer((int, long), return_value_converter
= lambda d
: d
.copy())
91 def factor_trial_division(n
):
93 Factor any integer into a product of primes, 0, 1, and -1.
94 Returns a dictionary {<prime: exponent>}.
113 while n
> 1 and d
*d
<= n
:
132 Represents any kind of number in sympy.
134 Floating point numbers are represented by the Real class.
135 Integer numbers (of any size), together with rational numbers (again, there
136 is no limit on their size) are represented by the Rational class.
138 If you want to represent for example 1+sqrt(2), then you need to do:
140 Rational(1) + sqrt(Rational(2))
142 is_commutative
= True
149 # Used to make max(x._prec, y._prec) return x._prec when only x is a float
154 def __new__(cls
, *obj
):
155 if len(obj
)==1: obj
=obj
[0]
156 if isinstance(obj
, (int, long)):
158 if isinstance(obj
,tuple) and len(obj
)==2:
159 return Rational(*obj
)
160 if isinstance(obj
, (str,float,mpmath
.mpf
,decimal
.Decimal
)):
162 if isinstance(obj
, Number
):
164 raise TypeError("expected str|int|long|float|Decimal|Number object but got %r" % (obj
))
166 def _as_mpf_val(self
, prec
):
167 """Evaluate to mpf tuple accurate to at least prec bits"""
168 raise NotImplementedError('%s needs ._as_mpf_val() method' % \
169 (self
.__class
__.__name
__))
171 def _eval_evalf(self
, prec
):
172 return Real
._new
(self
._as
_mpf
_val
(prec
), prec
)
174 def _as_mpf_op(self
, prec
):
175 prec
= max(prec
, self
._prec
)
176 return self
._as
_mpf
_val
(prec
), prec
179 return mlib
.to_float(self
._as
_mpf
_val
(53))
181 def _eval_derivative(self
, s
):
184 def _eval_conjugate(self
):
187 def _eval_order(self
, *symbols
):
188 # Order(5, x, y) -> Order(1,x,y)
189 return C
.Order(S
.One
, *symbols
)
191 def __eq__(self
, other
):
192 raise NotImplementedError('%s needs .__eq__() method' % (self
.__class
__.__name
__))
193 def __ne__(self
, other
):
194 raise NotImplementedError('%s needs .__ne__() method' % (self
.__class
__.__name
__))
195 def __lt__(self
, other
):
196 raise NotImplementedError('%s needs .__lt__() method' % (self
.__class
__.__name
__))
197 def __le__(self
, other
):
198 raise NotImplementedError('%s needs .__le__() method' % (self
.__class
__.__name
__))
200 def __gt__(self
, other
):
201 return _sympify(other
).__lt
__(self
)
202 def __ge__(self
, other
):
203 return _sympify(other
).__le
__(self
)
205 def as_coeff_terms(self
, x
=None):
212 Represents a floating point number. It is capable of representing
213 arbitrary-precision floating-point numbers
217 Real(3.5) .... 3.5 (the 3.5 was converted from a python float)
218 Real("3.0000000000000005")
222 - Real(x) with x being a Python int/long will return Integer(x)
225 is_irrational
= False
228 __slots__
= ['_mpf_', '_prec']
230 # mpz can't be pickled
231 def __getstate__(self
):
232 d
= Basic
.__getstate
__(self
).copy()
234 return mlib
.to_pickable(self
._mpf
_), d
236 def __setstate__(self
, state
):
238 _mpf_
= mlib
.from_pickable(_mpf_
)
240 Basic
.__setstate
__(self
, d
)
245 return C
.Integer(int(mlib
.to_int(mlib
.ffloor(self
._mpf
_, self
._prec
))))
248 return C
.Integer(int(mlib
.to_int(mlib
.fceil(self
._mpf
_, self
._prec
))))
252 return mpmath
.mpf(self
._mpf
_)
254 def _as_mpf_val(self
, prec
):
257 def _as_mpf_op(self
, prec
):
258 return self
._mpf
_, max(prec
, self
._prec
)
260 def __new__(cls
, num
, prec
=15):
261 prec
= mlib
.dps_to_prec(prec
)
262 if isinstance(num
, (int, long)):
264 if isinstance(num
, (str, decimal
.Decimal
)):
265 _mpf_
= mlib
.from_str(str(num
), prec
, rnd
)
266 elif isinstance(num
, tuple) and len(num
) == 4:
269 _mpf_
= mpmath
.mpf(num
)._mpf
_
272 obj
= Basic
.__new
__(cls
)
278 def _new(cls
, _mpf_
, _prec
):
279 if _mpf_
== mlib
.fzero
:
281 obj
= Basic
.__new
__(cls
)
286 def _hashable_content(self
):
287 return (self
._mpf
_, self
._prec
)
289 def _eval_is_positive(self
):
292 def _eval_is_negative(self
):
296 return Real
._new
(mlib
.fneg(self
._mpf
_), self
._prec
)
298 def __mul__(self
, other
):
300 other
= _sympify(other
)
302 return NotImplemented
303 if isinstance(other
, Number
):
304 rhs
, prec
= other
._as
_mpf
_op
(self
._prec
)
305 return Real
._new
(mlib
.fmul(self
._mpf
_, rhs
, prec
, rnd
), prec
)
306 return Number
.__mul
__(self
, other
)
308 def __add__(self
, other
):
310 other
= _sympify(other
)
312 return NotImplemented
313 if (other
is S
.NaN
) or (self
is NaN
):
315 if isinstance(other
, Number
):
316 rhs
, prec
= other
._as
_mpf
_op
(self
._prec
)
317 return Real
._new
(mlib
.fadd(self
._mpf
_, rhs
, prec
, rnd
), prec
)
318 return Number
.__add
__(self
, other
)
320 def _eval_power(b
, e
):
322 b is Real but not equal to rationals, integers, 0.5, oo, -oo, nan
323 e is symbolic object but not equal to 0, 1
325 (-p) ** r -> exp(r * log(-p)) -> exp(r * (log(p) + I*Pi)) ->
326 -> p ** r * (sin(Pi*r) + cos(Pi*r) * I)
328 if isinstance(e
, Number
):
329 if isinstance(e
, Integer
):
331 return Real
._new
(mlib
.fpowi(b
._mpf
_, e
.p
, prec
, rnd
), prec
)
332 e
, prec
= e
._as
_mpf
_op
(b
._prec
)
335 y
= mlib
.fpow(b
, e
, prec
, rnd
)
336 return Real
._new
(y
, prec
)
337 except mlib
.ComplexResult
:
338 re
, im
= mlibc
.mpc_pow((b
, mlib
.fzero
), (e
, mlib
.fzero
), prec
, rnd
)
339 return Real
._new
(re
, prec
) + Real
._new
(im
, prec
) * S
.ImaginaryUnit
342 return Real
._new
(mlib
.fabs(self
._mpf
_), self
._prec
)
345 return int(mlib
.to_int(self
._mpf
_))
347 def __eq__(self
, other
):
349 other
= _sympify(other
)
351 return False # sympy != other --> not ==
352 if isinstance(other
, NumberSymbol
):
353 if other
.is_irrational
: return False
354 return other
.__eq
__(self
)
355 if other
.is_comparable
: other
= other
.evalf()
356 if isinstance(other
, Number
):
357 return bool(mlib
.feq(self
._mpf
_, other
._as
_mpf
_val
(self
._prec
)))
358 return False # Real != non-Number
360 def __ne__(self
, other
):
362 other
= _sympify(other
)
364 return True # sympy != other
365 if isinstance(other
, NumberSymbol
):
366 if other
.is_irrational
: return True
367 return other
.__ne
__(self
)
368 if other
.is_comparable
: other
= other
.evalf()
369 if isinstance(other
, Number
):
370 return bool(not mlib
.feq(self
._mpf
_, other
._as
_mpf
_val
(self
._prec
)))
371 return True # Real != non-Number
373 def __lt__(self
, other
):
375 other
= _sympify(other
)
377 return False # sympy > other
378 if isinstance(other
, NumberSymbol
):
379 return other
.__ge
__(self
)
380 if other
.is_comparable
: other
= other
.evalf()
381 if isinstance(other
, Number
):
382 return bool(mlib
.flt(self
._mpf
_, other
._as
_mpf
_val
(self
._prec
)))
383 return Basic
.__lt
__(self
, other
)
385 def __le__(self
, other
):
387 other
= _sympify(other
)
389 return False # sympy > other --> ! <=
390 if isinstance(other
, NumberSymbol
):
391 return other
.__gt
__(self
)
392 if other
.is_comparable
: other
= other
.evalf()
393 if isinstance(other
, Number
):
394 return bool(mlib
.fle(self
._mpf
_, other
._as
_mpf
_val
(self
._prec
)))
395 return Basic
.__le
__(self
, other
)
397 def epsilon_eq(self
, other
, epsilon
="10e-16"):
398 return abs(self
- other
) < Real(epsilon
)
400 # this is here to work nicely in Sage
404 def _parse_rational(s
):
405 """Parse rational number from string representation"""
409 return int(p
), int(q
)
416 s
, periodic
= s
.split("[")
417 periodic
= periodic
.rstrip("]")
418 offset
= len(s
) - s
.index(".") - 1
420 n2
= int("9" * len(periodic
))
421 r
= Rational(*_parse_rational(s
)) + Rational(n1
, n2
*10**offset
)
423 # Ordinary decimal string. Use the Decimal class's built-in parser
425 sign
, digits
, expt
= decimal
.Decimal(s
).as_tuple()
426 p
= (1, -1)[sign
] * int("".join(str(x
) for x
in digits
))
428 return p
*(10**expt
), 1
433 class Rational(Number
):
434 """Represents integers and rational numbers (p/q) of any size.
443 You can create a rational from a string:
449 Use square brackets to indicate a recurring decimal:
450 >>> Rational("0.[333]")
452 >>> Rational("1.2[05]")
454 >>> float(Rational(1193,990))
461 Access nominator and denominator as .p and .q:
462 >>> r = Rational(3,4)
474 __slots__
= ['p', 'q']
478 @Memoizer(type, (int, long, str), MemoizerArg((int, long, type(None)), name
="q"))
479 def __new__(cls
, p
, q
= None):
481 if isinstance(p
, str):
482 p
, q
= _parse_rational(p
)
486 if p
==0: return S
.NaN
487 if p
<0: return S
.NegativeInfinity
496 if q
==1: return Integer(p
)
497 if p
==1 and q
==2: return S
.Half
498 obj
= Basic
.__new
__(cls
)
504 def _hashable_content(self
):
505 return (self
.p
, self
.q
)
507 def _eval_is_positive(self
):
510 def _eval_is_zero(self
):
513 def __neg__(self
): return Rational(-self
.p
, self
.q
)
515 @_sympifyit('other', NotImplemented)
516 def __mul__(self
, other
):
517 if (other
is S
.NaN
) or (self
is S
.NaN
):
519 if isinstance(other
, Real
):
521 if isinstance(other
, Rational
):
522 return Rational(self
.p
* other
.p
, self
.q
* other
.q
)
523 return Number
.__mul
__(self
, other
)
526 @_sympifyit('other', NotImplemented)
527 def __add__(self
, other
):
528 if (other
is S
.NaN
) or (self
is S
.NaN
):
530 if isinstance(other
, Real
):
532 if isinstance(other
, Rational
):
533 if self
.is_unbounded
:
539 if other
.is_unbounded
:
541 return Rational(self
.p
* other
.q
+ self
.q
* other
.p
, self
.q
* other
.q
)
542 return Number
.__add
__(self
, other
)
544 def _eval_power(b
, e
):
545 if isinstance(e
, Number
):
546 if (e
is S
.NaN
): return S
.NaN
547 if isinstance(e
, Real
):
548 return b
._eval
_evalf
(e
._prec
) ** e
550 # (3/4)**-2 -> (4/3)**2
553 return Rational(b
.q
, b
.p
)
554 return Rational(b
.q
, b
.p
) ** ne
555 if (e
is S
.Infinity
):
560 # (-3/2)**oo -> oo + I*oo
561 return S
.Infinity
+ S
.Infinity
* S
.ImaginaryUnit
563 if isinstance(e
, Integer
):
564 # (4/3)**2 -> 4**2 / 3**2
565 return Rational(b
.p
** e
.p
, b
.q
** e
.p
)
566 if isinstance(e
, Rational
):
568 # (4/3)**(5/6) -> 4**(5/6) * 3**(-5/6)
569 return Integer(b
.p
) ** e
* Integer(b
.q
) ** (-e
)
571 return Integer(b
.q
)**Rational(e
.p
* (e
.q
-1), e
.q
) / ( Integer(b
.q
) ** Integer(e
.p
))
573 return (-1)**e
* (-b
)**e
575 c
,t
= b
.as_coeff_terms()
576 if e
.is_even
and isinstance(c
, Number
) and c
< 0:
577 return (-c
* Mul(*t
)) ** e
581 def _as_mpf_val(self
, prec
):
582 return mlib
.from_rational(self
.p
, self
.q
, prec
, rnd
)
585 return Rational(abs(self
.p
), self
.q
)
588 return int(self
.p
//self
.q
)
590 def __eq__(self
, other
):
592 other
= _sympify(other
)
594 return False # sympy != other --> not ==
595 if isinstance(other
, NumberSymbol
):
596 if other
.is_irrational
: return False
597 return other
.__eq
__(self
)
598 if isinstance(self
, Number
) and isinstance(other
, FunctionClass
):
600 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
601 if isinstance(other
, Number
):
602 if isinstance(other
, Real
):
603 return bool(mlib
.feq(self
._as
_mpf
_val
(other
._prec
), other
._mpf
_))
604 return bool(self
.p
==other
.p
and self
.q
==other
.q
)
606 return False # Rational != non-Number
608 def __ne__(self
, other
):
610 other
= _sympify(other
)
612 return True # sympy != other
613 if isinstance(other
, NumberSymbol
):
614 if other
.is_irrational
: return True
615 return other
.__ne
__(self
)
616 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
617 if isinstance(other
, Number
):
618 if isinstance(other
, Real
):
619 return bool(not mlib
.feq(self
._as
_mpf
_val
(other
._prec
), other
._mpf
_))
620 return bool(self
.p
!=other
.p
or self
.q
!=other
.q
)
622 return True # Rational != non-Number
624 def __lt__(self
, other
):
626 other
= _sympify(other
)
628 return False # sympy > other --> not <
629 if isinstance(other
, NumberSymbol
):
630 return other
.__ge
__(self
)
631 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
632 if isinstance(other
, Number
):
633 if isinstance(other
, Real
):
634 return bool(mlib
.flt(self
._as
_mpf
_val
(other
._prec
), other
._mpf
_))
635 return bool(self
.p
* other
.q
< self
.q
* other
.p
)
636 return Basic
.__lt
__(self
, other
)
638 def __le__(self
, other
):
640 other
= _sympify(other
)
642 return False # sympy > other --> not <=
643 if isinstance(other
, NumberSymbol
):
644 return other
.__gt
__(self
)
645 if other
.is_comparable
and not isinstance(other
, Rational
): other
= other
.evalf()
646 if isinstance(other
, Number
):
647 if isinstance(other
, Real
):
648 return bool(mlib
.fle(self
._as
_mpf
_val
(other
._prec
), other
._mpf
_))
649 return bool(self
.p
* other
.q
<= self
.q
* other
.p
)
650 return Basic
.__le
__(self
, other
)
653 f
= factor_trial_division(self
.p
).copy()
654 for p
,e
in factor_trial_division(self
.q
).items():
656 except KeyError: f
[p
] = -e
658 if len(f
)>1 and f
.has_key(1): del f
[1]
661 def as_numer_denom(self
):
662 return Integer(self
.p
), Integer(self
.q
)
665 import sage
.all
as sage
666 #XXX: fixme, this should work:
667 #return sage.Integer(self[0])/sage.Integer(self[1])
668 return sage
.Integer(self
.p
)/sage
.Integer(self
.q
)
674 # TODO move this tracing facility to sympy/core/trace.py ?
675 def _intcache_printinfo():
676 ints
= sorted(_intcache
.keys())
677 nhit
= _intcache_hits
678 nmiss
= _intcache_misses
680 if nhit
== 0 and nmiss
== 0:
682 print 'Integer cache statistic was not collected'
685 miss_ratio
= float(nmiss
) / (nhit
+nmiss
)
688 print 'Integer cache statistic'
689 print '-----------------------'
691 print '#items: %i' % len(ints
)
693 print ' #hit #miss #total'
695 print '%5i %5i (%7.5f %%) %5i' % (nhit
, nmiss
, miss_ratio
*100, nhit
+nmiss
)
704 if os
.getenv('SYMPY_TRACE_INT', 'no').lower() != 'yes':
707 def Integer_tracer(cls
, i
):
708 global _intcache_hits
, _intcache_misses
715 _intcache_misses
+= 1
720 # also we want to hook our _intcache_printinfo into sys.atexit
722 atexit
.register(_intcache_printinfo
)
724 return Integer_tracer
729 class Integer(Rational
):
738 def _as_mpf_val(self
, prec
):
739 return mlib
.from_int(self
.p
)
741 # TODO caching with decorator, but not to degrade performance
747 # The most often situation is when Integers are created from Python
749 if isinstance(i
, (int, long)):
750 obj
= Basic
.__new
__(cls
)
755 # Also, we seldomly need the following to work:
756 # UC: Integer(Integer(4)) <-- sympify('4')
761 raise ValueError('invalid argument for Integer: %r' % (i
,))
763 # Arithmetic operations are here for efficiency
768 return Integer(-self
.p
)
774 return Integer(-self
.p
)
776 # TODO make it decorator + bytecodehacks?
779 return Integer(a
.p
+ b
)
780 elif isinstance(b
, Integer
):
781 return Integer(a
.p
+ b
.p
)
782 return Rational
.__add
__(a
, b
) # a,b -not- b,a
786 return Integer(b
+ a
.p
)
787 elif isinstance(b
, Integer
):
788 return Integer(b
.p
+ a
.p
)
789 return Rational
.__add
__(a
, b
)
793 return Integer(a
.p
- b
)
794 elif isinstance(b
, Integer
):
795 return Integer(a
.p
- b
.p
)
796 return Rational
.__sub
__(a
, b
)
800 return Integer(b
- a
.p
)
801 elif isinstance(b
, Integer
):
802 return Integer(b
.p
- a
.p
)
803 return Rational
.__rsub
__(a
, b
)
807 return Integer(a
.p
* b
)
808 elif isinstance(b
, Integer
):
809 return Integer(a
.p
* b
.p
)
810 return Rational
.__mul
__(a
, b
)
814 return Integer(b
* a
.p
)
815 elif isinstance(b
, Integer
):
816 return Integer(b
.p
* a
.p
)
817 return Rational
.__mul
__(a
, b
)
821 # XXX do we need to define __cmp__ ?
827 elif isinstance(b
, Integer
):
829 return Rational
.__eq
__(a
, b
)
834 elif isinstance(b
, Integer
):
836 return Rational
.__ne
__(a
, b
)
841 elif isinstance(b
, Integer
):
843 return Rational
.__gt
__(a
, b
)
848 elif isinstance(b
, Integer
):
850 return Rational
.__lt
__(a
, b
)
855 elif isinstance(b
, Integer
):
857 return Rational
.__ge
__(a
, b
)
862 elif isinstance(b
, Integer
):
864 return Rational
.__le
__(a
, b
)
866 ########################################
868 def _eval_is_odd(self
):
869 return bool(self
.p
% 2)
871 def _eval_power(b
, e
):
872 if isinstance(e
, Number
):
873 if e
is S
.NaN
: return S
.NaN
874 if isinstance(e
, Real
):
875 return b
._eval
_evalf
(e
._prec
) ** e
877 # (3/4)**-2 -> (4/3)**2
880 return Rational(1, b
.p
)
881 return Rational(1, b
.p
) ** ne
887 # (-3)**oo -> oo + I*oo
888 return S
.Infinity
+ S
.Infinity
* S
.ImaginaryUnit
890 if isinstance(e
, Integer
):
891 # (4/3)**2 -> 4**2 / 3**2
892 return Integer(b
.p
** e
.p
)
893 if isinstance(e
, Rational
):
894 if b
== -1: # any one has tested this ???
895 # calculate the roots of -1
898 r
= cos(pi
/e
.q
) + S
.ImaginaryUnit
*sin(pi
/e
.q
)
901 x
, xexact
= integer_nthroot(b
.p
, e
.q
)
903 res
= Integer(x
** abs(e
.p
))
909 if b
> 2**32: #Prevent from factorizing too big integers:
910 for i
in xrange(2, e
.q
/2 + 1): #OLD CODE
912 x
, xexact
= integer_nthroot(b
.p
, i
)
914 return Integer(x
)**(e
* i
)
915 # Try to get some part of the base out, if exponent > 1
919 return b
**i
* b
**Rational(r
, e
.q
)
931 for prime
,exponent
in dict.iteritems():
933 div_e
= exponent
/ e
.q
934 div_m
= exponent
% e
.q
937 out_int
*= prime
**div_e
939 sqr_dict
[prime
] = div_m
941 for p
,ex
in sqr_dict
.iteritems():
945 sqr_gcd
= igcd(sqr_gcd
, ex
)
947 for k
,v
in sqr_dict
.iteritems():
948 sqr_int
*= k
**(v
/sqr_gcd
)
950 if sqr_int
== b
.p
and out_int
== 1:
953 return out_int
* Pow(sqr_int
, Rational(sqr_gcd
, e
.q
))
956 return S
.ImaginaryUnit
** e
.p
* (-b
)**e
960 c
,t
= b
.as_coeff_terms()
961 if e
.is_even
and isinstance(c
, Number
) and c
< 0:
962 return (-c
* Mul(*t
)) ** e
966 def _eval_is_prime(self
):
970 def as_numer_denom(self
):
973 def __floordiv__(self
, other
):
974 return Integer(self
.p
// Integer(other
).p
)
976 def __rfloordiv__(self
, other
):
977 return Integer(Integer(other
).p
// self
.p
)
980 __metaclass__
= SingletonMeta
1001 def _eval_power(b
, e
):
1007 if isinstance(d
, Number
):
1011 coeff
, terms
= e
.as_coeff_terms()
1012 if coeff
.is_negative
:
1013 return S
.Infinity
** Mul(*terms
)
1014 if coeff
is not S
.One
:
1015 return b
** Mul(*terms
)
1017 def _eval_order(self
, *symbols
):
1022 __metaclass__
= SingletonMeta
1031 def _eval_evalf(self
, prec
):
1040 return S
.NegativeOne
1042 def _eval_power(b
, e
):
1045 def _eval_order(self
, *symbols
):
1052 class NegativeOne(Integer
):
1053 __metaclass__
= SingletonMeta
1060 def _eval_evalf(self
, prec
):
1071 def _eval_power(b
, e
):
1072 if e
.is_odd
: return S
.NegativeOne
1073 if e
.is_even
: return S
.One
1074 if isinstance(e
, Number
):
1075 if isinstance(e
, Real
):
1076 return Real(-1.0) ** e
1079 if e
is S
.Infinity
or e
is S
.NegativeInfinity
:
1082 return S
.ImaginaryUnit
1083 if isinstance(e
, Rational
):
1085 return S
.ImaginaryUnit
** Integer(e
.p
)
1089 return b
** q
* b
** (e
- q
)
1092 class Half(Rational
):
1093 __metaclass__
= SingletonMeta
1105 class Infinity(Rational
):
1106 __metaclass__
= SingletonMeta
1113 is_commutative
= True
1117 is_infinitesimal
= False
1128 return S
.NegativeInfinity
1130 def _eval_power(b
, e
):
1132 e is symbolic object but not equal to 0, 1
1135 oo ** (-p) -> 0, p is number, oo
1141 if isinstance(e
, Number
):
1145 if isinstance(d
, Number
):
1149 def _as_mpf_val(self
, prec
):
1153 import sage
.all
as sage
1156 class NegativeInfinity(Rational
):
1157 __metaclass__
= SingletonMeta
1164 is_commutative
= True
1169 is_infinitesimal
= False
1181 def _eval_power(b
, e
):
1183 e is symbolic object but not equal to 0, 1
1187 (-oo) ** (-oo) -> nan
1188 (-oo) ** e -> oo, e is positive even integer
1189 (-oo) ** o -> -oo, o is positive odd integer
1192 if isinstance(e
, Number
):
1193 if (e
is S
.NaN
) or (e
is S
.Infinity
) or (e
is S
.NegativeInfinity
):
1195 if isinstance(e
, Integer
):
1198 return S
.NegativeInfinity
1200 return S
.NegativeOne
**e
* S
.Infinity
** e
1203 def _as_mpf_val(self
, prec
):
1206 class NaN(Rational
):
1207 __metaclass__
= SingletonMeta
1212 is_commutative
= True
1216 is_comparable
= False
1219 #is_unbounded = False
1226 def _as_mpf_val(self
, prec
):
1229 def _eval_power(b
, e
):
1235 import sage
.all
as sage
1238 class ComplexInfinity(Atom
):
1239 __metaclass__
= SingletonMeta
1241 is_commutative
= True
1242 is_comparable
= None
1254 return S
.ComplexInfinity
1256 def _eval_power(b
, e
):
1257 if e
is S
.ComplexInfinity
:
1260 if isinstance(e
, Number
):
1265 return S
.ComplexInfinity
1269 class NumberSymbol(Atom
):
1270 __metaclass__
= SingletonMeta
1272 is_commutative
= True
1273 is_comparable
= True
1279 is_NumberSymbol
= True
1281 def approximation(self
, number_cls
):
1282 """ Return an interval with number_cls endpoints
1283 that contains the value of NumberSymbol.
1284 If not implemented, then return None.
1287 def _eval_evalf(self
, prec
):
1288 return Real
._new
(self
._as
_mpf
_val
(prec
), prec
)
1290 def _eval_derivative(self
, s
):
1293 def __eq__(self
, other
):
1295 other
= _sympify(other
)
1296 except SympifyError
:
1297 return False # sympy != other --> not ==
1298 if self
is other
: return True
1299 if isinstance(other
, Number
) and self
.is_irrational
: return False
1301 return False # NumberSymbol != non-(Number|self)
1303 def __ne__(self
, other
):
1305 other
= _sympify(other
)
1306 except SympifyError
:
1307 return True # sympy != other
1308 if self
is other
: return False
1309 if isinstance(other
, Number
) and self
.is_irrational
: return True
1311 return True # NumberSymbol != non(Number|self)
1313 def __lt__(self
, other
):
1315 other
= _sympify(other
)
1316 except SympifyError
:
1317 return False # sympy > other --> not <
1318 if self
is other
: return False
1319 if isinstance(other
, Number
):
1320 approx
= self
.approximation_interval(other
.__class
__)
1321 if approx
is not None:
1323 if other
< l
: return False
1324 if other
> u
: return True
1325 return self
.evalf()<other
1326 if other
.is_comparable
:
1327 other
= other
.evalf()
1328 return self
.evalf()<other
1329 return Basic
.__lt
__(self
, other
)
1330 def __le__(self
, other
):
1332 other
= _sympify(other
)
1333 except SympifyError
:
1334 return False # sympy > other --> not <=
1335 if self
is other
: return True
1336 if other
.is_comparable
: other
= other
.evalf()
1337 if isinstance(other
, Number
):
1338 return self
.evalf()<=other
1339 return Basic
.__le
__(self
, other
)
1340 def __gt__(self
, other
):
1341 return (-self
) < (-other
)
1342 def __ge__(self
, other
):
1343 return (-self
) <= (-other
)
1346 class Exp1(NumberSymbol
):
1350 is_negative
= False # XXX Forces is_negative/is_nonnegative
1351 is_irrational
= True
1359 def _as_mpf_val(self
, prec
):
1360 return mlib
.fe(prec
)
1362 def approximation_interval(self
, number_cls
):
1363 if issubclass(number_cls
,Integer
):
1364 return (Integer(2),Integer(3))
1365 elif issubclass(number_cls
,Rational
):
1368 def _eval_power(self
, exp
):
1372 import sage
.all
as sage
1375 class Pi(NumberSymbol
):
1380 is_irrational
= True
1388 def _as_mpf_val(self
, prec
):
1389 return mlib
.fpi(prec
)
1391 def approximation_interval(self
, number_cls
):
1392 if issubclass(number_cls
, Integer
):
1393 return (Integer(3), Integer(4))
1394 elif issubclass(number_cls
, Rational
):
1395 return (Rational(223,71), Rational(22,7))
1398 import sage
.all
as sage
1401 class GoldenRatio(NumberSymbol
):
1406 is_irrational
= True
1410 def _as_mpf_val(self
, prec
):
1411 return mlib
.from_man_exp(mpmath
.specfun
.phi_fixed(prec
+10), -prec
-10)
1413 def _eval_expand_func(self
, *args
):
1414 return S
.Half
+ S
.Half
*S
.Sqrt(5)
1416 def approximation_interval(self
, number_cls
):
1417 if issubclass(number_cls
, Integer
):
1418 return (S
.One
, Rational(2))
1419 elif issubclass(number_cls
, Rational
):
1423 import sage
.all
as sage
1424 return sage
.golden_ratio
1426 class EulerGamma(NumberSymbol
):
1431 is_irrational
= None
1435 def _as_mpf_val(self
, prec
):
1436 return mlib
.from_man_exp(mpmath
.specfun
.euler_fixed(prec
+10), -prec
-10)
1438 def approximation_interval(self
, number_cls
):
1439 if issubclass(number_cls
, Integer
):
1440 return (S
.Zero
, S
.One
)
1441 elif issubclass(number_cls
, Rational
):
1442 return (S
.Half
, Rational(3, 5))
1445 import sage
.all
as sage
1446 return sage
.euler_gamma
1448 class Catalan(NumberSymbol
):
1453 is_irrational
= None
1457 def _as_mpf_val(self
, prec
):
1458 return mlib
.from_man_exp(mpmath
.specfun
.catalan_fixed(prec
+10), -prec
-10)
1460 def approximation_interval(self
, number_cls
):
1461 if issubclass(number_cls
, Integer
):
1462 return (S
.Zero
, S
.One
)
1463 elif issubclass(number_cls
, Rational
):
1464 return (Rational(9, 10), S
.One
)
1467 import sage
.all
as sage
1470 class ImaginaryUnit(Atom
):
1471 __metaclass__
= SingletonMeta
1473 is_commutative
= True
1484 def _eval_evalf(self
, prec
):
1487 def _eval_conjugate(self
):
1488 return -S
.ImaginaryUnit
1490 def _eval_derivative(self
, s
):
1493 def _eval_power(b
, e
):
1496 e is symbolic object but not equal to 0, 1
1498 I ** r -> (-1)**(r/2) -> exp(r/2 * Pi * I) -> sin(Pi*r/2) + cos(Pi*r/2) * I, r is decimal
1506 if isinstance(e
, Number
):
1507 #if isinstance(e, Decimal):
1508 # a = decimal_math.pi() * exponent.num / 2
1509 # return Decimal(decimal_math.sin(a) + decimal_math.cos(a) * ImaginaryUnit())
1510 if isinstance(e
, Integer
):
1512 if e
==0: return S
.One
1513 if e
==1: return S
.ImaginaryUnit
1514 if e
==2: return -S
.One
1515 return -S
.ImaginaryUnit
1516 return (-S
.One
) ** (e
* S
.Half
)
1519 def as_base_exp(self
):
1520 return -S
.One
, S
.Half
1523 import sage
.all
as sage
1530 _
.Rational
= Rational
1546 _
.Rational
= Rational
1557 _intcache
[0] = S
.Zero
1558 _intcache
[1] = S
.One
1559 _intcache
[-1]= S
.NegativeOne
1561 Basic
.singleton
['E'] = Exp1
1562 Basic
.singleton
['pi'] = Pi
1563 Basic
.singleton
['I'] = ImaginaryUnit
1564 Basic
.singleton
['oo'] = Infinity
1565 Basic
.singleton
['nan'] = NaN
1567 Basic
.singleton
['zoo'] = ComplexInfinity
1569 Basic
.singleton
['GoldenRatio'] = GoldenRatio
1570 Basic
.singleton
['EulerGamma'] = EulerGamma
1571 Basic
.singleton
['Catalan'] = Catalan