2 This module implements efficient "low-level" number types for purely
5 We use the following types:
7 int/long -- (Python built-ins) exact integers
8 mpf -- arbitrary-precision floats
9 mpc -- arbitrary-precision complex floats
10 mpq -- nonintegral fractions
11 mpqc -- nonreal complex rationals
13 In the interest of speed, there are some quirks:
15 * mpq derives from tuple. mpq.__init__ does *not* validate its input.
16 mpqs *should only* be created from fully reduced (p, q) pairs,
17 and p/q should *not* be integer-valued.
19 * To safely create a fraction from two integers, use the function
22 * Arithmetic operations on mpqs automatically normalize back to Python
23 ints when the results are integer-valued. Likewise, mpqc with zero
24 real part normalize to their real parts.
26 * Note that ``mpq(2)/mpq(3)`` does *not* work as expected; it does the
27 same thing as ``2/3`` in Python. To perform safe division, use the
28 provided ``div`` function.
30 * mpqs can be compared with Python ints, but cannot be (correctly)
31 compared to Python floats. (Use the mpf class instead.)
33 Powers, except when the exponent is a positive integer, should be
34 computed with the ``try_power()`` function which detects when the
38 # Author: Fredrik Johansson
39 # Created: January 2008
45 __docformat__
= "restructuredtext"
47 from ..core
import init_module
49 init_module
.import_heads()
53 from ..basealgebra
.verbatim
import Verbatim
54 module
.Verbatim
= Verbatim
56 from ..utils
import str_SUM
, str_PRODUCT
, str_POWER
, str_APPLY
, str_SYMBOL
, str_NUMBER
, NUMBER
, SYMBOL
58 inttypes
= (int, long)
60 from .mpmath
import mpf
, mpc
, mp
61 from .mpmath
.libmp
import from_rational
, round_nearest
65 def mpf_to_str_data(self
, sort
=True):
67 return str_SUM
, str(self
)
68 return str_NUMBER
, str(self
)
70 def mpc_to_str_data(self
, sort
=True):
71 return str_NUMBER
, str(self
)
73 mpf
.to_str_data
= mpf_to_str_data
74 mpc
.to_str_data
= mpc_to_str_data
76 rounding
= round_nearest
89 #----------------------------------------------------------------------------
93 def normalized_fraction(p
, q
=1):
94 """ Return a normalized fraction.
107 """Represents a fraction."""
109 # These methods are inherited directly from tuple for speed. This works
110 # as long as all mpqs are normalized:
116 # These methods are generated and defined in methods.py:
117 # __add__, __sub__, __rsub__, __mul__, __div__, __rdiv__, __pow__
118 # __lt__, __le__, __gt__, __ge__
125 return from_rational(p
, q
, getprec(), rounding
)
127 def as_verbatim(self
):
130 return -(Verbatim(NUMBER
, -p
) / Verbatim(NUMBER
, q
))
131 return Verbatim(NUMBER
, p
) / Verbatim(NUMBER
, q
)
133 def to_str_data(self
,sort
=True):
135 return str_SUM
, str(self
)
136 return str_PRODUCT
, str(self
)
139 return "%i/%i" % self
143 return "%s((%s, %s))" % (type(self
).__name
__, p
, q
)
166 def __floordiv__(a
, b
):
169 def __rfloordiv__(a
, b
):
178 def __divmod__(a
, b
):
179 return (a
-a
%b
)/b
, a
%b
181 def __rdivmod__(a
, b
):
182 return (b
-b
%a
)/a
, b
%a
185 z
, sym
= try_power(b
, a
)
188 return NotImplemented
191 #----------------------------------------------------------------------------
196 if isinstance(x
, mpq
):
202 """Represents an exact complex number.
204 The integer power of a complex number is computed using
205 `exponentiation by squaring`__ method.
207 __ http://en.wikipedia.org/wiki/Exponentiation_by_squaring
210 __slots__
= ['real', 'imag']
212 def __new__(cls
, real
, imag
=0):
215 if isinstance(real
, (float, mpf
)) or isinstance(imag
, (float, mpf
)):
216 return mpc(real
, imag
)
217 self
= object.__new
__(mpqc
)
223 return "%s(%r, %r)" % (self
.__class
__.__name
__, self
.real
, self
.imag
)
226 return hash((self
.real
, self
.imag
))
228 def __mpcval__(self
):
229 return mpc(self
.real
, self
.imag
)
231 def __getstate__(self
):
232 return (self
.real
, self
.imag
)
234 def __setstate__(self
, (real
, imag
)):
238 def to_str_data(self
,sort
=True):
239 re
, im
= self
.real
, self
.imag
241 if im
== 1: return str_SYMBOL
,"I"
242 if im
== -1: return str_SUM
, "-I"
243 return str_PRODUCT
, str(self
.imag
) + "*I"
244 restr
= innerstr(self
.real
)
245 if im
== 1: return str_SUM
, "%s + I" % restr
246 if im
== -1: return str_SUM
, "%s - I" % restr
247 if im
> 0: return str_SUM
, "%s + %s*I" % (restr
, innerstr(self
.imag
))
248 if im
< 0: return str_SUM
, "%s - %s*I" % (restr
, innerstr(-self
.imag
))
249 raise NotImplementedError(`self`
)
252 return self
.to_str_data()[1]
254 def as_verbatim(self
):
255 re
, im
= self
.real
, self
.imag
257 r
= -Verbatim(NUMBER
, -self
.real
)
259 r
= Verbatim(NUMBER
, self
.real
)
261 i
= -Verbatim(NUMBER
, -self
.imag
)
262 ni
= Verbatim(NUMBER
, -self
.imag
)
264 i
= Verbatim(NUMBER
, self
.imag
)
265 I
= Verbatim(NUMBER
, mpqc(0,1))
268 if im
== -1: return -I
270 if im
== 1: return r
+ I
271 if im
== -1: return r
- I
277 def as_numer_denom(self
):
278 re
, im
= self
.real
, self
.imag
291 return mpqc(r
//c
,i
//c
), d
//c
293 def __eq__(self
, other
):
294 if hasattr(other
, "imag"):
295 return self
.real
== other
.real
and self
.imag
== other
.imag
298 def __pos__(self
): return self
299 def __neg__(self
): return mpqc(-self
.real
, -self
.imag
)
302 re
, im
= self
.real
, self
.imag
306 if isinstance(m2
, inttypes
):
307 m
, flag
= int_root(m2
,2)
310 if isinstance(m2
, mpq
):
311 p
,fp
= int_root(m2
[0],2)
312 q
,fq
= int_root(m2
[1],2)
315 raise NotImplementedError('abs(%r)' % (self
))
317 #----------------------------------------------------------------------------
318 # Interface functions
321 inttypes
= (int, long)
322 rationaltypes
= (mpq
,)
323 numbertypes
= (int, long, float, complex, mpq
, mpqc
, mpf
, mpc
)
324 realtypes
= (int, long, float, mpq
, mpf
)
325 complextypes
= (complex, mpqc
, mpc
)
327 inttypes_set
= frozenset(inttypes
)
328 rationaltypes_set
= frozenset(rationaltypes
)
329 realtypes_set
= frozenset(realtypes
)
330 complextypes_set
= frozenset(complextypes
)
331 numbertypes_set
= frozenset(numbertypes
)
333 def number_div(Algebra
, a
, b
):
334 if type(b
) in inttypes_set
:
337 return Infinity(Infinity(0))
341 if type(a
) in inttypes_set
:
342 return normalized_fraction(a
, b
)
346 """Safely compute a/b.
348 If a or b is an integer, this function makes sure to convert it to
351 if type(b
) in inttypes_set
:
354 raise ZeroDivisionError('%r / %r' % (a
, b
))
357 if type(a
) in inttypes_set
:
358 return normalized_fraction(a
, b
)
362 """ Return a pair ``(floor(y**(1/n)), x**n == y)``.
364 Given integers y and n, return a tuple containing ``x =
365 floor(y**(1/n))`` and a boolean indicating whether ``x**n == y``
368 if y
< 0: raise ValueError, "y must not be negative"
369 if n
< 1: raise ValueError, "n must be positive"
370 if y
in (0, 1): return y
, True
371 if n
== 1: return y
, True
372 if n
> y
: return 1, False
373 # Get initial estimate for Newton's method. Care must be taken to
376 guess
= int(y
** (1./n
)+0.5)
377 except OverflowError:
379 guess
= int(math
.exp(math
.log(y
)/n
)+0.5)
380 except OverflowError:
381 guess
= 1 << int(math
.log(y
, 2)/n
)
386 xprev
, x
= x
, x
- (t
*x
-y
)//(n
*t
)
387 if abs(x
- xprev
) < 1:
398 Attempt to compute ``x**y`` where ``x`` and ``y`` must be of the
399 types int, long, mpq, mpf, or mpqc. The function
404 where ``z`` is a number (i.e. a complex rational) and ``symbolic``
405 is a list of ``(b, e)`` pairs representing symbolic factors
410 try_power(3, 2) --> (9, [])
411 try_power(2, 1/2) --> (1, [(2, 1/2)])
412 try_power(45, 1/2) --> (3, [(5, 1/2)])
418 if isinstance(x
, Infinity
) or isinstance(y
, Infinity
):
420 if isinstance(y
, inttypes
):
424 return Infinity
.get_zoo(), []
425 elif isinstance(x
, inttypes
):
426 return mpq((1, x
**(-y
))), []
428 elif isinstance(x
, inttypes
) and isinstance(y
, mpq
):
433 return mpqc(0, 1)**p
, []
436 z
, sym
= try_power(-x
, y
)
437 z1
, sym1
= try_power(-1, y
)
438 return z
* z1
, sym
+sym1
441 r
, exact
= int_root(x
, q
)
445 g
= r
**p
if p
>0 else mpq((1, r
**(-p
)))
447 elif isinstance(x
, mpq
) and isinstance(y
, mpq
):
449 r
, rsym
= try_power(a
, y
)
450 s
, ssym
= try_power(b
, y
)
451 ssym
= [(b
, -e
) for b
, e
in ssym
]
452 return (div(r
,s
), rsym
+ ssym
)
453 elif isinstance(x
, mpf
) or isinstance(y
, mpf
):
457 from .number_theory
import gcd
458 from .evalf
import evalf
459 from .infinity
import Infinity
461 from .methods
import (\
462 fraction_add
, fraction_sub
, fraction_rsub
, fraction_mul
,
463 fraction_div
, fraction_rdiv
, fraction_pow
,
464 fraction_lt
, fraction_le
, fraction_gt
, fraction_ge
,
465 complex_add
, complex_sub
, complex_rsub
, complex_mul
,
466 complex_div
, complex_rdiv
, complex_pow
)
468 mpq
.__add
__ = mpq
.__radd
__ = fraction_add
469 mpq
.__sub
__ = fraction_sub
470 mpq
.__rsub
__ = fraction_rsub
471 mpq
.__mul
__ = mpq
.__rmul
__ = fraction_mul
472 mpq
.__div
__ = fraction_div
473 mpq
.__rdiv
__ = fraction_rdiv
474 mpq
.__pow
__ = fraction_pow
475 mpq
.__lt
__ = fraction_lt
476 mpq
.__le
__ = fraction_le
477 mpq
.__gt
__ = fraction_gt
478 mpq
.__ge
__ = fraction_ge
480 mpqc
.__add
__ = mpqc
.__radd
__ = complex_add
481 mpqc
.__sub
__ = complex_sub
482 mpqc
.__rsub
__ = complex_rsub
483 mpqc
.__mul
__ = mpqc
.__rmul
__ = complex_mul
484 mpqc
.__div
__ = complex_div
485 mpqc
.__rdiv
__ = complex_rdiv
486 mpqc
.__pow
__ = complex_pow