Coverage for /usr/lib/python3/dist-packages/sympy/core/numbers.py: 48%
2280 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1from __future__ import annotations
3import numbers
4import decimal
5import fractions
6import math
7import re as regex
8import sys
9from functools import lru_cache
11from .containers import Tuple
12from .sympify import (SympifyError, _sympy_converter, sympify, _convert_numpy_types,
13 _sympify, _is_numpy_instance)
14from .singleton import S, Singleton
15from .basic import Basic
16from .expr import Expr, AtomicExpr
17from .evalf import pure_complex
18from .cache import cacheit, clear_cache
19from .decorators import _sympifyit
20from .logic import fuzzy_not
21from .kind import NumberKind
22from sympy.external.gmpy import SYMPY_INTS, HAS_GMPY, gmpy
23from sympy.multipledispatch import dispatch
24import mpmath
25import mpmath.libmp as mlib
26from mpmath.libmp import bitcount, round_nearest as rnd
27from mpmath.libmp.backend import MPZ
28from mpmath.libmp import mpf_pow, mpf_pi, mpf_e, phi_fixed
29from mpmath.ctx_mp import mpnumeric
30from mpmath.libmp.libmpf import (
31 finf as _mpf_inf, fninf as _mpf_ninf,
32 fnan as _mpf_nan, fzero, _normalize as mpf_normalize,
33 prec_to_dps, dps_to_prec)
34from sympy.utilities.misc import as_int, debug, filldedent
35from .parameters import global_parameters
37_LOG2 = math.log(2)
40def comp(z1, z2, tol=None):
41 r"""Return a bool indicating whether the error between z1 and z2
42 is $\le$ ``tol``.
44 Examples
45 ========
47 If ``tol`` is ``None`` then ``True`` will be returned if
48 :math:`|z1 - z2|\times 10^p \le 5` where $p$ is minimum value of the
49 decimal precision of each value.
51 >>> from sympy import comp, pi
52 >>> pi4 = pi.n(4); pi4
53 3.142
54 >>> comp(_, 3.142)
55 True
56 >>> comp(pi4, 3.141)
57 False
58 >>> comp(pi4, 3.143)
59 False
61 A comparison of strings will be made
62 if ``z1`` is a Number and ``z2`` is a string or ``tol`` is ''.
64 >>> comp(pi4, 3.1415)
65 True
66 >>> comp(pi4, 3.1415, '')
67 False
69 When ``tol`` is provided and $z2$ is non-zero and
70 :math:`|z1| > 1` the error is normalized by :math:`|z1|`:
72 >>> abs(pi4 - 3.14)/pi4
73 0.000509791731426756
74 >>> comp(pi4, 3.14, .001) # difference less than 0.1%
75 True
76 >>> comp(pi4, 3.14, .0005) # difference less than 0.1%
77 False
79 When :math:`|z1| \le 1` the absolute error is used:
81 >>> 1/pi4
82 0.3183
83 >>> abs(1/pi4 - 0.3183)/(1/pi4)
84 3.07371499106316e-5
85 >>> abs(1/pi4 - 0.3183)
86 9.78393554684764e-6
87 >>> comp(1/pi4, 0.3183, 1e-5)
88 True
90 To see if the absolute error between ``z1`` and ``z2`` is less
91 than or equal to ``tol``, call this as ``comp(z1 - z2, 0, tol)``
92 or ``comp(z1 - z2, tol=tol)``:
94 >>> abs(pi4 - 3.14)
95 0.00160156249999988
96 >>> comp(pi4 - 3.14, 0, .002)
97 True
98 >>> comp(pi4 - 3.14, 0, .001)
99 False
100 """
101 if isinstance(z2, str):
102 if not pure_complex(z1, or_real=True):
103 raise ValueError('when z2 is a str z1 must be a Number')
104 return str(z1) == z2
105 if not z1:
106 z1, z2 = z2, z1
107 if not z1:
108 return True
109 if not tol:
110 a, b = z1, z2
111 if tol == '':
112 return str(a) == str(b)
113 if tol is None:
114 a, b = sympify(a), sympify(b)
115 if not all(i.is_number for i in (a, b)):
116 raise ValueError('expecting 2 numbers')
117 fa = a.atoms(Float)
118 fb = b.atoms(Float)
119 if not fa and not fb:
120 # no floats -- compare exactly
121 return a == b
122 # get a to be pure_complex
123 for _ in range(2):
124 ca = pure_complex(a, or_real=True)
125 if not ca:
126 if fa:
127 a = a.n(prec_to_dps(min([i._prec for i in fa])))
128 ca = pure_complex(a, or_real=True)
129 break
130 else:
131 fa, fb = fb, fa
132 a, b = b, a
133 cb = pure_complex(b)
134 if not cb and fb:
135 b = b.n(prec_to_dps(min([i._prec for i in fb])))
136 cb = pure_complex(b, or_real=True)
137 if ca and cb and (ca[1] or cb[1]):
138 return all(comp(i, j) for i, j in zip(ca, cb))
139 tol = 10**prec_to_dps(min(a._prec, getattr(b, '_prec', a._prec)))
140 return int(abs(a - b)*tol) <= 5
141 diff = abs(z1 - z2)
142 az1 = abs(z1)
143 if z2 and az1 > 1:
144 return diff/az1 <= tol
145 else:
146 return diff <= tol
149def mpf_norm(mpf, prec):
150 """Return the mpf tuple normalized appropriately for the indicated
151 precision after doing a check to see if zero should be returned or
152 not when the mantissa is 0. ``mpf_normlize`` always assumes that this
153 is zero, but it may not be since the mantissa for mpf's values "+inf",
154 "-inf" and "nan" have a mantissa of zero, too.
156 Note: this is not intended to validate a given mpf tuple, so sending
157 mpf tuples that were not created by mpmath may produce bad results. This
158 is only a wrapper to ``mpf_normalize`` which provides the check for non-
159 zero mpfs that have a 0 for the mantissa.
160 """
161 sign, man, expt, bc = mpf
162 if not man:
163 # hack for mpf_normalize which does not do this;
164 # it assumes that if man is zero the result is 0
165 # (see issue 6639)
166 if not bc:
167 return fzero
168 else:
169 # don't change anything; this should already
170 # be a well formed mpf tuple
171 return mpf
173 # Necessary if mpmath is using the gmpy backend
174 from mpmath.libmp.backend import MPZ
175 rv = mpf_normalize(sign, MPZ(man), expt, bc, prec, rnd)
176 return rv
178# TODO: we should use the warnings module
179_errdict = {"divide": False}
182def seterr(divide=False):
183 """
184 Should SymPy raise an exception on 0/0 or return a nan?
186 divide == True .... raise an exception
187 divide == False ... return nan
188 """
189 if _errdict["divide"] != divide:
190 clear_cache()
191 _errdict["divide"] = divide
194def _as_integer_ratio(p):
195 neg_pow, man, expt, _ = getattr(p, '_mpf_', mpmath.mpf(p)._mpf_)
196 p = [1, -1][neg_pow % 2]*man
197 if expt < 0:
198 q = 2**-expt
199 else:
200 q = 1
201 p *= 2**expt
202 return int(p), int(q)
205def _decimal_to_Rational_prec(dec):
206 """Convert an ordinary decimal instance to a Rational."""
207 if not dec.is_finite():
208 raise TypeError("dec must be finite, got %s." % dec)
209 s, d, e = dec.as_tuple()
210 prec = len(d)
211 if e >= 0: # it's an integer
212 rv = Integer(int(dec))
213 else:
214 s = (-1)**s
215 d = sum([di*10**i for i, di in enumerate(reversed(d))])
216 rv = Rational(s*d, 10**-e)
217 return rv, prec
220_floatpat = regex.compile(r"[-+]?((\d*\.\d+)|(\d+\.?))")
221def _literal_float(f):
222 """Return True if n starts like a floating point number."""
223 return bool(_floatpat.match(f))
225# (a,b) -> gcd(a,b)
227# TODO caching with decorator, but not to degrade performance
229@lru_cache(1024)
230def igcd(*args):
231 """Computes nonnegative integer greatest common divisor.
233 Explanation
234 ===========
236 The algorithm is based on the well known Euclid's algorithm [1]_. To
237 improve speed, ``igcd()`` has its own caching mechanism.
239 Examples
240 ========
242 >>> from sympy import igcd
243 >>> igcd(2, 4)
244 2
245 >>> igcd(5, 10, 15)
246 5
248 References
249 ==========
251 .. [1] https://en.wikipedia.org/wiki/Euclidean_algorithm
253 """
254 if len(args) < 2:
255 raise TypeError(
256 'igcd() takes at least 2 arguments (%s given)' % len(args))
257 args_temp = [abs(as_int(i)) for i in args]
258 if 1 in args_temp:
259 return 1
260 a = args_temp.pop()
261 if HAS_GMPY: # Using gmpy if present to speed up.
262 for b in args_temp:
263 a = gmpy.gcd(a, b) if b else a
264 return as_int(a)
265 for b in args_temp:
266 a = math.gcd(a, b)
267 return a
270igcd2 = math.gcd
273def igcd_lehmer(a, b):
274 r"""Computes greatest common divisor of two integers.
276 Explanation
277 ===========
279 Euclid's algorithm for the computation of the greatest
280 common divisor ``gcd(a, b)`` of two (positive) integers
281 $a$ and $b$ is based on the division identity
282 $$ a = q \times b + r$$,
283 where the quotient $q$ and the remainder $r$ are integers
284 and $0 \le r < b$. Then each common divisor of $a$ and $b$
285 divides $r$, and it follows that ``gcd(a, b) == gcd(b, r)``.
286 The algorithm works by constructing the sequence
287 r0, r1, r2, ..., where r0 = a, r1 = b, and each rn
288 is the remainder from the division of the two preceding
289 elements.
291 In Python, ``q = a // b`` and ``r = a % b`` are obtained by the
292 floor division and the remainder operations, respectively.
293 These are the most expensive arithmetic operations, especially
294 for large a and b.
296 Lehmer's algorithm [1]_ is based on the observation that the quotients
297 ``qn = r(n-1) // rn`` are in general small integers even
298 when a and b are very large. Hence the quotients can be
299 usually determined from a relatively small number of most
300 significant bits.
302 The efficiency of the algorithm is further enhanced by not
303 computing each long remainder in Euclid's sequence. The remainders
304 are linear combinations of a and b with integer coefficients
305 derived from the quotients. The coefficients can be computed
306 as far as the quotients can be determined from the chosen
307 most significant parts of a and b. Only then a new pair of
308 consecutive remainders is computed and the algorithm starts
309 anew with this pair.
311 References
312 ==========
314 .. [1] https://en.wikipedia.org/wiki/Lehmer%27s_GCD_algorithm
316 """
317 a, b = abs(as_int(a)), abs(as_int(b))
318 if a < b:
319 a, b = b, a
321 # The algorithm works by using one or two digit division
322 # whenever possible. The outer loop will replace the
323 # pair (a, b) with a pair of shorter consecutive elements
324 # of the Euclidean gcd sequence until a and b
325 # fit into two Python (long) int digits.
326 nbits = 2*sys.int_info.bits_per_digit
328 while a.bit_length() > nbits and b != 0:
329 # Quotients are mostly small integers that can
330 # be determined from most significant bits.
331 n = a.bit_length() - nbits
332 x, y = int(a >> n), int(b >> n) # most significant bits
334 # Elements of the Euclidean gcd sequence are linear
335 # combinations of a and b with integer coefficients.
336 # Compute the coefficients of consecutive pairs
337 # a' = A*a + B*b, b' = C*a + D*b
338 # using small integer arithmetic as far as possible.
339 A, B, C, D = 1, 0, 0, 1 # initial values
341 while True:
342 # The coefficients alternate in sign while looping.
343 # The inner loop combines two steps to keep track
344 # of the signs.
346 # At this point we have
347 # A > 0, B <= 0, C <= 0, D > 0,
348 # x' = x + B <= x < x" = x + A,
349 # y' = y + C <= y < y" = y + D,
350 # and
351 # x'*N <= a' < x"*N, y'*N <= b' < y"*N,
352 # where N = 2**n.
354 # Now, if y' > 0, and x"//y' and x'//y" agree,
355 # then their common value is equal to q = a'//b'.
356 # In addition,
357 # x'%y" = x' - q*y" < x" - q*y' = x"%y',
358 # and
359 # (x'%y")*N < a'%b' < (x"%y')*N.
361 # On the other hand, we also have x//y == q,
362 # and therefore
363 # x'%y" = x + B - q*(y + D) = x%y + B',
364 # x"%y' = x + A - q*(y + C) = x%y + A',
365 # where
366 # B' = B - q*D < 0, A' = A - q*C > 0.
368 if y + C <= 0:
369 break
370 q = (x + A) // (y + C)
372 # Now x'//y" <= q, and equality holds if
373 # x' - q*y" = (x - q*y) + (B - q*D) >= 0.
374 # This is a minor optimization to avoid division.
375 x_qy, B_qD = x - q*y, B - q*D
376 if x_qy + B_qD < 0:
377 break
379 # Next step in the Euclidean sequence.
380 x, y = y, x_qy
381 A, B, C, D = C, D, A - q*C, B_qD
383 # At this point the signs of the coefficients
384 # change and their roles are interchanged.
385 # A <= 0, B > 0, C > 0, D < 0,
386 # x' = x + A <= x < x" = x + B,
387 # y' = y + D < y < y" = y + C.
389 if y + D <= 0:
390 break
391 q = (x + B) // (y + D)
392 x_qy, A_qC = x - q*y, A - q*C
393 if x_qy + A_qC < 0:
394 break
396 x, y = y, x_qy
397 A, B, C, D = C, D, A_qC, B - q*D
398 # Now the conditions on top of the loop
399 # are again satisfied.
400 # A > 0, B < 0, C < 0, D > 0.
402 if B == 0:
403 # This can only happen when y == 0 in the beginning
404 # and the inner loop does nothing.
405 # Long division is forced.
406 a, b = b, a % b
407 continue
409 # Compute new long arguments using the coefficients.
410 a, b = A*a + B*b, C*a + D*b
412 # Small divisors. Finish with the standard algorithm.
413 while b:
414 a, b = b, a % b
416 return a
419def ilcm(*args):
420 """Computes integer least common multiple.
422 Examples
423 ========
425 >>> from sympy import ilcm
426 >>> ilcm(5, 10)
427 10
428 >>> ilcm(7, 3)
429 21
430 >>> ilcm(5, 10, 15)
431 30
433 """
434 if len(args) < 2:
435 raise TypeError(
436 'ilcm() takes at least 2 arguments (%s given)' % len(args))
437 if 0 in args:
438 return 0
439 a = args[0]
440 for b in args[1:]:
441 a = a // igcd(a, b) * b # since gcd(a,b) | a
442 return a
445def igcdex(a, b):
446 """Returns x, y, g such that g = x*a + y*b = gcd(a, b).
448 Examples
449 ========
451 >>> from sympy.core.numbers import igcdex
452 >>> igcdex(2, 3)
453 (-1, 1, 1)
454 >>> igcdex(10, 12)
455 (-1, 1, 2)
457 >>> x, y, g = igcdex(100, 2004)
458 >>> x, y, g
459 (-20, 1, 4)
460 >>> x*100 + y*2004
461 4
463 """
464 if (not a) and (not b):
465 return (0, 1, 0)
467 if not a:
468 return (0, b//abs(b), abs(b))
469 if not b:
470 return (a//abs(a), 0, abs(a))
472 if a < 0:
473 a, x_sign = -a, -1
474 else:
475 x_sign = 1
477 if b < 0:
478 b, y_sign = -b, -1
479 else:
480 y_sign = 1
482 x, y, r, s = 1, 0, 0, 1
484 while b:
485 (c, q) = (a % b, a // b)
486 (a, b, r, s, x, y) = (b, c, x - q*r, y - q*s, r, s)
488 return (x*x_sign, y*y_sign, a)
491def mod_inverse(a, m):
492 r"""
493 Return the number $c$ such that, $a \times c = 1 \pmod{m}$
494 where $c$ has the same sign as $m$. If no such value exists,
495 a ValueError is raised.
497 Examples
498 ========
500 >>> from sympy import mod_inverse, S
502 Suppose we wish to find multiplicative inverse $x$ of
503 3 modulo 11. This is the same as finding $x$ such
504 that $3x = 1 \pmod{11}$. One value of x that satisfies
505 this congruence is 4. Because $3 \times 4 = 12$ and $12 = 1 \pmod{11}$.
506 This is the value returned by ``mod_inverse``:
508 >>> mod_inverse(3, 11)
509 4
510 >>> mod_inverse(-3, 11)
511 7
513 When there is a common factor between the numerators of
514 `a` and `m` the inverse does not exist:
516 >>> mod_inverse(2, 4)
517 Traceback (most recent call last):
518 ...
519 ValueError: inverse of 2 mod 4 does not exist
521 >>> mod_inverse(S(2)/7, S(5)/2)
522 7/2
524 References
525 ==========
527 .. [1] https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
528 .. [2] https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
529 """
530 c = None
531 try:
532 a, m = as_int(a), as_int(m)
533 if m != 1 and m != -1:
534 x, _, g = igcdex(a, m)
535 if g == 1:
536 c = x % m
537 except ValueError:
538 a, m = sympify(a), sympify(m)
539 if not (a.is_number and m.is_number):
540 raise TypeError(filldedent('''
541 Expected numbers for arguments; symbolic `mod_inverse`
542 is not implemented
543 but symbolic expressions can be handled with the
544 similar function,
545 sympy.polys.polytools.invert'''))
546 big = (m > 1)
547 if big not in (S.true, S.false):
548 raise ValueError('m > 1 did not evaluate; try to simplify %s' % m)
549 elif big:
550 c = 1/a
551 if c is None:
552 raise ValueError('inverse of %s (mod %s) does not exist' % (a, m))
553 return c
556class Number(AtomicExpr):
557 """Represents atomic numbers in SymPy.
559 Explanation
560 ===========
562 Floating point numbers are represented by the Float class.
563 Rational numbers (of any size) are represented by the Rational class.
564 Integer numbers (of any size) are represented by the Integer class.
565 Float and Rational are subclasses of Number; Integer is a subclass
566 of Rational.
568 For example, ``2/3`` is represented as ``Rational(2, 3)`` which is
569 a different object from the floating point number obtained with
570 Python division ``2/3``. Even for numbers that are exactly
571 represented in binary, there is a difference between how two forms,
572 such as ``Rational(1, 2)`` and ``Float(0.5)``, are used in SymPy.
573 The rational form is to be preferred in symbolic computations.
575 Other kinds of numbers, such as algebraic numbers ``sqrt(2)`` or
576 complex numbers ``3 + 4*I``, are not instances of Number class as
577 they are not atomic.
579 See Also
580 ========
582 Float, Integer, Rational
583 """
584 is_commutative = True
585 is_number = True
586 is_Number = True
588 __slots__ = ()
590 # Used to make max(x._prec, y._prec) return x._prec when only x is a float
591 _prec = -1
593 kind = NumberKind
595 def __new__(cls, *obj):
596 if len(obj) == 1:
597 obj = obj[0]
599 if isinstance(obj, Number):
600 return obj
601 if isinstance(obj, SYMPY_INTS):
602 return Integer(obj)
603 if isinstance(obj, tuple) and len(obj) == 2:
604 return Rational(*obj)
605 if isinstance(obj, (float, mpmath.mpf, decimal.Decimal)):
606 return Float(obj)
607 if isinstance(obj, str):
608 _obj = obj.lower() # float('INF') == float('inf')
609 if _obj == 'nan':
610 return S.NaN
611 elif _obj == 'inf':
612 return S.Infinity
613 elif _obj == '+inf':
614 return S.Infinity
615 elif _obj == '-inf':
616 return S.NegativeInfinity
617 val = sympify(obj)
618 if isinstance(val, Number):
619 return val
620 else:
621 raise ValueError('String "%s" does not denote a Number' % obj)
622 msg = "expected str|int|long|float|Decimal|Number object but got %r"
623 raise TypeError(msg % type(obj).__name__)
625 def could_extract_minus_sign(self):
626 return bool(self.is_extended_negative)
628 def invert(self, other, *gens, **args):
629 from sympy.polys.polytools import invert
630 if getattr(other, 'is_number', True):
631 return mod_inverse(self, other)
632 return invert(self, other, *gens, **args)
634 def __divmod__(self, other):
635 from sympy.functions.elementary.complexes import sign
637 try:
638 other = Number(other)
639 if self.is_infinite or S.NaN in (self, other):
640 return (S.NaN, S.NaN)
641 except TypeError:
642 return NotImplemented
643 if not other:
644 raise ZeroDivisionError('modulo by zero')
645 if self.is_Integer and other.is_Integer:
646 return Tuple(*divmod(self.p, other.p))
647 elif isinstance(other, Float):
648 rat = self/Rational(other)
649 else:
650 rat = self/other
651 if other.is_finite:
652 w = int(rat) if rat >= 0 else int(rat) - 1
653 r = self - other*w
654 else:
655 w = 0 if not self or (sign(self) == sign(other)) else -1
656 r = other if w else self
657 return Tuple(w, r)
659 def __rdivmod__(self, other):
660 try:
661 other = Number(other)
662 except TypeError:
663 return NotImplemented
664 return divmod(other, self)
666 def _as_mpf_val(self, prec):
667 """Evaluation of mpf tuple accurate to at least prec bits."""
668 raise NotImplementedError('%s needs ._as_mpf_val() method' %
669 (self.__class__.__name__))
671 def _eval_evalf(self, prec):
672 return Float._new(self._as_mpf_val(prec), prec)
674 def _as_mpf_op(self, prec):
675 prec = max(prec, self._prec)
676 return self._as_mpf_val(prec), prec
678 def __float__(self):
679 return mlib.to_float(self._as_mpf_val(53))
681 def floor(self):
682 raise NotImplementedError('%s needs .floor() method' %
683 (self.__class__.__name__))
685 def ceiling(self):
686 raise NotImplementedError('%s needs .ceiling() method' %
687 (self.__class__.__name__))
689 def __floor__(self):
690 return self.floor()
692 def __ceil__(self):
693 return self.ceiling()
695 def _eval_conjugate(self):
696 return self
698 def _eval_order(self, *symbols):
699 from sympy.series.order import Order
700 # Order(5, x, y) -> Order(1,x,y)
701 return Order(S.One, *symbols)
703 def _eval_subs(self, old, new):
704 if old == -self:
705 return -new
706 return self # there is no other possibility
708 @classmethod
709 def class_key(cls):
710 return 1, 0, 'Number'
712 @cacheit
713 def sort_key(self, order=None):
714 return self.class_key(), (0, ()), (), self
716 @_sympifyit('other', NotImplemented)
717 def __add__(self, other):
718 if isinstance(other, Number) and global_parameters.evaluate:
719 if other is S.NaN:
720 return S.NaN
721 elif other is S.Infinity:
722 return S.Infinity
723 elif other is S.NegativeInfinity:
724 return S.NegativeInfinity
725 return AtomicExpr.__add__(self, other)
727 @_sympifyit('other', NotImplemented)
728 def __sub__(self, other):
729 if isinstance(other, Number) and global_parameters.evaluate:
730 if other is S.NaN:
731 return S.NaN
732 elif other is S.Infinity:
733 return S.NegativeInfinity
734 elif other is S.NegativeInfinity:
735 return S.Infinity
736 return AtomicExpr.__sub__(self, other)
738 @_sympifyit('other', NotImplemented)
739 def __mul__(self, other):
740 if isinstance(other, Number) and global_parameters.evaluate:
741 if other is S.NaN:
742 return S.NaN
743 elif other is S.Infinity:
744 if self.is_zero:
745 return S.NaN
746 elif self.is_positive:
747 return S.Infinity
748 else:
749 return S.NegativeInfinity
750 elif other is S.NegativeInfinity:
751 if self.is_zero:
752 return S.NaN
753 elif self.is_positive:
754 return S.NegativeInfinity
755 else:
756 return S.Infinity
757 elif isinstance(other, Tuple):
758 return NotImplemented
759 return AtomicExpr.__mul__(self, other)
761 @_sympifyit('other', NotImplemented)
762 def __truediv__(self, other):
763 if isinstance(other, Number) and global_parameters.evaluate:
764 if other is S.NaN:
765 return S.NaN
766 elif other in (S.Infinity, S.NegativeInfinity):
767 return S.Zero
768 return AtomicExpr.__truediv__(self, other)
770 def __eq__(self, other):
771 raise NotImplementedError('%s needs .__eq__() method' %
772 (self.__class__.__name__))
774 def __ne__(self, other):
775 raise NotImplementedError('%s needs .__ne__() method' %
776 (self.__class__.__name__))
778 def __lt__(self, other):
779 try:
780 other = _sympify(other)
781 except SympifyError:
782 raise TypeError("Invalid comparison %s < %s" % (self, other))
783 raise NotImplementedError('%s needs .__lt__() method' %
784 (self.__class__.__name__))
786 def __le__(self, other):
787 try:
788 other = _sympify(other)
789 except SympifyError:
790 raise TypeError("Invalid comparison %s <= %s" % (self, other))
791 raise NotImplementedError('%s needs .__le__() method' %
792 (self.__class__.__name__))
794 def __gt__(self, other):
795 try:
796 other = _sympify(other)
797 except SympifyError:
798 raise TypeError("Invalid comparison %s > %s" % (self, other))
799 return _sympify(other).__lt__(self)
801 def __ge__(self, other):
802 try:
803 other = _sympify(other)
804 except SympifyError:
805 raise TypeError("Invalid comparison %s >= %s" % (self, other))
806 return _sympify(other).__le__(self)
808 def __hash__(self):
809 return super().__hash__()
811 def is_constant(self, *wrt, **flags):
812 return True
814 def as_coeff_mul(self, *deps, rational=True, **kwargs):
815 # a -> c*t
816 if self.is_Rational or not rational:
817 return self, ()
818 elif self.is_negative:
819 return S.NegativeOne, (-self,)
820 return S.One, (self,)
822 def as_coeff_add(self, *deps):
823 # a -> c + t
824 if self.is_Rational:
825 return self, ()
826 return S.Zero, (self,)
828 def as_coeff_Mul(self, rational=False):
829 """Efficiently extract the coefficient of a product."""
830 if rational and not self.is_Rational:
831 return S.One, self
832 return (self, S.One) if self else (S.One, self)
834 def as_coeff_Add(self, rational=False):
835 """Efficiently extract the coefficient of a summation."""
836 if not rational:
837 return self, S.Zero
838 return S.Zero, self
840 def gcd(self, other):
841 """Compute GCD of `self` and `other`. """
842 from sympy.polys.polytools import gcd
843 return gcd(self, other)
845 def lcm(self, other):
846 """Compute LCM of `self` and `other`. """
847 from sympy.polys.polytools import lcm
848 return lcm(self, other)
850 def cofactors(self, other):
851 """Compute GCD and cofactors of `self` and `other`. """
852 from sympy.polys.polytools import cofactors
853 return cofactors(self, other)
856class Float(Number):
857 """Represent a floating-point number of arbitrary precision.
859 Examples
860 ========
862 >>> from sympy import Float
863 >>> Float(3.5)
864 3.50000000000000
865 >>> Float(3)
866 3.00000000000000
868 Creating Floats from strings (and Python ``int`` and ``long``
869 types) will give a minimum precision of 15 digits, but the
870 precision will automatically increase to capture all digits
871 entered.
873 >>> Float(1)
874 1.00000000000000
875 >>> Float(10**20)
876 100000000000000000000.
877 >>> Float('1e20')
878 100000000000000000000.
880 However, *floating-point* numbers (Python ``float`` types) retain
881 only 15 digits of precision:
883 >>> Float(1e20)
884 1.00000000000000e+20
885 >>> Float(1.23456789123456789)
886 1.23456789123457
888 It may be preferable to enter high-precision decimal numbers
889 as strings:
891 >>> Float('1.23456789123456789')
892 1.23456789123456789
894 The desired number of digits can also be specified:
896 >>> Float('1e-3', 3)
897 0.00100
898 >>> Float(100, 4)
899 100.0
901 Float can automatically count significant figures if a null string
902 is sent for the precision; spaces or underscores are also allowed. (Auto-
903 counting is only allowed for strings, ints and longs).
905 >>> Float('123 456 789.123_456', '')
906 123456789.123456
907 >>> Float('12e-3', '')
908 0.012
909 >>> Float(3, '')
910 3.
912 If a number is written in scientific notation, only the digits before the
913 exponent are considered significant if a decimal appears, otherwise the
914 "e" signifies only how to move the decimal:
916 >>> Float('60.e2', '') # 2 digits significant
917 6.0e+3
918 >>> Float('60e2', '') # 4 digits significant
919 6000.
920 >>> Float('600e-2', '') # 3 digits significant
921 6.00
923 Notes
924 =====
926 Floats are inexact by their nature unless their value is a binary-exact
927 value.
929 >>> approx, exact = Float(.1, 1), Float(.125, 1)
931 For calculation purposes, evalf needs to be able to change the precision
932 but this will not increase the accuracy of the inexact value. The
933 following is the most accurate 5-digit approximation of a value of 0.1
934 that had only 1 digit of precision:
936 >>> approx.evalf(5)
937 0.099609
939 By contrast, 0.125 is exact in binary (as it is in base 10) and so it
940 can be passed to Float or evalf to obtain an arbitrary precision with
941 matching accuracy:
943 >>> Float(exact, 5)
944 0.12500
945 >>> exact.evalf(20)
946 0.12500000000000000000
948 Trying to make a high-precision Float from a float is not disallowed,
949 but one must keep in mind that the *underlying float* (not the apparent
950 decimal value) is being obtained with high precision. For example, 0.3
951 does not have a finite binary representation. The closest rational is
952 the fraction 5404319552844595/2**54. So if you try to obtain a Float of
953 0.3 to 20 digits of precision you will not see the same thing as 0.3
954 followed by 19 zeros:
956 >>> Float(0.3, 20)
957 0.29999999999999998890
959 If you want a 20-digit value of the decimal 0.3 (not the floating point
960 approximation of 0.3) you should send the 0.3 as a string. The underlying
961 representation is still binary but a higher precision than Python's float
962 is used:
964 >>> Float('0.3', 20)
965 0.30000000000000000000
967 Although you can increase the precision of an existing Float using Float
968 it will not increase the accuracy -- the underlying value is not changed:
970 >>> def show(f): # binary rep of Float
971 ... from sympy import Mul, Pow
972 ... s, m, e, b = f._mpf_
973 ... v = Mul(int(m), Pow(2, int(e), evaluate=False), evaluate=False)
974 ... print('%s at prec=%s' % (v, f._prec))
975 ...
976 >>> t = Float('0.3', 3)
977 >>> show(t)
978 4915/2**14 at prec=13
979 >>> show(Float(t, 20)) # higher prec, not higher accuracy
980 4915/2**14 at prec=70
981 >>> show(Float(t, 2)) # lower prec
982 307/2**10 at prec=10
984 The same thing happens when evalf is used on a Float:
986 >>> show(t.evalf(20))
987 4915/2**14 at prec=70
988 >>> show(t.evalf(2))
989 307/2**10 at prec=10
991 Finally, Floats can be instantiated with an mpf tuple (n, c, p) to
992 produce the number (-1)**n*c*2**p:
994 >>> n, c, p = 1, 5, 0
995 >>> (-1)**n*c*2**p
996 -5
997 >>> Float((1, 5, 0))
998 -5.00000000000000
1000 An actual mpf tuple also contains the number of bits in c as the last
1001 element of the tuple:
1003 >>> _._mpf_
1004 (1, 5, 0, 3)
1006 This is not needed for instantiation and is not the same thing as the
1007 precision. The mpf tuple and the precision are two separate quantities
1008 that Float tracks.
1010 In SymPy, a Float is a number that can be computed with arbitrary
1011 precision. Although floating point 'inf' and 'nan' are not such
1012 numbers, Float can create these numbers:
1014 >>> Float('-inf')
1015 -oo
1016 >>> _.is_Float
1017 False
1019 Zero in Float only has a single value. Values are not separate for
1020 positive and negative zeroes.
1021 """
1022 __slots__ = ('_mpf_', '_prec')
1024 _mpf_: tuple[int, int, int, int]
1026 # A Float represents many real numbers,
1027 # both rational and irrational.
1028 is_rational = None
1029 is_irrational = None
1030 is_number = True
1032 is_real = True
1033 is_extended_real = True
1035 is_Float = True
1037 def __new__(cls, num, dps=None, precision=None):
1038 if dps is not None and precision is not None:
1039 raise ValueError('Both decimal and binary precision supplied. '
1040 'Supply only one. ')
1042 if isinstance(num, str):
1043 # Float accepts spaces as digit separators
1044 num = num.replace(' ', '').lower()
1045 if num.startswith('.') and len(num) > 1:
1046 num = '0' + num
1047 elif num.startswith('-.') and len(num) > 2:
1048 num = '-0.' + num[2:]
1049 elif num in ('inf', '+inf'):
1050 return S.Infinity
1051 elif num == '-inf':
1052 return S.NegativeInfinity
1053 elif isinstance(num, float) and num == 0:
1054 num = '0'
1055 elif isinstance(num, float) and num == float('inf'):
1056 return S.Infinity
1057 elif isinstance(num, float) and num == float('-inf'):
1058 return S.NegativeInfinity
1059 elif isinstance(num, float) and math.isnan(num):
1060 return S.NaN
1061 elif isinstance(num, (SYMPY_INTS, Integer)):
1062 num = str(num)
1063 elif num is S.Infinity:
1064 return num
1065 elif num is S.NegativeInfinity:
1066 return num
1067 elif num is S.NaN:
1068 return num
1069 elif _is_numpy_instance(num): # support for numpy datatypes
1070 num = _convert_numpy_types(num)
1071 elif isinstance(num, mpmath.mpf):
1072 if precision is None:
1073 if dps is None:
1074 precision = num.context.prec
1075 num = num._mpf_
1077 if dps is None and precision is None:
1078 dps = 15
1079 if isinstance(num, Float):
1080 return num
1081 if isinstance(num, str) and _literal_float(num):
1082 try:
1083 Num = decimal.Decimal(num)
1084 except decimal.InvalidOperation:
1085 pass
1086 else:
1087 isint = '.' not in num
1088 num, dps = _decimal_to_Rational_prec(Num)
1089 if num.is_Integer and isint:
1090 dps = max(dps, len(str(num).lstrip('-')))
1091 dps = max(15, dps)
1092 precision = dps_to_prec(dps)
1093 elif precision == '' and dps is None or precision is None and dps == '':
1094 if not isinstance(num, str):
1095 raise ValueError('The null string can only be used when '
1096 'the number to Float is passed as a string or an integer.')
1097 ok = None
1098 if _literal_float(num):
1099 try:
1100 Num = decimal.Decimal(num)
1101 except decimal.InvalidOperation:
1102 pass
1103 else:
1104 isint = '.' not in num
1105 num, dps = _decimal_to_Rational_prec(Num)
1106 if num.is_Integer and isint:
1107 dps = max(dps, len(str(num).lstrip('-')))
1108 precision = dps_to_prec(dps)
1109 ok = True
1110 if ok is None:
1111 raise ValueError('string-float not recognized: %s' % num)
1113 # decimal precision(dps) is set and maybe binary precision(precision)
1114 # as well.From here on binary precision is used to compute the Float.
1115 # Hence, if supplied use binary precision else translate from decimal
1116 # precision.
1118 if precision is None or precision == '':
1119 precision = dps_to_prec(dps)
1121 precision = int(precision)
1123 if isinstance(num, float):
1124 _mpf_ = mlib.from_float(num, precision, rnd)
1125 elif isinstance(num, str):
1126 _mpf_ = mlib.from_str(num, precision, rnd)
1127 elif isinstance(num, decimal.Decimal):
1128 if num.is_finite():
1129 _mpf_ = mlib.from_str(str(num), precision, rnd)
1130 elif num.is_nan():
1131 return S.NaN
1132 elif num.is_infinite():
1133 if num > 0:
1134 return S.Infinity
1135 return S.NegativeInfinity
1136 else:
1137 raise ValueError("unexpected decimal value %s" % str(num))
1138 elif isinstance(num, tuple) and len(num) in (3, 4):
1139 if isinstance(num[1], str):
1140 # it's a hexadecimal (coming from a pickled object)
1141 num = list(num)
1142 # If we're loading an object pickled in Python 2 into
1143 # Python 3, we may need to strip a tailing 'L' because
1144 # of a shim for int on Python 3, see issue #13470.
1145 if num[1].endswith('L'):
1146 num[1] = num[1][:-1]
1147 # Strip leading '0x' - gmpy2 only documents such inputs
1148 # with base prefix as valid when the 2nd argument (base) is 0.
1149 # When mpmath uses Sage as the backend, however, it
1150 # ends up including '0x' when preparing the picklable tuple.
1151 # See issue #19690.
1152 if num[1].startswith('0x'):
1153 num[1] = num[1][2:]
1154 # Now we can assume that it is in standard form
1155 num[1] = MPZ(num[1], 16)
1156 _mpf_ = tuple(num)
1157 else:
1158 if len(num) == 4:
1159 # handle normalization hack
1160 return Float._new(num, precision)
1161 else:
1162 if not all((
1163 num[0] in (0, 1),
1164 num[1] >= 0,
1165 all(type(i) in (int, int) for i in num)
1166 )):
1167 raise ValueError('malformed mpf: %s' % (num,))
1168 # don't compute number or else it may
1169 # over/underflow
1170 return Float._new(
1171 (num[0], num[1], num[2], bitcount(num[1])),
1172 precision)
1173 else:
1174 try:
1175 _mpf_ = num._as_mpf_val(precision)
1176 except (NotImplementedError, AttributeError):
1177 _mpf_ = mpmath.mpf(num, prec=precision)._mpf_
1179 return cls._new(_mpf_, precision, zero=False)
1181 @classmethod
1182 def _new(cls, _mpf_, _prec, zero=True):
1183 # special cases
1184 if zero and _mpf_ == fzero:
1185 return S.Zero # Float(0) -> 0.0; Float._new((0,0,0,0)) -> 0
1186 elif _mpf_ == _mpf_nan:
1187 return S.NaN
1188 elif _mpf_ == _mpf_inf:
1189 return S.Infinity
1190 elif _mpf_ == _mpf_ninf:
1191 return S.NegativeInfinity
1193 obj = Expr.__new__(cls)
1194 obj._mpf_ = mpf_norm(_mpf_, _prec)
1195 obj._prec = _prec
1196 return obj
1198 # mpz can't be pickled
1199 def __getnewargs_ex__(self):
1200 return ((mlib.to_pickable(self._mpf_),), {'precision': self._prec})
1202 def _hashable_content(self):
1203 return (self._mpf_, self._prec)
1205 def floor(self):
1206 return Integer(int(mlib.to_int(
1207 mlib.mpf_floor(self._mpf_, self._prec))))
1209 def ceiling(self):
1210 return Integer(int(mlib.to_int(
1211 mlib.mpf_ceil(self._mpf_, self._prec))))
1213 def __floor__(self):
1214 return self.floor()
1216 def __ceil__(self):
1217 return self.ceiling()
1219 @property
1220 def num(self):
1221 return mpmath.mpf(self._mpf_)
1223 def _as_mpf_val(self, prec):
1224 rv = mpf_norm(self._mpf_, prec)
1225 if rv != self._mpf_ and self._prec == prec:
1226 debug(self._mpf_, rv)
1227 return rv
1229 def _as_mpf_op(self, prec):
1230 return self._mpf_, max(prec, self._prec)
1232 def _eval_is_finite(self):
1233 if self._mpf_ in (_mpf_inf, _mpf_ninf):
1234 return False
1235 return True
1237 def _eval_is_infinite(self):
1238 if self._mpf_ in (_mpf_inf, _mpf_ninf):
1239 return True
1240 return False
1242 def _eval_is_integer(self):
1243 return self._mpf_ == fzero
1245 def _eval_is_negative(self):
1246 if self._mpf_ in (_mpf_ninf, _mpf_inf):
1247 return False
1248 return self.num < 0
1250 def _eval_is_positive(self):
1251 if self._mpf_ in (_mpf_ninf, _mpf_inf):
1252 return False
1253 return self.num > 0
1255 def _eval_is_extended_negative(self):
1256 if self._mpf_ == _mpf_ninf:
1257 return True
1258 if self._mpf_ == _mpf_inf:
1259 return False
1260 return self.num < 0
1262 def _eval_is_extended_positive(self):
1263 if self._mpf_ == _mpf_inf:
1264 return True
1265 if self._mpf_ == _mpf_ninf:
1266 return False
1267 return self.num > 0
1269 def _eval_is_zero(self):
1270 return self._mpf_ == fzero
1272 def __bool__(self):
1273 return self._mpf_ != fzero
1275 def __neg__(self):
1276 if not self:
1277 return self
1278 return Float._new(mlib.mpf_neg(self._mpf_), self._prec)
1280 @_sympifyit('other', NotImplemented)
1281 def __add__(self, other):
1282 if isinstance(other, Number) and global_parameters.evaluate:
1283 rhs, prec = other._as_mpf_op(self._prec)
1284 return Float._new(mlib.mpf_add(self._mpf_, rhs, prec, rnd), prec)
1285 return Number.__add__(self, other)
1287 @_sympifyit('other', NotImplemented)
1288 def __sub__(self, other):
1289 if isinstance(other, Number) and global_parameters.evaluate:
1290 rhs, prec = other._as_mpf_op(self._prec)
1291 return Float._new(mlib.mpf_sub(self._mpf_, rhs, prec, rnd), prec)
1292 return Number.__sub__(self, other)
1294 @_sympifyit('other', NotImplemented)
1295 def __mul__(self, other):
1296 if isinstance(other, Number) and global_parameters.evaluate:
1297 rhs, prec = other._as_mpf_op(self._prec)
1298 return Float._new(mlib.mpf_mul(self._mpf_, rhs, prec, rnd), prec)
1299 return Number.__mul__(self, other)
1301 @_sympifyit('other', NotImplemented)
1302 def __truediv__(self, other):
1303 if isinstance(other, Number) and other != 0 and global_parameters.evaluate:
1304 rhs, prec = other._as_mpf_op(self._prec)
1305 return Float._new(mlib.mpf_div(self._mpf_, rhs, prec, rnd), prec)
1306 return Number.__truediv__(self, other)
1308 @_sympifyit('other', NotImplemented)
1309 def __mod__(self, other):
1310 if isinstance(other, Rational) and other.q != 1 and global_parameters.evaluate:
1311 # calculate mod with Rationals, *then* round the result
1312 return Float(Rational.__mod__(Rational(self), other),
1313 precision=self._prec)
1314 if isinstance(other, Float) and global_parameters.evaluate:
1315 r = self/other
1316 if r == int(r):
1317 return Float(0, precision=max(self._prec, other._prec))
1318 if isinstance(other, Number) and global_parameters.evaluate:
1319 rhs, prec = other._as_mpf_op(self._prec)
1320 return Float._new(mlib.mpf_mod(self._mpf_, rhs, prec, rnd), prec)
1321 return Number.__mod__(self, other)
1323 @_sympifyit('other', NotImplemented)
1324 def __rmod__(self, other):
1325 if isinstance(other, Float) and global_parameters.evaluate:
1326 return other.__mod__(self)
1327 if isinstance(other, Number) and global_parameters.evaluate:
1328 rhs, prec = other._as_mpf_op(self._prec)
1329 return Float._new(mlib.mpf_mod(rhs, self._mpf_, prec, rnd), prec)
1330 return Number.__rmod__(self, other)
1332 def _eval_power(self, expt):
1333 """
1334 expt is symbolic object but not equal to 0, 1
1336 (-p)**r -> exp(r*log(-p)) -> exp(r*(log(p) + I*Pi)) ->
1337 -> p**r*(sin(Pi*r) + cos(Pi*r)*I)
1338 """
1339 if equal_valued(self, 0):
1340 if expt.is_extended_positive:
1341 return self
1342 if expt.is_extended_negative:
1343 return S.ComplexInfinity
1344 if isinstance(expt, Number):
1345 if isinstance(expt, Integer):
1346 prec = self._prec
1347 return Float._new(
1348 mlib.mpf_pow_int(self._mpf_, expt.p, prec, rnd), prec)
1349 elif isinstance(expt, Rational) and \
1350 expt.p == 1 and expt.q % 2 and self.is_negative:
1351 return Pow(S.NegativeOne, expt, evaluate=False)*(
1352 -self)._eval_power(expt)
1353 expt, prec = expt._as_mpf_op(self._prec)
1354 mpfself = self._mpf_
1355 try:
1356 y = mpf_pow(mpfself, expt, prec, rnd)
1357 return Float._new(y, prec)
1358 except mlib.ComplexResult:
1359 re, im = mlib.mpc_pow(
1360 (mpfself, fzero), (expt, fzero), prec, rnd)
1361 return Float._new(re, prec) + \
1362 Float._new(im, prec)*S.ImaginaryUnit
1364 def __abs__(self):
1365 return Float._new(mlib.mpf_abs(self._mpf_), self._prec)
1367 def __int__(self):
1368 if self._mpf_ == fzero:
1369 return 0
1370 return int(mlib.to_int(self._mpf_)) # uses round_fast = round_down
1372 def __eq__(self, other):
1373 from sympy.logic.boolalg import Boolean
1374 try:
1375 other = _sympify(other)
1376 except SympifyError:
1377 return NotImplemented
1378 if isinstance(other, Boolean):
1379 return False
1380 if other.is_NumberSymbol:
1381 if other.is_irrational:
1382 return False
1383 return other.__eq__(self)
1384 if other.is_Float:
1385 # comparison is exact
1386 # so Float(.1, 3) != Float(.1, 33)
1387 return self._mpf_ == other._mpf_
1388 if other.is_Rational:
1389 return other.__eq__(self)
1390 if other.is_Number:
1391 # numbers should compare at the same precision;
1392 # all _as_mpf_val routines should be sure to abide
1393 # by the request to change the prec if necessary; if
1394 # they don't, the equality test will fail since it compares
1395 # the mpf tuples
1396 ompf = other._as_mpf_val(self._prec)
1397 return bool(mlib.mpf_eq(self._mpf_, ompf))
1398 if not self:
1399 return not other
1400 return False # Float != non-Number
1402 def __ne__(self, other):
1403 return not self == other
1405 def _Frel(self, other, op):
1406 try:
1407 other = _sympify(other)
1408 except SympifyError:
1409 return NotImplemented
1410 if other.is_Rational:
1411 # test self*other.q <?> other.p without losing precision
1412 '''
1413 >>> f = Float(.1,2)
1414 >>> i = 1234567890
1415 >>> (f*i)._mpf_
1416 (0, 471, 18, 9)
1417 >>> mlib.mpf_mul(f._mpf_, mlib.from_int(i))
1418 (0, 505555550955, -12, 39)
1419 '''
1420 smpf = mlib.mpf_mul(self._mpf_, mlib.from_int(other.q))
1421 ompf = mlib.from_int(other.p)
1422 return _sympify(bool(op(smpf, ompf)))
1423 elif other.is_Float:
1424 return _sympify(bool(
1425 op(self._mpf_, other._mpf_)))
1426 elif other.is_comparable and other not in (
1427 S.Infinity, S.NegativeInfinity):
1428 other = other.evalf(prec_to_dps(self._prec))
1429 if other._prec > 1:
1430 if other.is_Number:
1431 return _sympify(bool(
1432 op(self._mpf_, other._as_mpf_val(self._prec))))
1434 def __gt__(self, other):
1435 if isinstance(other, NumberSymbol):
1436 return other.__lt__(self)
1437 rv = self._Frel(other, mlib.mpf_gt)
1438 if rv is None:
1439 return Expr.__gt__(self, other)
1440 return rv
1442 def __ge__(self, other):
1443 if isinstance(other, NumberSymbol):
1444 return other.__le__(self)
1445 rv = self._Frel(other, mlib.mpf_ge)
1446 if rv is None:
1447 return Expr.__ge__(self, other)
1448 return rv
1450 def __lt__(self, other):
1451 if isinstance(other, NumberSymbol):
1452 return other.__gt__(self)
1453 rv = self._Frel(other, mlib.mpf_lt)
1454 if rv is None:
1455 return Expr.__lt__(self, other)
1456 return rv
1458 def __le__(self, other):
1459 if isinstance(other, NumberSymbol):
1460 return other.__ge__(self)
1461 rv = self._Frel(other, mlib.mpf_le)
1462 if rv is None:
1463 return Expr.__le__(self, other)
1464 return rv
1466 def __hash__(self):
1467 return super().__hash__()
1469 def epsilon_eq(self, other, epsilon="1e-15"):
1470 return abs(self - other) < Float(epsilon)
1472 def __format__(self, format_spec):
1473 return format(decimal.Decimal(str(self)), format_spec)
1476# Add sympify converters
1477_sympy_converter[float] = _sympy_converter[decimal.Decimal] = Float
1479# this is here to work nicely in Sage
1480RealNumber = Float
1483class Rational(Number):
1484 """Represents rational numbers (p/q) of any size.
1486 Examples
1487 ========
1489 >>> from sympy import Rational, nsimplify, S, pi
1490 >>> Rational(1, 2)
1491 1/2
1493 Rational is unprejudiced in accepting input. If a float is passed, the
1494 underlying value of the binary representation will be returned:
1496 >>> Rational(.5)
1497 1/2
1498 >>> Rational(.2)
1499 3602879701896397/18014398509481984
1501 If the simpler representation of the float is desired then consider
1502 limiting the denominator to the desired value or convert the float to
1503 a string (which is roughly equivalent to limiting the denominator to
1504 10**12):
1506 >>> Rational(str(.2))
1507 1/5
1508 >>> Rational(.2).limit_denominator(10**12)
1509 1/5
1511 An arbitrarily precise Rational is obtained when a string literal is
1512 passed:
1514 >>> Rational("1.23")
1515 123/100
1516 >>> Rational('1e-2')
1517 1/100
1518 >>> Rational(".1")
1519 1/10
1520 >>> Rational('1e-2/3.2')
1521 1/320
1523 The conversion of other types of strings can be handled by
1524 the sympify() function, and conversion of floats to expressions
1525 or simple fractions can be handled with nsimplify:
1527 >>> S('.[3]') # repeating digits in brackets
1528 1/3
1529 >>> S('3**2/10') # general expressions
1530 9/10
1531 >>> nsimplify(.3) # numbers that have a simple form
1532 3/10
1534 But if the input does not reduce to a literal Rational, an error will
1535 be raised:
1537 >>> Rational(pi)
1538 Traceback (most recent call last):
1539 ...
1540 TypeError: invalid input: pi
1543 Low-level
1544 ---------
1546 Access numerator and denominator as .p and .q:
1548 >>> r = Rational(3, 4)
1549 >>> r
1550 3/4
1551 >>> r.p
1552 3
1553 >>> r.q
1554 4
1556 Note that p and q return integers (not SymPy Integers) so some care
1557 is needed when using them in expressions:
1559 >>> r.p/r.q
1560 0.75
1562 If an unevaluated Rational is desired, ``gcd=1`` can be passed and
1563 this will keep common divisors of the numerator and denominator
1564 from being eliminated. It is not possible, however, to leave a
1565 negative value in the denominator.
1567 >>> Rational(2, 4, gcd=1)
1568 2/4
1569 >>> Rational(2, -4, gcd=1).q
1570 4
1572 See Also
1573 ========
1574 sympy.core.sympify.sympify, sympy.simplify.simplify.nsimplify
1575 """
1576 is_real = True
1577 is_integer = False
1578 is_rational = True
1579 is_number = True
1581 __slots__ = ('p', 'q')
1583 p: int
1584 q: int
1586 is_Rational = True
1588 @cacheit
1589 def __new__(cls, p, q=None, gcd=None):
1590 if q is None:
1591 if isinstance(p, Rational):
1592 return p
1594 if isinstance(p, SYMPY_INTS):
1595 pass
1596 else:
1597 if isinstance(p, (float, Float)):
1598 return Rational(*_as_integer_ratio(p))
1600 if not isinstance(p, str):
1601 try:
1602 p = sympify(p)
1603 except (SympifyError, SyntaxError):
1604 pass # error will raise below
1605 else:
1606 if p.count('/') > 1:
1607 raise TypeError('invalid input: %s' % p)
1608 p = p.replace(' ', '')
1609 pq = p.rsplit('/', 1)
1610 if len(pq) == 2:
1611 p, q = pq
1612 fp = fractions.Fraction(p)
1613 fq = fractions.Fraction(q)
1614 p = fp/fq
1615 try:
1616 p = fractions.Fraction(p)
1617 except ValueError:
1618 pass # error will raise below
1619 else:
1620 return Rational(p.numerator, p.denominator, 1)
1622 if not isinstance(p, Rational):
1623 raise TypeError('invalid input: %s' % p)
1625 q = 1
1626 gcd = 1
1627 Q = 1
1629 if not isinstance(p, SYMPY_INTS):
1630 p = Rational(p)
1631 Q *= p.q
1632 p = p.p
1633 else:
1634 p = int(p)
1636 if not isinstance(q, SYMPY_INTS):
1637 q = Rational(q)
1638 p *= q.q
1639 Q *= q.p
1640 else:
1641 Q *= int(q)
1642 q = Q
1644 # p and q are now ints
1645 if q == 0:
1646 if p == 0:
1647 if _errdict["divide"]:
1648 raise ValueError("Indeterminate 0/0")
1649 else:
1650 return S.NaN
1651 return S.ComplexInfinity
1652 if q < 0:
1653 q = -q
1654 p = -p
1655 if not gcd:
1656 gcd = igcd(abs(p), q)
1657 if gcd > 1:
1658 p //= gcd
1659 q //= gcd
1660 if q == 1:
1661 return Integer(p)
1662 if p == 1 and q == 2:
1663 return S.Half
1664 obj = Expr.__new__(cls)
1665 obj.p = p
1666 obj.q = q
1667 return obj
1669 def limit_denominator(self, max_denominator=1000000):
1670 """Closest Rational to self with denominator at most max_denominator.
1672 Examples
1673 ========
1675 >>> from sympy import Rational
1676 >>> Rational('3.141592653589793').limit_denominator(10)
1677 22/7
1678 >>> Rational('3.141592653589793').limit_denominator(100)
1679 311/99
1681 """
1682 f = fractions.Fraction(self.p, self.q)
1683 return Rational(f.limit_denominator(fractions.Fraction(int(max_denominator))))
1685 def __getnewargs__(self):
1686 return (self.p, self.q)
1688 def _hashable_content(self):
1689 return (self.p, self.q)
1691 def _eval_is_positive(self):
1692 return self.p > 0
1694 def _eval_is_zero(self):
1695 return self.p == 0
1697 def __neg__(self):
1698 return Rational(-self.p, self.q)
1700 @_sympifyit('other', NotImplemented)
1701 def __add__(self, other):
1702 if global_parameters.evaluate:
1703 if isinstance(other, Integer):
1704 return Rational(self.p + self.q*other.p, self.q, 1)
1705 elif isinstance(other, Rational):
1706 #TODO: this can probably be optimized more
1707 return Rational(self.p*other.q + self.q*other.p, self.q*other.q)
1708 elif isinstance(other, Float):
1709 return other + self
1710 else:
1711 return Number.__add__(self, other)
1712 return Number.__add__(self, other)
1713 __radd__ = __add__
1715 @_sympifyit('other', NotImplemented)
1716 def __sub__(self, other):
1717 if global_parameters.evaluate:
1718 if isinstance(other, Integer):
1719 return Rational(self.p - self.q*other.p, self.q, 1)
1720 elif isinstance(other, Rational):
1721 return Rational(self.p*other.q - self.q*other.p, self.q*other.q)
1722 elif isinstance(other, Float):
1723 return -other + self
1724 else:
1725 return Number.__sub__(self, other)
1726 return Number.__sub__(self, other)
1727 @_sympifyit('other', NotImplemented)
1728 def __rsub__(self, other):
1729 if global_parameters.evaluate:
1730 if isinstance(other, Integer):
1731 return Rational(self.q*other.p - self.p, self.q, 1)
1732 elif isinstance(other, Rational):
1733 return Rational(self.q*other.p - self.p*other.q, self.q*other.q)
1734 elif isinstance(other, Float):
1735 return -self + other
1736 else:
1737 return Number.__rsub__(self, other)
1738 return Number.__rsub__(self, other)
1739 @_sympifyit('other', NotImplemented)
1740 def __mul__(self, other):
1741 if global_parameters.evaluate:
1742 if isinstance(other, Integer):
1743 return Rational(self.p*other.p, self.q, igcd(other.p, self.q))
1744 elif isinstance(other, Rational):
1745 return Rational(self.p*other.p, self.q*other.q, igcd(self.p, other.q)*igcd(self.q, other.p))
1746 elif isinstance(other, Float):
1747 return other*self
1748 else:
1749 return Number.__mul__(self, other)
1750 return Number.__mul__(self, other)
1751 __rmul__ = __mul__
1753 @_sympifyit('other', NotImplemented)
1754 def __truediv__(self, other):
1755 if global_parameters.evaluate:
1756 if isinstance(other, Integer):
1757 if self.p and other.p == S.Zero:
1758 return S.ComplexInfinity
1759 else:
1760 return Rational(self.p, self.q*other.p, igcd(self.p, other.p))
1761 elif isinstance(other, Rational):
1762 return Rational(self.p*other.q, self.q*other.p, igcd(self.p, other.p)*igcd(self.q, other.q))
1763 elif isinstance(other, Float):
1764 return self*(1/other)
1765 else:
1766 return Number.__truediv__(self, other)
1767 return Number.__truediv__(self, other)
1768 @_sympifyit('other', NotImplemented)
1769 def __rtruediv__(self, other):
1770 if global_parameters.evaluate:
1771 if isinstance(other, Integer):
1772 return Rational(other.p*self.q, self.p, igcd(self.p, other.p))
1773 elif isinstance(other, Rational):
1774 return Rational(other.p*self.q, other.q*self.p, igcd(self.p, other.p)*igcd(self.q, other.q))
1775 elif isinstance(other, Float):
1776 return other*(1/self)
1777 else:
1778 return Number.__rtruediv__(self, other)
1779 return Number.__rtruediv__(self, other)
1781 @_sympifyit('other', NotImplemented)
1782 def __mod__(self, other):
1783 if global_parameters.evaluate:
1784 if isinstance(other, Rational):
1785 n = (self.p*other.q) // (other.p*self.q)
1786 return Rational(self.p*other.q - n*other.p*self.q, self.q*other.q)
1787 if isinstance(other, Float):
1788 # calculate mod with Rationals, *then* round the answer
1789 return Float(self.__mod__(Rational(other)),
1790 precision=other._prec)
1791 return Number.__mod__(self, other)
1792 return Number.__mod__(self, other)
1794 @_sympifyit('other', NotImplemented)
1795 def __rmod__(self, other):
1796 if isinstance(other, Rational):
1797 return Rational.__mod__(other, self)
1798 return Number.__rmod__(self, other)
1800 def _eval_power(self, expt):
1801 if isinstance(expt, Number):
1802 if isinstance(expt, Float):
1803 return self._eval_evalf(expt._prec)**expt
1804 if expt.is_extended_negative:
1805 # (3/4)**-2 -> (4/3)**2
1806 ne = -expt
1807 if (ne is S.One):
1808 return Rational(self.q, self.p)
1809 if self.is_negative:
1810 return S.NegativeOne**expt*Rational(self.q, -self.p)**ne
1811 else:
1812 return Rational(self.q, self.p)**ne
1813 if expt is S.Infinity: # -oo already caught by test for negative
1814 if self.p > self.q:
1815 # (3/2)**oo -> oo
1816 return S.Infinity
1817 if self.p < -self.q:
1818 # (-3/2)**oo -> oo + I*oo
1819 return S.Infinity + S.Infinity*S.ImaginaryUnit
1820 return S.Zero
1821 if isinstance(expt, Integer):
1822 # (4/3)**2 -> 4**2 / 3**2
1823 return Rational(self.p**expt.p, self.q**expt.p, 1)
1824 if isinstance(expt, Rational):
1825 intpart = expt.p // expt.q
1826 if intpart:
1827 intpart += 1
1828 remfracpart = intpart*expt.q - expt.p
1829 ratfracpart = Rational(remfracpart, expt.q)
1830 if self.p != 1:
1831 return Integer(self.p)**expt*Integer(self.q)**ratfracpart*Rational(1, self.q**intpart, 1)
1832 return Integer(self.q)**ratfracpart*Rational(1, self.q**intpart, 1)
1833 else:
1834 remfracpart = expt.q - expt.p
1835 ratfracpart = Rational(remfracpart, expt.q)
1836 if self.p != 1:
1837 return Integer(self.p)**expt*Integer(self.q)**ratfracpart*Rational(1, self.q, 1)
1838 return Integer(self.q)**ratfracpart*Rational(1, self.q, 1)
1840 if self.is_extended_negative and expt.is_even:
1841 return (-self)**expt
1843 return
1845 def _as_mpf_val(self, prec):
1846 return mlib.from_rational(self.p, self.q, prec, rnd)
1848 def _mpmath_(self, prec, rnd):
1849 return mpmath.make_mpf(mlib.from_rational(self.p, self.q, prec, rnd))
1851 def __abs__(self):
1852 return Rational(abs(self.p), self.q)
1854 def __int__(self):
1855 p, q = self.p, self.q
1856 if p < 0:
1857 return -int(-p//q)
1858 return int(p//q)
1860 def floor(self):
1861 return Integer(self.p // self.q)
1863 def ceiling(self):
1864 return -Integer(-self.p // self.q)
1866 def __floor__(self):
1867 return self.floor()
1869 def __ceil__(self):
1870 return self.ceiling()
1872 def __eq__(self, other):
1873 try:
1874 other = _sympify(other)
1875 except SympifyError:
1876 return NotImplemented
1877 if not isinstance(other, Number):
1878 # S(0) == S.false is False
1879 # S(0) == False is True
1880 return False
1881 if not self:
1882 return not other
1883 if other.is_NumberSymbol:
1884 if other.is_irrational:
1885 return False
1886 return other.__eq__(self)
1887 if other.is_Rational:
1888 # a Rational is always in reduced form so will never be 2/4
1889 # so we can just check equivalence of args
1890 return self.p == other.p and self.q == other.q
1891 if other.is_Float:
1892 # all Floats have a denominator that is a power of 2
1893 # so if self doesn't, it can't be equal to other
1894 if self.q & (self.q - 1):
1895 return False
1896 s, m, t = other._mpf_[:3]
1897 if s:
1898 m = -m
1899 if not t:
1900 # other is an odd integer
1901 if not self.is_Integer or self.is_even:
1902 return False
1903 return m == self.p
1905 from .power import integer_log
1906 if t > 0:
1907 # other is an even integer
1908 if not self.is_Integer:
1909 return False
1910 # does m*2**t == self.p
1911 return self.p and not self.p % m and \
1912 integer_log(self.p//m, 2) == (t, True)
1913 # does non-integer s*m/2**-t = p/q?
1914 if self.is_Integer:
1915 return False
1916 return m == self.p and integer_log(self.q, 2) == (-t, True)
1917 return False
1919 def __ne__(self, other):
1920 return not self == other
1922 def _Rrel(self, other, attr):
1923 # if you want self < other, pass self, other, __gt__
1924 try:
1925 other = _sympify(other)
1926 except SympifyError:
1927 return NotImplemented
1928 if other.is_Number:
1929 op = None
1930 s, o = self, other
1931 if other.is_NumberSymbol:
1932 op = getattr(o, attr)
1933 elif other.is_Float:
1934 op = getattr(o, attr)
1935 elif other.is_Rational:
1936 s, o = Integer(s.p*o.q), Integer(s.q*o.p)
1937 op = getattr(o, attr)
1938 if op:
1939 return op(s)
1940 if o.is_number and o.is_extended_real:
1941 return Integer(s.p), s.q*o
1943 def __gt__(self, other):
1944 rv = self._Rrel(other, '__lt__')
1945 if rv is None:
1946 rv = self, other
1947 elif not isinstance(rv, tuple):
1948 return rv
1949 return Expr.__gt__(*rv)
1951 def __ge__(self, other):
1952 rv = self._Rrel(other, '__le__')
1953 if rv is None:
1954 rv = self, other
1955 elif not isinstance(rv, tuple):
1956 return rv
1957 return Expr.__ge__(*rv)
1959 def __lt__(self, other):
1960 rv = self._Rrel(other, '__gt__')
1961 if rv is None:
1962 rv = self, other
1963 elif not isinstance(rv, tuple):
1964 return rv
1965 return Expr.__lt__(*rv)
1967 def __le__(self, other):
1968 rv = self._Rrel(other, '__ge__')
1969 if rv is None:
1970 rv = self, other
1971 elif not isinstance(rv, tuple):
1972 return rv
1973 return Expr.__le__(*rv)
1975 def __hash__(self):
1976 return super().__hash__()
1978 def factors(self, limit=None, use_trial=True, use_rho=False,
1979 use_pm1=False, verbose=False, visual=False):
1980 """A wrapper to factorint which return factors of self that are
1981 smaller than limit (or cheap to compute). Special methods of
1982 factoring are disabled by default so that only trial division is used.
1983 """
1984 from sympy.ntheory.factor_ import factorrat
1986 return factorrat(self, limit=limit, use_trial=use_trial,
1987 use_rho=use_rho, use_pm1=use_pm1,
1988 verbose=verbose).copy()
1990 @property
1991 def numerator(self):
1992 return self.p
1994 @property
1995 def denominator(self):
1996 return self.q
1998 @_sympifyit('other', NotImplemented)
1999 def gcd(self, other):
2000 if isinstance(other, Rational):
2001 if other == S.Zero:
2002 return other
2003 return Rational(
2004 igcd(self.p, other.p),
2005 ilcm(self.q, other.q))
2006 return Number.gcd(self, other)
2008 @_sympifyit('other', NotImplemented)
2009 def lcm(self, other):
2010 if isinstance(other, Rational):
2011 return Rational(
2012 self.p // igcd(self.p, other.p) * other.p,
2013 igcd(self.q, other.q))
2014 return Number.lcm(self, other)
2016 def as_numer_denom(self):
2017 return Integer(self.p), Integer(self.q)
2019 def as_content_primitive(self, radical=False, clear=True):
2020 """Return the tuple (R, self/R) where R is the positive Rational
2021 extracted from self.
2023 Examples
2024 ========
2026 >>> from sympy import S
2027 >>> (S(-3)/2).as_content_primitive()
2028 (3/2, -1)
2030 See docstring of Expr.as_content_primitive for more examples.
2031 """
2033 if self:
2034 if self.is_positive:
2035 return self, S.One
2036 return -self, S.NegativeOne
2037 return S.One, self
2039 def as_coeff_Mul(self, rational=False):
2040 """Efficiently extract the coefficient of a product."""
2041 return self, S.One
2043 def as_coeff_Add(self, rational=False):
2044 """Efficiently extract the coefficient of a summation."""
2045 return self, S.Zero
2048class Integer(Rational):
2049 """Represents integer numbers of any size.
2051 Examples
2052 ========
2054 >>> from sympy import Integer
2055 >>> Integer(3)
2056 3
2058 If a float or a rational is passed to Integer, the fractional part
2059 will be discarded; the effect is of rounding toward zero.
2061 >>> Integer(3.8)
2062 3
2063 >>> Integer(-3.8)
2064 -3
2066 A string is acceptable input if it can be parsed as an integer:
2068 >>> Integer("9" * 20)
2069 99999999999999999999
2071 It is rarely needed to explicitly instantiate an Integer, because
2072 Python integers are automatically converted to Integer when they
2073 are used in SymPy expressions.
2074 """
2075 q = 1
2076 is_integer = True
2077 is_number = True
2079 is_Integer = True
2081 __slots__ = ()
2083 def _as_mpf_val(self, prec):
2084 return mlib.from_int(self.p, prec, rnd)
2086 def _mpmath_(self, prec, rnd):
2087 return mpmath.make_mpf(self._as_mpf_val(prec))
2089 @cacheit
2090 def __new__(cls, i):
2091 if isinstance(i, str):
2092 i = i.replace(' ', '')
2093 # whereas we cannot, in general, make a Rational from an
2094 # arbitrary expression, we can make an Integer unambiguously
2095 # (except when a non-integer expression happens to round to
2096 # an integer). So we proceed by taking int() of the input and
2097 # let the int routines determine whether the expression can
2098 # be made into an int or whether an error should be raised.
2099 try:
2100 ival = int(i)
2101 except TypeError:
2102 raise TypeError(
2103 "Argument of Integer should be of numeric type, got %s." % i)
2104 # We only work with well-behaved integer types. This converts, for
2105 # example, numpy.int32 instances.
2106 if ival == 1:
2107 return S.One
2108 if ival == -1:
2109 return S.NegativeOne
2110 if ival == 0:
2111 return S.Zero
2112 obj = Expr.__new__(cls)
2113 obj.p = ival
2114 return obj
2116 def __getnewargs__(self):
2117 return (self.p,)
2119 # Arithmetic operations are here for efficiency
2120 def __int__(self):
2121 return self.p
2123 def floor(self):
2124 return Integer(self.p)
2126 def ceiling(self):
2127 return Integer(self.p)
2129 def __floor__(self):
2130 return self.floor()
2132 def __ceil__(self):
2133 return self.ceiling()
2135 def __neg__(self):
2136 return Integer(-self.p)
2138 def __abs__(self):
2139 if self.p >= 0:
2140 return self
2141 else:
2142 return Integer(-self.p)
2144 def __divmod__(self, other):
2145 if isinstance(other, Integer) and global_parameters.evaluate:
2146 return Tuple(*(divmod(self.p, other.p)))
2147 else:
2148 return Number.__divmod__(self, other)
2150 def __rdivmod__(self, other):
2151 if isinstance(other, int) and global_parameters.evaluate:
2152 return Tuple(*(divmod(other, self.p)))
2153 else:
2154 try:
2155 other = Number(other)
2156 except TypeError:
2157 msg = "unsupported operand type(s) for divmod(): '%s' and '%s'"
2158 oname = type(other).__name__
2159 sname = type(self).__name__
2160 raise TypeError(msg % (oname, sname))
2161 return Number.__divmod__(other, self)
2163 # TODO make it decorator + bytecodehacks?
2164 def __add__(self, other):
2165 if global_parameters.evaluate:
2166 if isinstance(other, int):
2167 return Integer(self.p + other)
2168 elif isinstance(other, Integer):
2169 return Integer(self.p + other.p)
2170 elif isinstance(other, Rational):
2171 return Rational(self.p*other.q + other.p, other.q, 1)
2172 return Rational.__add__(self, other)
2173 else:
2174 return Add(self, other)
2176 def __radd__(self, other):
2177 if global_parameters.evaluate:
2178 if isinstance(other, int):
2179 return Integer(other + self.p)
2180 elif isinstance(other, Rational):
2181 return Rational(other.p + self.p*other.q, other.q, 1)
2182 return Rational.__radd__(self, other)
2183 return Rational.__radd__(self, other)
2185 def __sub__(self, other):
2186 if global_parameters.evaluate:
2187 if isinstance(other, int):
2188 return Integer(self.p - other)
2189 elif isinstance(other, Integer):
2190 return Integer(self.p - other.p)
2191 elif isinstance(other, Rational):
2192 return Rational(self.p*other.q - other.p, other.q, 1)
2193 return Rational.__sub__(self, other)
2194 return Rational.__sub__(self, other)
2196 def __rsub__(self, other):
2197 if global_parameters.evaluate:
2198 if isinstance(other, int):
2199 return Integer(other - self.p)
2200 elif isinstance(other, Rational):
2201 return Rational(other.p - self.p*other.q, other.q, 1)
2202 return Rational.__rsub__(self, other)
2203 return Rational.__rsub__(self, other)
2205 def __mul__(self, other):
2206 if global_parameters.evaluate:
2207 if isinstance(other, int):
2208 return Integer(self.p*other)
2209 elif isinstance(other, Integer):
2210 return Integer(self.p*other.p)
2211 elif isinstance(other, Rational):
2212 return Rational(self.p*other.p, other.q, igcd(self.p, other.q))
2213 return Rational.__mul__(self, other)
2214 return Rational.__mul__(self, other)
2216 def __rmul__(self, other):
2217 if global_parameters.evaluate:
2218 if isinstance(other, int):
2219 return Integer(other*self.p)
2220 elif isinstance(other, Rational):
2221 return Rational(other.p*self.p, other.q, igcd(self.p, other.q))
2222 return Rational.__rmul__(self, other)
2223 return Rational.__rmul__(self, other)
2225 def __mod__(self, other):
2226 if global_parameters.evaluate:
2227 if isinstance(other, int):
2228 return Integer(self.p % other)
2229 elif isinstance(other, Integer):
2230 return Integer(self.p % other.p)
2231 return Rational.__mod__(self, other)
2232 return Rational.__mod__(self, other)
2234 def __rmod__(self, other):
2235 if global_parameters.evaluate:
2236 if isinstance(other, int):
2237 return Integer(other % self.p)
2238 elif isinstance(other, Integer):
2239 return Integer(other.p % self.p)
2240 return Rational.__rmod__(self, other)
2241 return Rational.__rmod__(self, other)
2243 def __eq__(self, other):
2244 if isinstance(other, int):
2245 return (self.p == other)
2246 elif isinstance(other, Integer):
2247 return (self.p == other.p)
2248 return Rational.__eq__(self, other)
2250 def __ne__(self, other):
2251 return not self == other
2253 def __gt__(self, other):
2254 try:
2255 other = _sympify(other)
2256 except SympifyError:
2257 return NotImplemented
2258 if other.is_Integer:
2259 return _sympify(self.p > other.p)
2260 return Rational.__gt__(self, other)
2262 def __lt__(self, other):
2263 try:
2264 other = _sympify(other)
2265 except SympifyError:
2266 return NotImplemented
2267 if other.is_Integer:
2268 return _sympify(self.p < other.p)
2269 return Rational.__lt__(self, other)
2271 def __ge__(self, other):
2272 try:
2273 other = _sympify(other)
2274 except SympifyError:
2275 return NotImplemented
2276 if other.is_Integer:
2277 return _sympify(self.p >= other.p)
2278 return Rational.__ge__(self, other)
2280 def __le__(self, other):
2281 try:
2282 other = _sympify(other)
2283 except SympifyError:
2284 return NotImplemented
2285 if other.is_Integer:
2286 return _sympify(self.p <= other.p)
2287 return Rational.__le__(self, other)
2289 def __hash__(self):
2290 return hash(self.p)
2292 def __index__(self):
2293 return self.p
2295 ########################################
2297 def _eval_is_odd(self):
2298 return bool(self.p % 2)
2300 def _eval_power(self, expt):
2301 """
2302 Tries to do some simplifications on self**expt
2304 Returns None if no further simplifications can be done.
2306 Explanation
2307 ===========
2309 When exponent is a fraction (so we have for example a square root),
2310 we try to find a simpler representation by factoring the argument
2311 up to factors of 2**15, e.g.
2313 - sqrt(4) becomes 2
2314 - sqrt(-4) becomes 2*I
2315 - (2**(3+7)*3**(6+7))**Rational(1,7) becomes 6*18**(3/7)
2317 Further simplification would require a special call to factorint on
2318 the argument which is not done here for sake of speed.
2320 """
2321 from sympy.ntheory.factor_ import perfect_power
2323 if expt is S.Infinity:
2324 if self.p > S.One:
2325 return S.Infinity
2326 # cases -1, 0, 1 are done in their respective classes
2327 return S.Infinity + S.ImaginaryUnit*S.Infinity
2328 if expt is S.NegativeInfinity:
2329 return Rational(1, self, 1)**S.Infinity
2330 if not isinstance(expt, Number):
2331 # simplify when expt is even
2332 # (-2)**k --> 2**k
2333 if self.is_negative and expt.is_even:
2334 return (-self)**expt
2335 if isinstance(expt, Float):
2336 # Rational knows how to exponentiate by a Float
2337 return super()._eval_power(expt)
2338 if not isinstance(expt, Rational):
2339 return
2340 if expt is S.Half and self.is_negative:
2341 # we extract I for this special case since everyone is doing so
2342 return S.ImaginaryUnit*Pow(-self, expt)
2343 if expt.is_negative:
2344 # invert base and change sign on exponent
2345 ne = -expt
2346 if self.is_negative:
2347 return S.NegativeOne**expt*Rational(1, -self, 1)**ne
2348 else:
2349 return Rational(1, self.p, 1)**ne
2350 # see if base is a perfect root, sqrt(4) --> 2
2351 x, xexact = integer_nthroot(abs(self.p), expt.q)
2352 if xexact:
2353 # if it's a perfect root we've finished
2354 result = Integer(x**abs(expt.p))
2355 if self.is_negative:
2356 result *= S.NegativeOne**expt
2357 return result
2359 # The following is an algorithm where we collect perfect roots
2360 # from the factors of base.
2362 # if it's not an nth root, it still might be a perfect power
2363 b_pos = int(abs(self.p))
2364 p = perfect_power(b_pos)
2365 if p is not False:
2366 dict = {p[0]: p[1]}
2367 else:
2368 dict = Integer(b_pos).factors(limit=2**15)
2370 # now process the dict of factors
2371 out_int = 1 # integer part
2372 out_rad = 1 # extracted radicals
2373 sqr_int = 1
2374 sqr_gcd = 0
2375 sqr_dict = {}
2376 for prime, exponent in dict.items():
2377 exponent *= expt.p
2378 # remove multiples of expt.q: (2**12)**(1/10) -> 2*(2**2)**(1/10)
2379 div_e, div_m = divmod(exponent, expt.q)
2380 if div_e > 0:
2381 out_int *= prime**div_e
2382 if div_m > 0:
2383 # see if the reduced exponent shares a gcd with e.q
2384 # (2**2)**(1/10) -> 2**(1/5)
2385 g = igcd(div_m, expt.q)
2386 if g != 1:
2387 out_rad *= Pow(prime, Rational(div_m//g, expt.q//g, 1))
2388 else:
2389 sqr_dict[prime] = div_m
2390 # identify gcd of remaining powers
2391 for p, ex in sqr_dict.items():
2392 if sqr_gcd == 0:
2393 sqr_gcd = ex
2394 else:
2395 sqr_gcd = igcd(sqr_gcd, ex)
2396 if sqr_gcd == 1:
2397 break
2398 for k, v in sqr_dict.items():
2399 sqr_int *= k**(v//sqr_gcd)
2400 if sqr_int == b_pos and out_int == 1 and out_rad == 1:
2401 result = None
2402 else:
2403 result = out_int*out_rad*Pow(sqr_int, Rational(sqr_gcd, expt.q))
2404 if self.is_negative:
2405 result *= Pow(S.NegativeOne, expt)
2406 return result
2408 def _eval_is_prime(self):
2409 from sympy.ntheory.primetest import isprime
2411 return isprime(self)
2413 def _eval_is_composite(self):
2414 if self > 1:
2415 return fuzzy_not(self.is_prime)
2416 else:
2417 return False
2419 def as_numer_denom(self):
2420 return self, S.One
2422 @_sympifyit('other', NotImplemented)
2423 def __floordiv__(self, other):
2424 if not isinstance(other, Expr):
2425 return NotImplemented
2426 if isinstance(other, Integer):
2427 return Integer(self.p // other)
2428 return divmod(self, other)[0]
2430 def __rfloordiv__(self, other):
2431 return Integer(Integer(other).p // self.p)
2433 # These bitwise operations (__lshift__, __rlshift__, ..., __invert__) are defined
2434 # for Integer only and not for general SymPy expressions. This is to achieve
2435 # compatibility with the numbers.Integral ABC which only defines these operations
2436 # among instances of numbers.Integral. Therefore, these methods check explicitly for
2437 # integer types rather than using sympify because they should not accept arbitrary
2438 # symbolic expressions and there is no symbolic analogue of numbers.Integral's
2439 # bitwise operations.
2440 def __lshift__(self, other):
2441 if isinstance(other, (int, Integer, numbers.Integral)):
2442 return Integer(self.p << int(other))
2443 else:
2444 return NotImplemented
2446 def __rlshift__(self, other):
2447 if isinstance(other, (int, numbers.Integral)):
2448 return Integer(int(other) << self.p)
2449 else:
2450 return NotImplemented
2452 def __rshift__(self, other):
2453 if isinstance(other, (int, Integer, numbers.Integral)):
2454 return Integer(self.p >> int(other))
2455 else:
2456 return NotImplemented
2458 def __rrshift__(self, other):
2459 if isinstance(other, (int, numbers.Integral)):
2460 return Integer(int(other) >> self.p)
2461 else:
2462 return NotImplemented
2464 def __and__(self, other):
2465 if isinstance(other, (int, Integer, numbers.Integral)):
2466 return Integer(self.p & int(other))
2467 else:
2468 return NotImplemented
2470 def __rand__(self, other):
2471 if isinstance(other, (int, numbers.Integral)):
2472 return Integer(int(other) & self.p)
2473 else:
2474 return NotImplemented
2476 def __xor__(self, other):
2477 if isinstance(other, (int, Integer, numbers.Integral)):
2478 return Integer(self.p ^ int(other))
2479 else:
2480 return NotImplemented
2482 def __rxor__(self, other):
2483 if isinstance(other, (int, numbers.Integral)):
2484 return Integer(int(other) ^ self.p)
2485 else:
2486 return NotImplemented
2488 def __or__(self, other):
2489 if isinstance(other, (int, Integer, numbers.Integral)):
2490 return Integer(self.p | int(other))
2491 else:
2492 return NotImplemented
2494 def __ror__(self, other):
2495 if isinstance(other, (int, numbers.Integral)):
2496 return Integer(int(other) | self.p)
2497 else:
2498 return NotImplemented
2500 def __invert__(self):
2501 return Integer(~self.p)
2503# Add sympify converters
2504_sympy_converter[int] = Integer
2507class AlgebraicNumber(Expr):
2508 r"""
2509 Class for representing algebraic numbers in SymPy.
2511 Symbolically, an instance of this class represents an element
2512 $\alpha \in \mathbb{Q}(\theta) \hookrightarrow \mathbb{C}$. That is, the
2513 algebraic number $\alpha$ is represented as an element of a particular
2514 number field $\mathbb{Q}(\theta)$, with a particular embedding of this
2515 field into the complex numbers.
2517 Formally, the primitive element $\theta$ is given by two data points: (1)
2518 its minimal polynomial (which defines $\mathbb{Q}(\theta)$), and (2) a
2519 particular complex number that is a root of this polynomial (which defines
2520 the embedding $\mathbb{Q}(\theta) \hookrightarrow \mathbb{C}$). Finally,
2521 the algebraic number $\alpha$ which we represent is then given by the
2522 coefficients of a polynomial in $\theta$.
2523 """
2525 __slots__ = ('rep', 'root', 'alias', 'minpoly', '_own_minpoly')
2527 is_AlgebraicNumber = True
2528 is_algebraic = True
2529 is_number = True
2532 kind = NumberKind
2534 # Optional alias symbol is not free.
2535 # Actually, alias should be a Str, but some methods
2536 # expect that it be an instance of Expr.
2537 free_symbols: set[Basic] = set()
2539 def __new__(cls, expr, coeffs=None, alias=None, **args):
2540 r"""
2541 Construct a new algebraic number $\alpha$ belonging to a number field
2542 $k = \mathbb{Q}(\theta)$.
2544 There are four instance attributes to be determined:
2546 =========== ============================================================================
2547 Attribute Type/Meaning
2548 =========== ============================================================================
2549 ``root`` :py:class:`~.Expr` for $\theta$ as a complex number
2550 ``minpoly`` :py:class:`~.Poly`, the minimal polynomial of $\theta$
2551 ``rep`` :py:class:`~sympy.polys.polyclasses.DMP` giving $\alpha$ as poly in $\theta$
2552 ``alias`` :py:class:`~.Symbol` for $\theta$, or ``None``
2553 =========== ============================================================================
2555 See Parameters section for how they are determined.
2557 Parameters
2558 ==========
2560 expr : :py:class:`~.Expr`, or pair $(m, r)$
2561 There are three distinct modes of construction, depending on what
2562 is passed as *expr*.
2564 **(1)** *expr* is an :py:class:`~.AlgebraicNumber`:
2565 In this case we begin by copying all four instance attributes from
2566 *expr*. If *coeffs* were also given, we compose the two coeff
2567 polynomials (see below). If an *alias* was given, it overrides.
2569 **(2)** *expr* is any other type of :py:class:`~.Expr`:
2570 Then ``root`` will equal *expr*. Therefore it
2571 must express an algebraic quantity, and we will compute its
2572 ``minpoly``.
2574 **(3)** *expr* is an ordered pair $(m, r)$ giving the
2575 ``minpoly`` $m$, and a ``root`` $r$ thereof, which together
2576 define $\theta$. In this case $m$ may be either a univariate
2577 :py:class:`~.Poly` or any :py:class:`~.Expr` which represents the
2578 same, while $r$ must be some :py:class:`~.Expr` representing a
2579 complex number that is a root of $m$, including both explicit
2580 expressions in radicals, and instances of
2581 :py:class:`~.ComplexRootOf` or :py:class:`~.AlgebraicNumber`.
2583 coeffs : list, :py:class:`~.ANP`, None, optional (default=None)
2584 This defines ``rep``, giving the algebraic number $\alpha$ as a
2585 polynomial in $\theta$.
2587 If a list, the elements should be integers or rational numbers.
2588 If an :py:class:`~.ANP`, we take its coefficients (using its
2589 :py:meth:`~.ANP.to_list()` method). If ``None``, then the list of
2590 coefficients defaults to ``[1, 0]``, meaning that $\alpha = \theta$
2591 is the primitive element of the field.
2593 If *expr* was an :py:class:`~.AlgebraicNumber`, let $g(x)$ be its
2594 ``rep`` polynomial, and let $f(x)$ be the polynomial defined by
2595 *coeffs*. Then ``self.rep`` will represent the composition
2596 $(f \circ g)(x)$.
2598 alias : str, :py:class:`~.Symbol`, None, optional (default=None)
2599 This is a way to provide a name for the primitive element. We
2600 described several ways in which the *expr* argument can define the
2601 value of the primitive element, but none of these methods gave it
2602 a name. Here, for example, *alias* could be set as
2603 ``Symbol('theta')``, in order to make this symbol appear when
2604 $\alpha$ is printed, or rendered as a polynomial, using the
2605 :py:meth:`~.as_poly()` method.
2607 Examples
2608 ========
2610 Recall that we are constructing an algebraic number as a field element
2611 $\alpha \in \mathbb{Q}(\theta)$.
2613 >>> from sympy import AlgebraicNumber, sqrt, CRootOf, S
2614 >>> from sympy.abc import x
2616 Example (1): $\alpha = \theta = \sqrt{2}$
2618 >>> a1 = AlgebraicNumber(sqrt(2))
2619 >>> a1.minpoly_of_element().as_expr(x)
2620 x**2 - 2
2621 >>> a1.evalf(10)
2622 1.414213562
2624 Example (2): $\alpha = 3 \sqrt{2} - 5$, $\theta = \sqrt{2}$. We can
2625 either build on the last example:
2627 >>> a2 = AlgebraicNumber(a1, [3, -5])
2628 >>> a2.as_expr()
2629 -5 + 3*sqrt(2)
2631 or start from scratch:
2633 >>> a2 = AlgebraicNumber(sqrt(2), [3, -5])
2634 >>> a2.as_expr()
2635 -5 + 3*sqrt(2)
2637 Example (3): $\alpha = 6 \sqrt{2} - 11$, $\theta = \sqrt{2}$. Again we
2638 can build on the previous example, and we see that the coeff polys are
2639 composed:
2641 >>> a3 = AlgebraicNumber(a2, [2, -1])
2642 >>> a3.as_expr()
2643 -11 + 6*sqrt(2)
2645 reflecting the fact that $(2x - 1) \circ (3x - 5) = 6x - 11$.
2647 Example (4): $\alpha = \sqrt{2}$, $\theta = \sqrt{2} + \sqrt{3}$. The
2648 easiest way is to use the :py:func:`~.to_number_field()` function:
2650 >>> from sympy import to_number_field
2651 >>> a4 = to_number_field(sqrt(2), sqrt(2) + sqrt(3))
2652 >>> a4.minpoly_of_element().as_expr(x)
2653 x**2 - 2
2654 >>> a4.to_root()
2655 sqrt(2)
2656 >>> a4.primitive_element()
2657 sqrt(2) + sqrt(3)
2658 >>> a4.coeffs()
2659 [1/2, 0, -9/2, 0]
2661 but if you already knew the right coefficients, you could construct it
2662 directly:
2664 >>> a4 = AlgebraicNumber(sqrt(2) + sqrt(3), [S(1)/2, 0, S(-9)/2, 0])
2665 >>> a4.to_root()
2666 sqrt(2)
2667 >>> a4.primitive_element()
2668 sqrt(2) + sqrt(3)
2670 Example (5): Construct the Golden Ratio as an element of the 5th
2671 cyclotomic field, supposing we already know its coefficients. This time
2672 we introduce the alias $\zeta$ for the primitive element of the field:
2674 >>> from sympy import cyclotomic_poly
2675 >>> from sympy.abc import zeta
2676 >>> a5 = AlgebraicNumber(CRootOf(cyclotomic_poly(5), -1),
2677 ... [-1, -1, 0, 0], alias=zeta)
2678 >>> a5.as_poly().as_expr()
2679 -zeta**3 - zeta**2
2680 >>> a5.evalf()
2681 1.61803398874989
2683 (The index ``-1`` to ``CRootOf`` selects the complex root with the
2684 largest real and imaginary parts, which in this case is
2685 $\mathrm{e}^{2i\pi/5}$. See :py:class:`~.ComplexRootOf`.)
2687 Example (6): Building on the last example, construct the number
2688 $2 \phi \in \mathbb{Q}(\phi)$, where $\phi$ is the Golden Ratio:
2690 >>> from sympy.abc import phi
2691 >>> a6 = AlgebraicNumber(a5.to_root(), coeffs=[2, 0], alias=phi)
2692 >>> a6.as_poly().as_expr()
2693 2*phi
2694 >>> a6.primitive_element().evalf()
2695 1.61803398874989
2697 Note that we needed to use ``a5.to_root()``, since passing ``a5`` as
2698 the first argument would have constructed the number $2 \phi$ as an
2699 element of the field $\mathbb{Q}(\zeta)$:
2701 >>> a6_wrong = AlgebraicNumber(a5, coeffs=[2, 0])
2702 >>> a6_wrong.as_poly().as_expr()
2703 -2*zeta**3 - 2*zeta**2
2704 >>> a6_wrong.primitive_element().evalf()
2705 0.309016994374947 + 0.951056516295154*I
2707 """
2708 from sympy.polys.polyclasses import ANP, DMP
2709 from sympy.polys.numberfields import minimal_polynomial
2711 expr = sympify(expr)
2712 rep0 = None
2713 alias0 = None
2715 if isinstance(expr, (tuple, Tuple)):
2716 minpoly, root = expr
2718 if not minpoly.is_Poly:
2719 from sympy.polys.polytools import Poly
2720 minpoly = Poly(minpoly)
2721 elif expr.is_AlgebraicNumber:
2722 minpoly, root, rep0, alias0 = (expr.minpoly, expr.root,
2723 expr.rep, expr.alias)
2724 else:
2725 minpoly, root = minimal_polynomial(
2726 expr, args.get('gen'), polys=True), expr
2728 dom = minpoly.get_domain()
2730 if coeffs is not None:
2731 if not isinstance(coeffs, ANP):
2732 rep = DMP.from_sympy_list(sympify(coeffs), 0, dom)
2733 scoeffs = Tuple(*coeffs)
2734 else:
2735 rep = DMP.from_list(coeffs.to_list(), 0, dom)
2736 scoeffs = Tuple(*coeffs.to_list())
2738 else:
2739 rep = DMP.from_list([1, 0], 0, dom)
2740 scoeffs = Tuple(1, 0)
2742 if rep0 is not None:
2743 from sympy.polys.densetools import dup_compose
2744 c = dup_compose(rep.rep, rep0.rep, dom)
2745 rep = DMP.from_list(c, 0, dom)
2746 scoeffs = Tuple(*c)
2748 if rep.degree() >= minpoly.degree():
2749 rep = rep.rem(minpoly.rep)
2751 sargs = (root, scoeffs)
2753 alias = alias or alias0
2754 if alias is not None:
2755 from .symbol import Symbol
2756 if not isinstance(alias, Symbol):
2757 alias = Symbol(alias)
2758 sargs = sargs + (alias,)
2760 obj = Expr.__new__(cls, *sargs)
2762 obj.rep = rep
2763 obj.root = root
2764 obj.alias = alias
2765 obj.minpoly = minpoly
2767 obj._own_minpoly = None
2769 return obj
2771 def __hash__(self):
2772 return super().__hash__()
2774 def _eval_evalf(self, prec):
2775 return self.as_expr()._evalf(prec)
2777 @property
2778 def is_aliased(self):
2779 """Returns ``True`` if ``alias`` was set. """
2780 return self.alias is not None
2782 def as_poly(self, x=None):
2783 """Create a Poly instance from ``self``. """
2784 from sympy.polys.polytools import Poly, PurePoly
2785 if x is not None:
2786 return Poly.new(self.rep, x)
2787 else:
2788 if self.alias is not None:
2789 return Poly.new(self.rep, self.alias)
2790 else:
2791 from .symbol import Dummy
2792 return PurePoly.new(self.rep, Dummy('x'))
2794 def as_expr(self, x=None):
2795 """Create a Basic expression from ``self``. """
2796 return self.as_poly(x or self.root).as_expr().expand()
2798 def coeffs(self):
2799 """Returns all SymPy coefficients of an algebraic number. """
2800 return [ self.rep.dom.to_sympy(c) for c in self.rep.all_coeffs() ]
2802 def native_coeffs(self):
2803 """Returns all native coefficients of an algebraic number. """
2804 return self.rep.all_coeffs()
2806 def to_algebraic_integer(self):
2807 """Convert ``self`` to an algebraic integer. """
2808 from sympy.polys.polytools import Poly
2810 f = self.minpoly
2812 if f.LC() == 1:
2813 return self
2815 coeff = f.LC()**(f.degree() - 1)
2816 poly = f.compose(Poly(f.gen/f.LC()))
2818 minpoly = poly*coeff
2819 root = f.LC()*self.root
2821 return AlgebraicNumber((minpoly, root), self.coeffs())
2823 def _eval_simplify(self, **kwargs):
2824 from sympy.polys.rootoftools import CRootOf
2825 from sympy.polys import minpoly
2826 measure, ratio = kwargs['measure'], kwargs['ratio']
2827 for r in [r for r in self.minpoly.all_roots() if r.func != CRootOf]:
2828 if minpoly(self.root - r).is_Symbol:
2829 # use the matching root if it's simpler
2830 if measure(r) < ratio*measure(self.root):
2831 return AlgebraicNumber(r)
2832 return self
2834 def field_element(self, coeffs):
2835 r"""
2836 Form another element of the same number field.
2838 Explanation
2839 ===========
2841 If we represent $\alpha \in \mathbb{Q}(\theta)$, form another element
2842 $\beta \in \mathbb{Q}(\theta)$ of the same number field.
2844 Parameters
2845 ==========
2847 coeffs : list, :py:class:`~.ANP`
2848 Like the *coeffs* arg to the class
2849 :py:meth:`constructor<.AlgebraicNumber.__new__>`, defines the
2850 new element as a polynomial in the primitive element.
2852 If a list, the elements should be integers or rational numbers.
2853 If an :py:class:`~.ANP`, we take its coefficients (using its
2854 :py:meth:`~.ANP.to_list()` method).
2856 Examples
2857 ========
2859 >>> from sympy import AlgebraicNumber, sqrt
2860 >>> a = AlgebraicNumber(sqrt(5), [-1, 1])
2861 >>> b = a.field_element([3, 2])
2862 >>> print(a)
2863 1 - sqrt(5)
2864 >>> print(b)
2865 2 + 3*sqrt(5)
2866 >>> print(b.primitive_element() == a.primitive_element())
2867 True
2869 See Also
2870 ========
2872 AlgebraicNumber
2873 """
2874 return AlgebraicNumber(
2875 (self.minpoly, self.root), coeffs=coeffs, alias=self.alias)
2877 @property
2878 def is_primitive_element(self):
2879 r"""
2880 Say whether this algebraic number $\alpha \in \mathbb{Q}(\theta)$ is
2881 equal to the primitive element $\theta$ for its field.
2882 """
2883 c = self.coeffs()
2884 # Second case occurs if self.minpoly is linear:
2885 return c == [1, 0] or c == [self.root]
2887 def primitive_element(self):
2888 r"""
2889 Get the primitive element $\theta$ for the number field
2890 $\mathbb{Q}(\theta)$ to which this algebraic number $\alpha$ belongs.
2892 Returns
2893 =======
2895 AlgebraicNumber
2897 """
2898 if self.is_primitive_element:
2899 return self
2900 return self.field_element([1, 0])
2902 def to_primitive_element(self, radicals=True):
2903 r"""
2904 Convert ``self`` to an :py:class:`~.AlgebraicNumber` instance that is
2905 equal to its own primitive element.
2907 Explanation
2908 ===========
2910 If we represent $\alpha \in \mathbb{Q}(\theta)$, $\alpha \neq \theta$,
2911 construct a new :py:class:`~.AlgebraicNumber` that represents
2912 $\alpha \in \mathbb{Q}(\alpha)$.
2914 Examples
2915 ========
2917 >>> from sympy import sqrt, to_number_field
2918 >>> from sympy.abc import x
2919 >>> a = to_number_field(sqrt(2), sqrt(2) + sqrt(3))
2921 The :py:class:`~.AlgebraicNumber` ``a`` represents the number
2922 $\sqrt{2}$ in the field $\mathbb{Q}(\sqrt{2} + \sqrt{3})$. Rendering
2923 ``a`` as a polynomial,
2925 >>> a.as_poly().as_expr(x)
2926 x**3/2 - 9*x/2
2928 reflects the fact that $\sqrt{2} = \theta^3/2 - 9 \theta/2$, where
2929 $\theta = \sqrt{2} + \sqrt{3}$.
2931 ``a`` is not equal to its own primitive element. Its minpoly
2933 >>> a.minpoly.as_poly().as_expr(x)
2934 x**4 - 10*x**2 + 1
2936 is that of $\theta$.
2938 Converting to a primitive element,
2940 >>> a_prim = a.to_primitive_element()
2941 >>> a_prim.minpoly.as_poly().as_expr(x)
2942 x**2 - 2
2944 we obtain an :py:class:`~.AlgebraicNumber` whose ``minpoly`` is that of
2945 the number itself.
2947 Parameters
2948 ==========
2950 radicals : boolean, optional (default=True)
2951 If ``True``, then we will try to return an
2952 :py:class:`~.AlgebraicNumber` whose ``root`` is an expression
2953 in radicals. If that is not possible (or if *radicals* is
2954 ``False``), ``root`` will be a :py:class:`~.ComplexRootOf`.
2956 Returns
2957 =======
2959 AlgebraicNumber
2961 See Also
2962 ========
2964 is_primitive_element
2966 """
2967 if self.is_primitive_element:
2968 return self
2969 m = self.minpoly_of_element()
2970 r = self.to_root(radicals=radicals)
2971 return AlgebraicNumber((m, r))
2973 def minpoly_of_element(self):
2974 r"""
2975 Compute the minimal polynomial for this algebraic number.
2977 Explanation
2978 ===========
2980 Recall that we represent an element $\alpha \in \mathbb{Q}(\theta)$.
2981 Our instance attribute ``self.minpoly`` is the minimal polynomial for
2982 our primitive element $\theta$. This method computes the minimal
2983 polynomial for $\alpha$.
2985 """
2986 if self._own_minpoly is None:
2987 if self.is_primitive_element:
2988 self._own_minpoly = self.minpoly
2989 else:
2990 from sympy.polys.numberfields.minpoly import minpoly
2991 theta = self.primitive_element()
2992 self._own_minpoly = minpoly(self.as_expr(theta), polys=True)
2993 return self._own_minpoly
2995 def to_root(self, radicals=True, minpoly=None):
2996 """
2997 Convert to an :py:class:`~.Expr` that is not an
2998 :py:class:`~.AlgebraicNumber`, specifically, either a
2999 :py:class:`~.ComplexRootOf`, or, optionally and where possible, an
3000 expression in radicals.
3002 Parameters
3003 ==========
3005 radicals : boolean, optional (default=True)
3006 If ``True``, then we will try to return the root as an expression
3007 in radicals. If that is not possible, we will return a
3008 :py:class:`~.ComplexRootOf`.
3010 minpoly : :py:class:`~.Poly`
3011 If the minimal polynomial for `self` has been pre-computed, it can
3012 be passed in order to save time.
3014 """
3015 if self.is_primitive_element and not isinstance(self.root, AlgebraicNumber):
3016 return self.root
3017 m = minpoly or self.minpoly_of_element()
3018 roots = m.all_roots(radicals=radicals)
3019 if len(roots) == 1:
3020 return roots[0]
3021 ex = self.as_expr()
3022 for b in roots:
3023 if m.same_root(b, ex):
3024 return b
3027class RationalConstant(Rational):
3028 """
3029 Abstract base class for rationals with specific behaviors
3031 Derived classes must define class attributes p and q and should probably all
3032 be singletons.
3033 """
3034 __slots__ = ()
3036 def __new__(cls):
3037 return AtomicExpr.__new__(cls)
3040class IntegerConstant(Integer):
3041 __slots__ = ()
3043 def __new__(cls):
3044 return AtomicExpr.__new__(cls)
3047class Zero(IntegerConstant, metaclass=Singleton):
3048 """The number zero.
3050 Zero is a singleton, and can be accessed by ``S.Zero``
3052 Examples
3053 ========
3055 >>> from sympy import S, Integer
3056 >>> Integer(0) is S.Zero
3057 True
3058 >>> 1/S.Zero
3059 zoo
3061 References
3062 ==========
3064 .. [1] https://en.wikipedia.org/wiki/Zero
3065 """
3067 p = 0
3068 q = 1
3069 is_positive = False
3070 is_negative = False
3071 is_zero = True
3072 is_number = True
3073 is_comparable = True
3075 __slots__ = ()
3077 def __getnewargs__(self):
3078 return ()
3080 @staticmethod
3081 def __abs__():
3082 return S.Zero
3084 @staticmethod
3085 def __neg__():
3086 return S.Zero
3088 def _eval_power(self, expt):
3089 if expt.is_extended_positive:
3090 return self
3091 if expt.is_extended_negative:
3092 return S.ComplexInfinity
3093 if expt.is_extended_real is False:
3094 return S.NaN
3095 if expt.is_zero:
3096 return S.One
3098 # infinities are already handled with pos and neg
3099 # tests above; now throw away leading numbers on Mul
3100 # exponent since 0**-x = zoo**x even when x == 0
3101 coeff, terms = expt.as_coeff_Mul()
3102 if coeff.is_negative:
3103 return S.ComplexInfinity**terms
3104 if coeff is not S.One: # there is a Number to discard
3105 return self**terms
3107 def _eval_order(self, *symbols):
3108 # Order(0,x) -> 0
3109 return self
3111 def __bool__(self):
3112 return False
3115class One(IntegerConstant, metaclass=Singleton):
3116 """The number one.
3118 One is a singleton, and can be accessed by ``S.One``.
3120 Examples
3121 ========
3123 >>> from sympy import S, Integer
3124 >>> Integer(1) is S.One
3125 True
3127 References
3128 ==========
3130 .. [1] https://en.wikipedia.org/wiki/1_%28number%29
3131 """
3132 is_number = True
3133 is_positive = True
3135 p = 1
3136 q = 1
3138 __slots__ = ()
3140 def __getnewargs__(self):
3141 return ()
3143 @staticmethod
3144 def __abs__():
3145 return S.One
3147 @staticmethod
3148 def __neg__():
3149 return S.NegativeOne
3151 def _eval_power(self, expt):
3152 return self
3154 def _eval_order(self, *symbols):
3155 return
3157 @staticmethod
3158 def factors(limit=None, use_trial=True, use_rho=False, use_pm1=False,
3159 verbose=False, visual=False):
3160 if visual:
3161 return S.One
3162 else:
3163 return {}
3166class NegativeOne(IntegerConstant, metaclass=Singleton):
3167 """The number negative one.
3169 NegativeOne is a singleton, and can be accessed by ``S.NegativeOne``.
3171 Examples
3172 ========
3174 >>> from sympy import S, Integer
3175 >>> Integer(-1) is S.NegativeOne
3176 True
3178 See Also
3179 ========
3181 One
3183 References
3184 ==========
3186 .. [1] https://en.wikipedia.org/wiki/%E2%88%921_%28number%29
3188 """
3189 is_number = True
3191 p = -1
3192 q = 1
3194 __slots__ = ()
3196 def __getnewargs__(self):
3197 return ()
3199 @staticmethod
3200 def __abs__():
3201 return S.One
3203 @staticmethod
3204 def __neg__():
3205 return S.One
3207 def _eval_power(self, expt):
3208 if expt.is_odd:
3209 return S.NegativeOne
3210 if expt.is_even:
3211 return S.One
3212 if isinstance(expt, Number):
3213 if isinstance(expt, Float):
3214 return Float(-1.0)**expt
3215 if expt is S.NaN:
3216 return S.NaN
3217 if expt in (S.Infinity, S.NegativeInfinity):
3218 return S.NaN
3219 if expt is S.Half:
3220 return S.ImaginaryUnit
3221 if isinstance(expt, Rational):
3222 if expt.q == 2:
3223 return S.ImaginaryUnit**Integer(expt.p)
3224 i, r = divmod(expt.p, expt.q)
3225 if i:
3226 return self**i*self**Rational(r, expt.q)
3227 return
3230class Half(RationalConstant, metaclass=Singleton):
3231 """The rational number 1/2.
3233 Half is a singleton, and can be accessed by ``S.Half``.
3235 Examples
3236 ========
3238 >>> from sympy import S, Rational
3239 >>> Rational(1, 2) is S.Half
3240 True
3242 References
3243 ==========
3245 .. [1] https://en.wikipedia.org/wiki/One_half
3246 """
3247 is_number = True
3249 p = 1
3250 q = 2
3252 __slots__ = ()
3254 def __getnewargs__(self):
3255 return ()
3257 @staticmethod
3258 def __abs__():
3259 return S.Half
3262class Infinity(Number, metaclass=Singleton):
3263 r"""Positive infinite quantity.
3265 Explanation
3266 ===========
3268 In real analysis the symbol `\infty` denotes an unbounded
3269 limit: `x\to\infty` means that `x` grows without bound.
3271 Infinity is often used not only to define a limit but as a value
3272 in the affinely extended real number system. Points labeled `+\infty`
3273 and `-\infty` can be added to the topological space of the real numbers,
3274 producing the two-point compactification of the real numbers. Adding
3275 algebraic properties to this gives us the extended real numbers.
3277 Infinity is a singleton, and can be accessed by ``S.Infinity``,
3278 or can be imported as ``oo``.
3280 Examples
3281 ========
3283 >>> from sympy import oo, exp, limit, Symbol
3284 >>> 1 + oo
3285 oo
3286 >>> 42/oo
3287 0
3288 >>> x = Symbol('x')
3289 >>> limit(exp(x), x, oo)
3290 oo
3292 See Also
3293 ========
3295 NegativeInfinity, NaN
3297 References
3298 ==========
3300 .. [1] https://en.wikipedia.org/wiki/Infinity
3301 """
3303 is_commutative = True
3304 is_number = True
3305 is_complex = False
3306 is_extended_real = True
3307 is_infinite = True
3308 is_comparable = True
3309 is_extended_positive = True
3310 is_prime = False
3312 __slots__ = ()
3314 def __new__(cls):
3315 return AtomicExpr.__new__(cls)
3317 def _latex(self, printer):
3318 return r"\infty"
3320 def _eval_subs(self, old, new):
3321 if self == old:
3322 return new
3324 def _eval_evalf(self, prec=None):
3325 return Float('inf')
3327 def evalf(self, prec=None, **options):
3328 return self._eval_evalf(prec)
3330 @_sympifyit('other', NotImplemented)
3331 def __add__(self, other):
3332 if isinstance(other, Number) and global_parameters.evaluate:
3333 if other in (S.NegativeInfinity, S.NaN):
3334 return S.NaN
3335 return self
3336 return Number.__add__(self, other)
3337 __radd__ = __add__
3339 @_sympifyit('other', NotImplemented)
3340 def __sub__(self, other):
3341 if isinstance(other, Number) and global_parameters.evaluate:
3342 if other in (S.Infinity, S.NaN):
3343 return S.NaN
3344 return self
3345 return Number.__sub__(self, other)
3347 @_sympifyit('other', NotImplemented)
3348 def __rsub__(self, other):
3349 return (-self).__add__(other)
3351 @_sympifyit('other', NotImplemented)
3352 def __mul__(self, other):
3353 if isinstance(other, Number) and global_parameters.evaluate:
3354 if other.is_zero or other is S.NaN:
3355 return S.NaN
3356 if other.is_extended_positive:
3357 return self
3358 return S.NegativeInfinity
3359 return Number.__mul__(self, other)
3360 __rmul__ = __mul__
3362 @_sympifyit('other', NotImplemented)
3363 def __truediv__(self, other):
3364 if isinstance(other, Number) and global_parameters.evaluate:
3365 if other is S.Infinity or \
3366 other is S.NegativeInfinity or \
3367 other is S.NaN:
3368 return S.NaN
3369 if other.is_extended_nonnegative:
3370 return self
3371 return S.NegativeInfinity
3372 return Number.__truediv__(self, other)
3374 def __abs__(self):
3375 return S.Infinity
3377 def __neg__(self):
3378 return S.NegativeInfinity
3380 def _eval_power(self, expt):
3381 """
3382 ``expt`` is symbolic object but not equal to 0 or 1.
3384 ================ ======= ==============================
3385 Expression Result Notes
3386 ================ ======= ==============================
3387 ``oo ** nan`` ``nan``
3388 ``oo ** -p`` ``0`` ``p`` is number, ``oo``
3389 ================ ======= ==============================
3391 See Also
3392 ========
3393 Pow
3394 NaN
3395 NegativeInfinity
3397 """
3398 if expt.is_extended_positive:
3399 return S.Infinity
3400 if expt.is_extended_negative:
3401 return S.Zero
3402 if expt is S.NaN:
3403 return S.NaN
3404 if expt is S.ComplexInfinity:
3405 return S.NaN
3406 if expt.is_extended_real is False and expt.is_number:
3407 from sympy.functions.elementary.complexes import re
3408 expt_real = re(expt)
3409 if expt_real.is_positive:
3410 return S.ComplexInfinity
3411 if expt_real.is_negative:
3412 return S.Zero
3413 if expt_real.is_zero:
3414 return S.NaN
3416 return self**expt.evalf()
3418 def _as_mpf_val(self, prec):
3419 return mlib.finf
3421 def __hash__(self):
3422 return super().__hash__()
3424 def __eq__(self, other):
3425 return other is S.Infinity or other == float('inf')
3427 def __ne__(self, other):
3428 return other is not S.Infinity and other != float('inf')
3430 __gt__ = Expr.__gt__
3431 __ge__ = Expr.__ge__
3432 __lt__ = Expr.__lt__
3433 __le__ = Expr.__le__
3435 @_sympifyit('other', NotImplemented)
3436 def __mod__(self, other):
3437 if not isinstance(other, Expr):
3438 return NotImplemented
3439 return S.NaN
3441 __rmod__ = __mod__
3443 def floor(self):
3444 return self
3446 def ceiling(self):
3447 return self
3449oo = S.Infinity
3452class NegativeInfinity(Number, metaclass=Singleton):
3453 """Negative infinite quantity.
3455 NegativeInfinity is a singleton, and can be accessed
3456 by ``S.NegativeInfinity``.
3458 See Also
3459 ========
3461 Infinity
3462 """
3464 is_extended_real = True
3465 is_complex = False
3466 is_commutative = True
3467 is_infinite = True
3468 is_comparable = True
3469 is_extended_negative = True
3470 is_number = True
3471 is_prime = False
3473 __slots__ = ()
3475 def __new__(cls):
3476 return AtomicExpr.__new__(cls)
3478 def _latex(self, printer):
3479 return r"-\infty"
3481 def _eval_subs(self, old, new):
3482 if self == old:
3483 return new
3485 def _eval_evalf(self, prec=None):
3486 return Float('-inf')
3488 def evalf(self, prec=None, **options):
3489 return self._eval_evalf(prec)
3491 @_sympifyit('other', NotImplemented)
3492 def __add__(self, other):
3493 if isinstance(other, Number) and global_parameters.evaluate:
3494 if other in (S.Infinity, S.NaN):
3495 return S.NaN
3496 return self
3497 return Number.__add__(self, other)
3498 __radd__ = __add__
3500 @_sympifyit('other', NotImplemented)
3501 def __sub__(self, other):
3502 if isinstance(other, Number) and global_parameters.evaluate:
3503 if other in (S.NegativeInfinity, S.NaN):
3504 return S.NaN
3505 return self
3506 return Number.__sub__(self, other)
3508 @_sympifyit('other', NotImplemented)
3509 def __rsub__(self, other):
3510 return (-self).__add__(other)
3512 @_sympifyit('other', NotImplemented)
3513 def __mul__(self, other):
3514 if isinstance(other, Number) and global_parameters.evaluate:
3515 if other.is_zero or other is S.NaN:
3516 return S.NaN
3517 if other.is_extended_positive:
3518 return self
3519 return S.Infinity
3520 return Number.__mul__(self, other)
3521 __rmul__ = __mul__
3523 @_sympifyit('other', NotImplemented)
3524 def __truediv__(self, other):
3525 if isinstance(other, Number) and global_parameters.evaluate:
3526 if other is S.Infinity or \
3527 other is S.NegativeInfinity or \
3528 other is S.NaN:
3529 return S.NaN
3530 if other.is_extended_nonnegative:
3531 return self
3532 return S.Infinity
3533 return Number.__truediv__(self, other)
3535 def __abs__(self):
3536 return S.Infinity
3538 def __neg__(self):
3539 return S.Infinity
3541 def _eval_power(self, expt):
3542 """
3543 ``expt`` is symbolic object but not equal to 0 or 1.
3545 ================ ======= ==============================
3546 Expression Result Notes
3547 ================ ======= ==============================
3548 ``(-oo) ** nan`` ``nan``
3549 ``(-oo) ** oo`` ``nan``
3550 ``(-oo) ** -oo`` ``nan``
3551 ``(-oo) ** e`` ``oo`` ``e`` is positive even integer
3552 ``(-oo) ** o`` ``-oo`` ``o`` is positive odd integer
3553 ================ ======= ==============================
3555 See Also
3556 ========
3558 Infinity
3559 Pow
3560 NaN
3562 """
3563 if expt.is_number:
3564 if expt is S.NaN or \
3565 expt is S.Infinity or \
3566 expt is S.NegativeInfinity:
3567 return S.NaN
3569 if isinstance(expt, Integer) and expt.is_extended_positive:
3570 if expt.is_odd:
3571 return S.NegativeInfinity
3572 else:
3573 return S.Infinity
3575 inf_part = S.Infinity**expt
3576 s_part = S.NegativeOne**expt
3577 if inf_part == 0 and s_part.is_finite:
3578 return inf_part
3579 if (inf_part is S.ComplexInfinity and
3580 s_part.is_finite and not s_part.is_zero):
3581 return S.ComplexInfinity
3582 return s_part*inf_part
3584 def _as_mpf_val(self, prec):
3585 return mlib.fninf
3587 def __hash__(self):
3588 return super().__hash__()
3590 def __eq__(self, other):
3591 return other is S.NegativeInfinity or other == float('-inf')
3593 def __ne__(self, other):
3594 return other is not S.NegativeInfinity and other != float('-inf')
3596 __gt__ = Expr.__gt__
3597 __ge__ = Expr.__ge__
3598 __lt__ = Expr.__lt__
3599 __le__ = Expr.__le__
3601 @_sympifyit('other', NotImplemented)
3602 def __mod__(self, other):
3603 if not isinstance(other, Expr):
3604 return NotImplemented
3605 return S.NaN
3607 __rmod__ = __mod__
3609 def floor(self):
3610 return self
3612 def ceiling(self):
3613 return self
3615 def as_powers_dict(self):
3616 return {S.NegativeOne: 1, S.Infinity: 1}
3619class NaN(Number, metaclass=Singleton):
3620 """
3621 Not a Number.
3623 Explanation
3624 ===========
3626 This serves as a place holder for numeric values that are indeterminate.
3627 Most operations on NaN, produce another NaN. Most indeterminate forms,
3628 such as ``0/0`` or ``oo - oo` produce NaN. Two exceptions are ``0**0``
3629 and ``oo**0``, which all produce ``1`` (this is consistent with Python's
3630 float).
3632 NaN is loosely related to floating point nan, which is defined in the
3633 IEEE 754 floating point standard, and corresponds to the Python
3634 ``float('nan')``. Differences are noted below.
3636 NaN is mathematically not equal to anything else, even NaN itself. This
3637 explains the initially counter-intuitive results with ``Eq`` and ``==`` in
3638 the examples below.
3640 NaN is not comparable so inequalities raise a TypeError. This is in
3641 contrast with floating point nan where all inequalities are false.
3643 NaN is a singleton, and can be accessed by ``S.NaN``, or can be imported
3644 as ``nan``.
3646 Examples
3647 ========
3649 >>> from sympy import nan, S, oo, Eq
3650 >>> nan is S.NaN
3651 True
3652 >>> oo - oo
3653 nan
3654 >>> nan + 1
3655 nan
3656 >>> Eq(nan, nan) # mathematical equality
3657 False
3658 >>> nan == nan # structural equality
3659 True
3661 References
3662 ==========
3664 .. [1] https://en.wikipedia.org/wiki/NaN
3666 """
3667 is_commutative = True
3668 is_extended_real = None
3669 is_real = None
3670 is_rational = None
3671 is_algebraic = None
3672 is_transcendental = None
3673 is_integer = None
3674 is_comparable = False
3675 is_finite = None
3676 is_zero = None
3677 is_prime = None
3678 is_positive = None
3679 is_negative = None
3680 is_number = True
3682 __slots__ = ()
3684 def __new__(cls):
3685 return AtomicExpr.__new__(cls)
3687 def _latex(self, printer):
3688 return r"\text{NaN}"
3690 def __neg__(self):
3691 return self
3693 @_sympifyit('other', NotImplemented)
3694 def __add__(self, other):
3695 return self
3697 @_sympifyit('other', NotImplemented)
3698 def __sub__(self, other):
3699 return self
3701 @_sympifyit('other', NotImplemented)
3702 def __mul__(self, other):
3703 return self
3705 @_sympifyit('other', NotImplemented)
3706 def __truediv__(self, other):
3707 return self
3709 def floor(self):
3710 return self
3712 def ceiling(self):
3713 return self
3715 def _as_mpf_val(self, prec):
3716 return _mpf_nan
3718 def __hash__(self):
3719 return super().__hash__()
3721 def __eq__(self, other):
3722 # NaN is structurally equal to another NaN
3723 return other is S.NaN
3725 def __ne__(self, other):
3726 return other is not S.NaN
3728 # Expr will _sympify and raise TypeError
3729 __gt__ = Expr.__gt__
3730 __ge__ = Expr.__ge__
3731 __lt__ = Expr.__lt__
3732 __le__ = Expr.__le__
3734nan = S.NaN
3736@dispatch(NaN, Expr) # type:ignore
3737def _eval_is_eq(a, b): # noqa:F811
3738 return False
3741class ComplexInfinity(AtomicExpr, metaclass=Singleton):
3742 r"""Complex infinity.
3744 Explanation
3745 ===========
3747 In complex analysis the symbol `\tilde\infty`, called "complex
3748 infinity", represents a quantity with infinite magnitude, but
3749 undetermined complex phase.
3751 ComplexInfinity is a singleton, and can be accessed by
3752 ``S.ComplexInfinity``, or can be imported as ``zoo``.
3754 Examples
3755 ========
3757 >>> from sympy import zoo
3758 >>> zoo + 42
3759 zoo
3760 >>> 42/zoo
3761 0
3762 >>> zoo + zoo
3763 nan
3764 >>> zoo*zoo
3765 zoo
3767 See Also
3768 ========
3770 Infinity
3771 """
3773 is_commutative = True
3774 is_infinite = True
3775 is_number = True
3776 is_prime = False
3777 is_complex = False
3778 is_extended_real = False
3780 kind = NumberKind
3782 __slots__ = ()
3784 def __new__(cls):
3785 return AtomicExpr.__new__(cls)
3787 def _latex(self, printer):
3788 return r"\tilde{\infty}"
3790 @staticmethod
3791 def __abs__():
3792 return S.Infinity
3794 def floor(self):
3795 return self
3797 def ceiling(self):
3798 return self
3800 @staticmethod
3801 def __neg__():
3802 return S.ComplexInfinity
3804 def _eval_power(self, expt):
3805 if expt is S.ComplexInfinity:
3806 return S.NaN
3808 if isinstance(expt, Number):
3809 if expt.is_zero:
3810 return S.NaN
3811 else:
3812 if expt.is_positive:
3813 return S.ComplexInfinity
3814 else:
3815 return S.Zero
3818zoo = S.ComplexInfinity
3821class NumberSymbol(AtomicExpr):
3823 is_commutative = True
3824 is_finite = True
3825 is_number = True
3827 __slots__ = ()
3829 is_NumberSymbol = True
3831 kind = NumberKind
3833 def __new__(cls):
3834 return AtomicExpr.__new__(cls)
3836 def approximation(self, number_cls):
3837 """ Return an interval with number_cls endpoints
3838 that contains the value of NumberSymbol.
3839 If not implemented, then return None.
3840 """
3842 def _eval_evalf(self, prec):
3843 return Float._new(self._as_mpf_val(prec), prec)
3845 def __eq__(self, other):
3846 try:
3847 other = _sympify(other)
3848 except SympifyError:
3849 return NotImplemented
3850 if self is other:
3851 return True
3852 if other.is_Number and self.is_irrational:
3853 return False
3855 return False # NumberSymbol != non-(Number|self)
3857 def __ne__(self, other):
3858 return not self == other
3860 def __le__(self, other):
3861 if self is other:
3862 return S.true
3863 return Expr.__le__(self, other)
3865 def __ge__(self, other):
3866 if self is other:
3867 return S.true
3868 return Expr.__ge__(self, other)
3870 def __int__(self):
3871 # subclass with appropriate return value
3872 raise NotImplementedError
3874 def __hash__(self):
3875 return super().__hash__()
3878class Exp1(NumberSymbol, metaclass=Singleton):
3879 r"""The `e` constant.
3881 Explanation
3882 ===========
3884 The transcendental number `e = 2.718281828\ldots` is the base of the
3885 natural logarithm and of the exponential function, `e = \exp(1)`.
3886 Sometimes called Euler's number or Napier's constant.
3888 Exp1 is a singleton, and can be accessed by ``S.Exp1``,
3889 or can be imported as ``E``.
3891 Examples
3892 ========
3894 >>> from sympy import exp, log, E
3895 >>> E is exp(1)
3896 True
3897 >>> log(E)
3898 1
3900 References
3901 ==========
3903 .. [1] https://en.wikipedia.org/wiki/E_%28mathematical_constant%29
3904 """
3906 is_real = True
3907 is_positive = True
3908 is_negative = False # XXX Forces is_negative/is_nonnegative
3909 is_irrational = True
3910 is_number = True
3911 is_algebraic = False
3912 is_transcendental = True
3914 __slots__ = ()
3916 def _latex(self, printer):
3917 return r"e"
3919 @staticmethod
3920 def __abs__():
3921 return S.Exp1
3923 def __int__(self):
3924 return 2
3926 def _as_mpf_val(self, prec):
3927 return mpf_e(prec)
3929 def approximation_interval(self, number_cls):
3930 if issubclass(number_cls, Integer):
3931 return (Integer(2), Integer(3))
3932 elif issubclass(number_cls, Rational):
3933 pass
3935 def _eval_power(self, expt):
3936 if global_parameters.exp_is_pow:
3937 return self._eval_power_exp_is_pow(expt)
3938 else:
3939 from sympy.functions.elementary.exponential import exp
3940 return exp(expt)
3942 def _eval_power_exp_is_pow(self, arg):
3943 if arg.is_Number:
3944 if arg is oo:
3945 return oo
3946 elif arg == -oo:
3947 return S.Zero
3948 from sympy.functions.elementary.exponential import log
3949 if isinstance(arg, log):
3950 return arg.args[0]
3952 # don't autoexpand Pow or Mul (see the issue 3351):
3953 elif not arg.is_Add:
3954 Ioo = I*oo
3955 if arg in [Ioo, -Ioo]:
3956 return nan
3958 coeff = arg.coeff(pi*I)
3959 if coeff:
3960 if (2*coeff).is_integer:
3961 if coeff.is_even:
3962 return S.One
3963 elif coeff.is_odd:
3964 return S.NegativeOne
3965 elif (coeff + S.Half).is_even:
3966 return -I
3967 elif (coeff + S.Half).is_odd:
3968 return I
3969 elif coeff.is_Rational:
3970 ncoeff = coeff % 2 # restrict to [0, 2pi)
3971 if ncoeff > 1: # restrict to (-pi, pi]
3972 ncoeff -= 2
3973 if ncoeff != coeff:
3974 return S.Exp1**(ncoeff*S.Pi*S.ImaginaryUnit)
3976 # Warning: code in risch.py will be very sensitive to changes
3977 # in this (see DifferentialExtension).
3979 # look for a single log factor
3981 coeff, terms = arg.as_coeff_Mul()
3983 # but it can't be multiplied by oo
3984 if coeff in (oo, -oo):
3985 return
3987 coeffs, log_term = [coeff], None
3988 for term in Mul.make_args(terms):
3989 if isinstance(term, log):
3990 if log_term is None:
3991 log_term = term.args[0]
3992 else:
3993 return
3994 elif term.is_comparable:
3995 coeffs.append(term)
3996 else:
3997 return
3999 return log_term**Mul(*coeffs) if log_term else None
4000 elif arg.is_Add:
4001 out = []
4002 add = []
4003 argchanged = False
4004 for a in arg.args:
4005 if a is S.One:
4006 add.append(a)
4007 continue
4008 newa = self**a
4009 if isinstance(newa, Pow) and newa.base is self:
4010 if newa.exp != a:
4011 add.append(newa.exp)
4012 argchanged = True
4013 else:
4014 add.append(a)
4015 else:
4016 out.append(newa)
4017 if out or argchanged:
4018 return Mul(*out)*Pow(self, Add(*add), evaluate=False)
4019 elif arg.is_Matrix:
4020 return arg.exp()
4022 def _eval_rewrite_as_sin(self, **kwargs):
4023 from sympy.functions.elementary.trigonometric import sin
4024 return sin(I + S.Pi/2) - I*sin(I)
4026 def _eval_rewrite_as_cos(self, **kwargs):
4027 from sympy.functions.elementary.trigonometric import cos
4028 return cos(I) + I*cos(I + S.Pi/2)
4030E = S.Exp1
4033class Pi(NumberSymbol, metaclass=Singleton):
4034 r"""The `\pi` constant.
4036 Explanation
4037 ===========
4039 The transcendental number `\pi = 3.141592654\ldots` represents the ratio
4040 of a circle's circumference to its diameter, the area of the unit circle,
4041 the half-period of trigonometric functions, and many other things
4042 in mathematics.
4044 Pi is a singleton, and can be accessed by ``S.Pi``, or can
4045 be imported as ``pi``.
4047 Examples
4048 ========
4050 >>> from sympy import S, pi, oo, sin, exp, integrate, Symbol
4051 >>> S.Pi
4052 pi
4053 >>> pi > 3
4054 True
4055 >>> pi.is_irrational
4056 True
4057 >>> x = Symbol('x')
4058 >>> sin(x + 2*pi)
4059 sin(x)
4060 >>> integrate(exp(-x**2), (x, -oo, oo))
4061 sqrt(pi)
4063 References
4064 ==========
4066 .. [1] https://en.wikipedia.org/wiki/Pi
4067 """
4069 is_real = True
4070 is_positive = True
4071 is_negative = False
4072 is_irrational = True
4073 is_number = True
4074 is_algebraic = False
4075 is_transcendental = True
4077 __slots__ = ()
4079 def _latex(self, printer):
4080 return r"\pi"
4082 @staticmethod
4083 def __abs__():
4084 return S.Pi
4086 def __int__(self):
4087 return 3
4089 def _as_mpf_val(self, prec):
4090 return mpf_pi(prec)
4092 def approximation_interval(self, number_cls):
4093 if issubclass(number_cls, Integer):
4094 return (Integer(3), Integer(4))
4095 elif issubclass(number_cls, Rational):
4096 return (Rational(223, 71, 1), Rational(22, 7, 1))
4098pi = S.Pi
4101class GoldenRatio(NumberSymbol, metaclass=Singleton):
4102 r"""The golden ratio, `\phi`.
4104 Explanation
4105 ===========
4107 `\phi = \frac{1 + \sqrt{5}}{2}` is an algebraic number. Two quantities
4108 are in the golden ratio if their ratio is the same as the ratio of
4109 their sum to the larger of the two quantities, i.e. their maximum.
4111 GoldenRatio is a singleton, and can be accessed by ``S.GoldenRatio``.
4113 Examples
4114 ========
4116 >>> from sympy import S
4117 >>> S.GoldenRatio > 1
4118 True
4119 >>> S.GoldenRatio.expand(func=True)
4120 1/2 + sqrt(5)/2
4121 >>> S.GoldenRatio.is_irrational
4122 True
4124 References
4125 ==========
4127 .. [1] https://en.wikipedia.org/wiki/Golden_ratio
4128 """
4130 is_real = True
4131 is_positive = True
4132 is_negative = False
4133 is_irrational = True
4134 is_number = True
4135 is_algebraic = True
4136 is_transcendental = False
4138 __slots__ = ()
4140 def _latex(self, printer):
4141 return r"\phi"
4143 def __int__(self):
4144 return 1
4146 def _as_mpf_val(self, prec):
4147 # XXX track down why this has to be increased
4148 rv = mlib.from_man_exp(phi_fixed(prec + 10), -prec - 10)
4149 return mpf_norm(rv, prec)
4151 def _eval_expand_func(self, **hints):
4152 from sympy.functions.elementary.miscellaneous import sqrt
4153 return S.Half + S.Half*sqrt(5)
4155 def approximation_interval(self, number_cls):
4156 if issubclass(number_cls, Integer):
4157 return (S.One, Rational(2))
4158 elif issubclass(number_cls, Rational):
4159 pass
4161 _eval_rewrite_as_sqrt = _eval_expand_func
4164class TribonacciConstant(NumberSymbol, metaclass=Singleton):
4165 r"""The tribonacci constant.
4167 Explanation
4168 ===========
4170 The tribonacci numbers are like the Fibonacci numbers, but instead
4171 of starting with two predetermined terms, the sequence starts with
4172 three predetermined terms and each term afterwards is the sum of the
4173 preceding three terms.
4175 The tribonacci constant is the ratio toward which adjacent tribonacci
4176 numbers tend. It is a root of the polynomial `x^3 - x^2 - x - 1 = 0`,
4177 and also satisfies the equation `x + x^{-3} = 2`.
4179 TribonacciConstant is a singleton, and can be accessed
4180 by ``S.TribonacciConstant``.
4182 Examples
4183 ========
4185 >>> from sympy import S
4186 >>> S.TribonacciConstant > 1
4187 True
4188 >>> S.TribonacciConstant.expand(func=True)
4189 1/3 + (19 - 3*sqrt(33))**(1/3)/3 + (3*sqrt(33) + 19)**(1/3)/3
4190 >>> S.TribonacciConstant.is_irrational
4191 True
4192 >>> S.TribonacciConstant.n(20)
4193 1.8392867552141611326
4195 References
4196 ==========
4198 .. [1] https://en.wikipedia.org/wiki/Generalizations_of_Fibonacci_numbers#Tribonacci_numbers
4199 """
4201 is_real = True
4202 is_positive = True
4203 is_negative = False
4204 is_irrational = True
4205 is_number = True
4206 is_algebraic = True
4207 is_transcendental = False
4209 __slots__ = ()
4211 def _latex(self, printer):
4212 return r"\text{TribonacciConstant}"
4214 def __int__(self):
4215 return 1
4217 def _eval_evalf(self, prec):
4218 rv = self._eval_expand_func(function=True)._eval_evalf(prec + 4)
4219 return Float(rv, precision=prec)
4221 def _eval_expand_func(self, **hints):
4222 from sympy.functions.elementary.miscellaneous import cbrt, sqrt
4223 return (1 + cbrt(19 - 3*sqrt(33)) + cbrt(19 + 3*sqrt(33))) / 3
4225 def approximation_interval(self, number_cls):
4226 if issubclass(number_cls, Integer):
4227 return (S.One, Rational(2))
4228 elif issubclass(number_cls, Rational):
4229 pass
4231 _eval_rewrite_as_sqrt = _eval_expand_func
4234class EulerGamma(NumberSymbol, metaclass=Singleton):
4235 r"""The Euler-Mascheroni constant.
4237 Explanation
4238 ===========
4240 `\gamma = 0.5772157\ldots` (also called Euler's constant) is a mathematical
4241 constant recurring in analysis and number theory. It is defined as the
4242 limiting difference between the harmonic series and the
4243 natural logarithm:
4245 .. math:: \gamma = \lim\limits_{n\to\infty}
4246 \left(\sum\limits_{k=1}^n\frac{1}{k} - \ln n\right)
4248 EulerGamma is a singleton, and can be accessed by ``S.EulerGamma``.
4250 Examples
4251 ========
4253 >>> from sympy import S
4254 >>> S.EulerGamma.is_irrational
4255 >>> S.EulerGamma > 0
4256 True
4257 >>> S.EulerGamma > 1
4258 False
4260 References
4261 ==========
4263 .. [1] https://en.wikipedia.org/wiki/Euler%E2%80%93Mascheroni_constant
4264 """
4266 is_real = True
4267 is_positive = True
4268 is_negative = False
4269 is_irrational = None
4270 is_number = True
4272 __slots__ = ()
4274 def _latex(self, printer):
4275 return r"\gamma"
4277 def __int__(self):
4278 return 0
4280 def _as_mpf_val(self, prec):
4281 # XXX track down why this has to be increased
4282 v = mlib.libhyper.euler_fixed(prec + 10)
4283 rv = mlib.from_man_exp(v, -prec - 10)
4284 return mpf_norm(rv, prec)
4286 def approximation_interval(self, number_cls):
4287 if issubclass(number_cls, Integer):
4288 return (S.Zero, S.One)
4289 elif issubclass(number_cls, Rational):
4290 return (S.Half, Rational(3, 5, 1))
4293class Catalan(NumberSymbol, metaclass=Singleton):
4294 r"""Catalan's constant.
4296 Explanation
4297 ===========
4299 $G = 0.91596559\ldots$ is given by the infinite series
4301 .. math:: G = \sum_{k=0}^{\infty} \frac{(-1)^k}{(2k+1)^2}
4303 Catalan is a singleton, and can be accessed by ``S.Catalan``.
4305 Examples
4306 ========
4308 >>> from sympy import S
4309 >>> S.Catalan.is_irrational
4310 >>> S.Catalan > 0
4311 True
4312 >>> S.Catalan > 1
4313 False
4315 References
4316 ==========
4318 .. [1] https://en.wikipedia.org/wiki/Catalan%27s_constant
4319 """
4321 is_real = True
4322 is_positive = True
4323 is_negative = False
4324 is_irrational = None
4325 is_number = True
4327 __slots__ = ()
4329 def __int__(self):
4330 return 0
4332 def _as_mpf_val(self, prec):
4333 # XXX track down why this has to be increased
4334 v = mlib.catalan_fixed(prec + 10)
4335 rv = mlib.from_man_exp(v, -prec - 10)
4336 return mpf_norm(rv, prec)
4338 def approximation_interval(self, number_cls):
4339 if issubclass(number_cls, Integer):
4340 return (S.Zero, S.One)
4341 elif issubclass(number_cls, Rational):
4342 return (Rational(9, 10, 1), S.One)
4344 def _eval_rewrite_as_Sum(self, k_sym=None, symbols=None):
4345 if (k_sym is not None) or (symbols is not None):
4346 return self
4347 from .symbol import Dummy
4348 from sympy.concrete.summations import Sum
4349 k = Dummy('k', integer=True, nonnegative=True)
4350 return Sum(S.NegativeOne**k / (2*k+1)**2, (k, 0, S.Infinity))
4352 def _latex(self, printer):
4353 return "G"
4356class ImaginaryUnit(AtomicExpr, metaclass=Singleton):
4357 r"""The imaginary unit, `i = \sqrt{-1}`.
4359 I is a singleton, and can be accessed by ``S.I``, or can be
4360 imported as ``I``.
4362 Examples
4363 ========
4365 >>> from sympy import I, sqrt
4366 >>> sqrt(-1)
4367 I
4368 >>> I*I
4369 -1
4370 >>> 1/I
4371 -I
4373 References
4374 ==========
4376 .. [1] https://en.wikipedia.org/wiki/Imaginary_unit
4377 """
4379 is_commutative = True
4380 is_imaginary = True
4381 is_finite = True
4382 is_number = True
4383 is_algebraic = True
4384 is_transcendental = False
4386 kind = NumberKind
4388 __slots__ = ()
4390 def _latex(self, printer):
4391 return printer._settings['imaginary_unit_latex']
4393 @staticmethod
4394 def __abs__():
4395 return S.One
4397 def _eval_evalf(self, prec):
4398 return self
4400 def _eval_conjugate(self):
4401 return -S.ImaginaryUnit
4403 def _eval_power(self, expt):
4404 """
4405 b is I = sqrt(-1)
4406 e is symbolic object but not equal to 0, 1
4408 I**r -> (-1)**(r/2) -> exp(r/2*Pi*I) -> sin(Pi*r/2) + cos(Pi*r/2)*I, r is decimal
4409 I**0 mod 4 -> 1
4410 I**1 mod 4 -> I
4411 I**2 mod 4 -> -1
4412 I**3 mod 4 -> -I
4413 """
4415 if isinstance(expt, Integer):
4416 expt = expt % 4
4417 if expt == 0:
4418 return S.One
4419 elif expt == 1:
4420 return S.ImaginaryUnit
4421 elif expt == 2:
4422 return S.NegativeOne
4423 elif expt == 3:
4424 return -S.ImaginaryUnit
4425 if isinstance(expt, Rational):
4426 i, r = divmod(expt, 2)
4427 rv = Pow(S.ImaginaryUnit, r, evaluate=False)
4428 if i % 2:
4429 return Mul(S.NegativeOne, rv, evaluate=False)
4430 return rv
4432 def as_base_exp(self):
4433 return S.NegativeOne, S.Half
4435 @property
4436 def _mpc_(self):
4437 return (Float(0)._mpf_, Float(1)._mpf_)
4440I = S.ImaginaryUnit
4443def equal_valued(x, y):
4444 """Compare expressions treating plain floats as rationals.
4446 Examples
4447 ========
4449 >>> from sympy import S, symbols, Rational, Float
4450 >>> from sympy.core.numbers import equal_valued
4451 >>> equal_valued(1, 2)
4452 False
4453 >>> equal_valued(1, 1)
4454 True
4456 In SymPy expressions with Floats compare unequal to corresponding
4457 expressions with rationals:
4459 >>> x = symbols('x')
4460 >>> x**2 == x**2.0
4461 False
4463 However an individual Float compares equal to a Rational:
4465 >>> Rational(1, 2) == Float(0.5)
4466 True
4468 In a future version of SymPy this might change so that Rational and Float
4469 compare unequal. This function provides the behavior currently expected of
4470 ``==`` so that it could still be used if the behavior of ``==`` were to
4471 change in future.
4473 >>> equal_valued(1, 1.0) # Float vs Rational
4474 True
4475 >>> equal_valued(S(1).n(3), S(1).n(5)) # Floats of different precision
4476 True
4478 Explanation
4479 ===========
4481 In future SymPy verions Float and Rational might compare unequal and floats
4482 with different precisions might compare unequal. In that context a function
4483 is needed that can check if a number is equal to 1 or 0 etc. The idea is
4484 that instead of testing ``if x == 1:`` if we want to accept floats like
4485 ``1.0`` as well then the test can be written as ``if equal_valued(x, 1):``
4486 or ``if equal_valued(x, 2):``. Since this function is intended to be used
4487 in situations where one or both operands are expected to be concrete
4488 numbers like 1 or 0 the function does not recurse through the args of any
4489 compound expression to compare any nested floats.
4491 References
4492 ==========
4494 .. [1] https://github.com/sympy/sympy/pull/20033
4495 """
4496 x = _sympify(x)
4497 y = _sympify(y)
4499 # Handle everything except Float/Rational first
4500 if not x.is_Float and not y.is_Float:
4501 return x == y
4502 elif x.is_Float and y.is_Float:
4503 # Compare values without regard for precision
4504 return x._mpf_ == y._mpf_
4505 elif x.is_Float:
4506 x, y = y, x
4507 if not x.is_Rational:
4508 return False
4510 # Now y is Float and x is Rational. A simple approach at this point would
4511 # just be x == Rational(y) but if y has a large exponent creating a
4512 # Rational could be prohibitively expensive.
4514 sign, man, exp, _ = y._mpf_
4515 p, q = x.p, x.q
4517 if sign:
4518 man = -man
4520 if exp == 0:
4521 # y odd integer
4522 return q == 1 and man == p
4523 elif exp > 0:
4524 # y even integer
4525 if q != 1:
4526 return False
4527 # 'sage.rings.integer.Integer' object has no attribute 'bit_length'
4528 # so man.bit_length raises an AttributeError when testing sage
4529 bl = man.bit_length() if hasattr(man, "bit_length") else man.nbits()
4530 if p.bit_length() != bl + exp:
4531 return False
4532 return man << exp == p
4533 else:
4534 # y non-integer. Need p == man and q == 2**-exp
4535 if p != man:
4536 return False
4537 neg_exp = -exp
4538 if q.bit_length() - 1 != neg_exp:
4539 return False
4540 return (1 << neg_exp) == q
4543@dispatch(Tuple, Number) # type:ignore
4544def _eval_is_eq(self, other): # noqa: F811
4545 return False
4547def sympify_fractions(f):
4548 return Rational(f.numerator, f.denominator, 1)
4550_sympy_converter[fractions.Fraction] = sympify_fractions
4552if HAS_GMPY:
4553 def sympify_mpz(x):
4554 return Integer(int(x))
4556 # XXX: The sympify_mpq function here was never used because it is
4557 # overridden by the other sympify_mpq function below. Maybe it should just
4558 # be removed or maybe it should be used for something...
4559 def sympify_mpq(x):
4560 return Rational(int(x.numerator), int(x.denominator))
4562 _sympy_converter[type(gmpy.mpz(1))] = sympify_mpz
4563 _sympy_converter[type(gmpy.mpq(1, 2))] = sympify_mpq
4566def sympify_mpmath_mpq(x):
4567 p, q = x._mpq_
4568 return Rational(p, q, 1)
4570_sympy_converter[type(mpmath.rational.mpq(1, 2))] = sympify_mpmath_mpq
4573def sympify_mpmath(x):
4574 return Expr._from_mpmath(x, x.context.prec)
4576_sympy_converter[mpnumeric] = sympify_mpmath
4579def sympify_complex(a):
4580 real, imag = list(map(sympify, (a.real, a.imag)))
4581 return real + S.ImaginaryUnit*imag
4583_sympy_converter[complex] = sympify_complex
4585from .power import Pow, integer_nthroot
4586from .mul import Mul
4587Mul.identity = One()
4588from .add import Add
4589Add.identity = Zero()
4591def _register_classes():
4592 numbers.Number.register(Number)
4593 numbers.Real.register(Float)
4594 numbers.Rational.register(Rational)
4595 numbers.Integral.register(Integer)
4597_register_classes()
4599_illegal = (S.NaN, S.Infinity, S.NegativeInfinity, S.ComplexInfinity)