|
""" |
|
The routines here were removed from numbers.py, power.py, |
|
digits.py and factor_.py so they could be imported into core |
|
without raising circular import errors. |
|
|
|
Although the name 'intfunc' was chosen to represent functions that |
|
work with integers, it can also be thought of as containing |
|
internal/core functions that are needed by the classes of the core. |
|
""" |
|
|
|
import math |
|
import sys |
|
from functools import lru_cache |
|
|
|
from .sympify import sympify |
|
from .singleton import S |
|
from sympy.external.gmpy import (gcd as number_gcd, lcm as number_lcm, sqrt, |
|
iroot, bit_scan1, gcdext) |
|
from sympy.utilities.misc import as_int, filldedent |
|
|
|
|
|
def num_digits(n, base=10): |
|
"""Return the number of digits needed to express n in give base. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy.core.intfunc import num_digits |
|
>>> num_digits(10) |
|
2 |
|
>>> num_digits(10, 2) # 1010 -> 4 digits |
|
4 |
|
>>> num_digits(-100, 16) # -64 -> 2 digits |
|
2 |
|
|
|
|
|
Parameters |
|
========== |
|
|
|
n: integer |
|
The number whose digits are counted. |
|
|
|
b: integer |
|
The base in which digits are computed. |
|
|
|
See Also |
|
======== |
|
sympy.ntheory.digits.digits, sympy.ntheory.digits.count_digits |
|
""" |
|
if base < 0: |
|
raise ValueError('base must be int greater than 1') |
|
if not n: |
|
return 1 |
|
e, t = integer_log(abs(n), base) |
|
return 1 + e |
|
|
|
|
|
def integer_log(n, b): |
|
r""" |
|
Returns ``(e, bool)`` where e is the largest nonnegative integer |
|
such that :math:`|n| \geq |b^e|` and ``bool`` is True if $n = b^e$. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy import integer_log |
|
>>> integer_log(125, 5) |
|
(3, True) |
|
>>> integer_log(17, 9) |
|
(1, False) |
|
|
|
If the base is positive and the number negative the |
|
return value will always be the same except for 2: |
|
|
|
>>> integer_log(-4, 2) |
|
(2, False) |
|
>>> integer_log(-16, 4) |
|
(0, False) |
|
|
|
When the base is negative, the returned value |
|
will only be True if the parity of the exponent is |
|
correct for the sign of the base: |
|
|
|
>>> integer_log(4, -2) |
|
(2, True) |
|
>>> integer_log(8, -2) |
|
(3, False) |
|
>>> integer_log(-8, -2) |
|
(3, True) |
|
>>> integer_log(-4, -2) |
|
(2, False) |
|
|
|
See Also |
|
======== |
|
integer_nthroot |
|
sympy.ntheory.primetest.is_square |
|
sympy.ntheory.factor_.multiplicity |
|
sympy.ntheory.factor_.perfect_power |
|
""" |
|
n = as_int(n) |
|
b = as_int(b) |
|
|
|
if b < 0: |
|
e, t = integer_log(abs(n), -b) |
|
|
|
|
|
t = t and e % 2 == (n < 0) |
|
return e, t |
|
if b <= 1: |
|
raise ValueError('base must be 2 or more') |
|
if n < 0: |
|
if b != 2: |
|
return 0, False |
|
e, t = integer_log(-n, b) |
|
return e, False |
|
if n == 0: |
|
raise ValueError('n cannot be 0') |
|
|
|
if n < b: |
|
return 0, n == 1 |
|
if b == 2: |
|
e = n.bit_length() - 1 |
|
return e, trailing(n) == e |
|
t = trailing(b) |
|
if 2**t == b: |
|
e = int(n.bit_length() - 1)//t |
|
n_ = 1 << (t*e) |
|
return e, n_ == n |
|
|
|
d = math.floor(math.log10(n) / math.log10(b)) |
|
n_ = b ** d |
|
while n_ <= n: |
|
d += 1 |
|
n_ *= b |
|
return d - (n_ > n), (n_ == n or n_//b == n) |
|
|
|
|
|
def trailing(n): |
|
"""Count the number of trailing zero digits in the binary |
|
representation of n, i.e. determine the largest power of 2 |
|
that divides n. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy import trailing |
|
>>> trailing(128) |
|
7 |
|
>>> trailing(63) |
|
0 |
|
|
|
See Also |
|
======== |
|
sympy.ntheory.factor_.multiplicity |
|
|
|
""" |
|
if not n: |
|
return 0 |
|
return bit_scan1(int(n)) |
|
|
|
|
|
@lru_cache(1024) |
|
def igcd(*args): |
|
"""Computes nonnegative integer greatest common divisor. |
|
|
|
Explanation |
|
=========== |
|
|
|
The algorithm is based on the well known Euclid's algorithm [1]_. To |
|
improve speed, ``igcd()`` has its own caching mechanism. |
|
If you do not need the cache mechanism, using ``sympy.external.gmpy.gcd``. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy import igcd |
|
>>> igcd(2, 4) |
|
2 |
|
>>> igcd(5, 10, 15) |
|
5 |
|
|
|
References |
|
========== |
|
|
|
.. [1] https://en.wikipedia.org/wiki/Euclidean_algorithm |
|
|
|
""" |
|
if len(args) < 2: |
|
raise TypeError("igcd() takes at least 2 arguments (%s given)" % len(args)) |
|
return int(number_gcd(*map(as_int, args))) |
|
|
|
|
|
igcd2 = math.gcd |
|
|
|
|
|
def igcd_lehmer(a, b): |
|
r"""Computes greatest common divisor of two integers. |
|
|
|
Explanation |
|
=========== |
|
|
|
Euclid's algorithm for the computation of the greatest |
|
common divisor ``gcd(a, b)`` of two (positive) integers |
|
$a$ and $b$ is based on the division identity |
|
$$ a = q \times b + r$$, |
|
where the quotient $q$ and the remainder $r$ are integers |
|
and $0 \le r < b$. Then each common divisor of $a$ and $b$ |
|
divides $r$, and it follows that ``gcd(a, b) == gcd(b, r)``. |
|
The algorithm works by constructing the sequence |
|
r0, r1, r2, ..., where r0 = a, r1 = b, and each rn |
|
is the remainder from the division of the two preceding |
|
elements. |
|
|
|
In Python, ``q = a // b`` and ``r = a % b`` are obtained by the |
|
floor division and the remainder operations, respectively. |
|
These are the most expensive arithmetic operations, especially |
|
for large a and b. |
|
|
|
Lehmer's algorithm [1]_ is based on the observation that the quotients |
|
``qn = r(n-1) // rn`` are in general small integers even |
|
when a and b are very large. Hence the quotients can be |
|
usually determined from a relatively small number of most |
|
significant bits. |
|
|
|
The efficiency of the algorithm is further enhanced by not |
|
computing each long remainder in Euclid's sequence. The remainders |
|
are linear combinations of a and b with integer coefficients |
|
derived from the quotients. The coefficients can be computed |
|
as far as the quotients can be determined from the chosen |
|
most significant parts of a and b. Only then a new pair of |
|
consecutive remainders is computed and the algorithm starts |
|
anew with this pair. |
|
|
|
References |
|
========== |
|
|
|
.. [1] https://en.wikipedia.org/wiki/Lehmer%27s_GCD_algorithm |
|
|
|
""" |
|
a, b = abs(as_int(a)), abs(as_int(b)) |
|
if a < b: |
|
a, b = b, a |
|
|
|
|
|
|
|
|
|
|
|
|
|
nbits = 2 * sys.int_info.bits_per_digit |
|
|
|
while a.bit_length() > nbits and b != 0: |
|
|
|
|
|
n = a.bit_length() - nbits |
|
x, y = int(a >> n), int(b >> n) |
|
|
|
|
|
|
|
|
|
|
|
|
|
A, B, C, D = 1, 0, 0, 1 |
|
|
|
while True: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if y + C <= 0: |
|
break |
|
q = (x + A) // (y + C) |
|
|
|
|
|
|
|
|
|
x_qy, B_qD = x - q * y, B - q * D |
|
if x_qy + B_qD < 0: |
|
break |
|
|
|
|
|
x, y = y, x_qy |
|
A, B, C, D = C, D, A - q * C, B_qD |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if y + D <= 0: |
|
break |
|
q = (x + B) // (y + D) |
|
x_qy, A_qC = x - q * y, A - q * C |
|
if x_qy + A_qC < 0: |
|
break |
|
|
|
x, y = y, x_qy |
|
A, B, C, D = C, D, A_qC, B - q * D |
|
|
|
|
|
|
|
|
|
if B == 0: |
|
|
|
|
|
|
|
a, b = b, a % b |
|
continue |
|
|
|
|
|
a, b = A * a + B * b, C * a + D * b |
|
|
|
|
|
while b: |
|
a, b = b, a % b |
|
|
|
return a |
|
|
|
|
|
def ilcm(*args): |
|
"""Computes integer least common multiple. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy import ilcm |
|
>>> ilcm(5, 10) |
|
10 |
|
>>> ilcm(7, 3) |
|
21 |
|
>>> ilcm(5, 10, 15) |
|
30 |
|
|
|
""" |
|
if len(args) < 2: |
|
raise TypeError("ilcm() takes at least 2 arguments (%s given)" % len(args)) |
|
return int(number_lcm(*map(as_int, args))) |
|
|
|
|
|
def igcdex(a, b): |
|
"""Returns x, y, g such that g = x*a + y*b = gcd(a, b). |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy.core.intfunc import igcdex |
|
>>> igcdex(2, 3) |
|
(-1, 1, 1) |
|
>>> igcdex(10, 12) |
|
(-1, 1, 2) |
|
|
|
>>> x, y, g = igcdex(100, 2004) |
|
>>> x, y, g |
|
(-20, 1, 4) |
|
>>> x*100 + y*2004 |
|
4 |
|
|
|
""" |
|
if (not a) and (not b): |
|
return (0, 1, 0) |
|
g, x, y = gcdext(int(a), int(b)) |
|
return x, y, g |
|
|
|
|
|
def mod_inverse(a, m): |
|
r""" |
|
Return the number $c$ such that, $a \times c = 1 \pmod{m}$ |
|
where $c$ has the same sign as $m$. If no such value exists, |
|
a ValueError is raised. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy import mod_inverse, S |
|
|
|
Suppose we wish to find multiplicative inverse $x$ of |
|
3 modulo 11. This is the same as finding $x$ such |
|
that $3x = 1 \pmod{11}$. One value of x that satisfies |
|
this congruence is 4. Because $3 \times 4 = 12$ and $12 = 1 \pmod{11}$. |
|
This is the value returned by ``mod_inverse``: |
|
|
|
>>> mod_inverse(3, 11) |
|
4 |
|
>>> mod_inverse(-3, 11) |
|
7 |
|
|
|
When there is a common factor between the numerators of |
|
`a` and `m` the inverse does not exist: |
|
|
|
>>> mod_inverse(2, 4) |
|
Traceback (most recent call last): |
|
... |
|
ValueError: inverse of 2 mod 4 does not exist |
|
|
|
>>> mod_inverse(S(2)/7, S(5)/2) |
|
7/2 |
|
|
|
References |
|
========== |
|
|
|
.. [1] https://en.wikipedia.org/wiki/Modular_multiplicative_inverse |
|
.. [2] https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm |
|
""" |
|
c = None |
|
try: |
|
a, m = as_int(a), as_int(m) |
|
if m != 1 and m != -1: |
|
x, _, g = igcdex(a, m) |
|
if g == 1: |
|
c = x % m |
|
except ValueError: |
|
a, m = sympify(a), sympify(m) |
|
if not (a.is_number and m.is_number): |
|
raise TypeError( |
|
filldedent( |
|
""" |
|
Expected numbers for arguments; symbolic `mod_inverse` |
|
is not implemented |
|
but symbolic expressions can be handled with the |
|
similar function, |
|
sympy.polys.polytools.invert""" |
|
) |
|
) |
|
big = m > 1 |
|
if big not in (S.true, S.false): |
|
raise ValueError("m > 1 did not evaluate; try to simplify %s" % m) |
|
elif big: |
|
c = 1 / a |
|
if c is None: |
|
raise ValueError("inverse of %s (mod %s) does not exist" % (a, m)) |
|
return c |
|
|
|
|
|
def isqrt(n): |
|
r""" Return the largest integer less than or equal to `\sqrt{n}`. |
|
|
|
Parameters |
|
========== |
|
|
|
n : non-negative integer |
|
|
|
Returns |
|
======= |
|
|
|
int : `\left\lfloor\sqrt{n}\right\rfloor` |
|
|
|
Raises |
|
====== |
|
|
|
ValueError |
|
If n is negative. |
|
TypeError |
|
If n is of a type that cannot be compared to ``int``. |
|
Therefore, a TypeError is raised for ``str``, but not for ``float``. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy.core.intfunc import isqrt |
|
>>> isqrt(0) |
|
0 |
|
>>> isqrt(9) |
|
3 |
|
>>> isqrt(10) |
|
3 |
|
>>> isqrt("30") |
|
Traceback (most recent call last): |
|
... |
|
TypeError: '<' not supported between instances of 'str' and 'int' |
|
>>> from sympy.core.numbers import Rational |
|
>>> isqrt(Rational(-1, 2)) |
|
Traceback (most recent call last): |
|
... |
|
ValueError: n must be nonnegative |
|
|
|
""" |
|
if n < 0: |
|
raise ValueError("n must be nonnegative") |
|
return int(sqrt(int(n))) |
|
|
|
|
|
def integer_nthroot(y, n): |
|
""" |
|
Return a tuple containing x = floor(y**(1/n)) |
|
and a boolean indicating whether the result is exact (that is, |
|
whether x**n == y). |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy import integer_nthroot |
|
>>> integer_nthroot(16, 2) |
|
(4, True) |
|
>>> integer_nthroot(26, 2) |
|
(5, False) |
|
|
|
To simply determine if a number is a perfect square, the is_square |
|
function should be used: |
|
|
|
>>> from sympy.ntheory.primetest import is_square |
|
>>> is_square(26) |
|
False |
|
|
|
See Also |
|
======== |
|
sympy.ntheory.primetest.is_square |
|
integer_log |
|
""" |
|
x, b = iroot(as_int(y), as_int(n)) |
|
return int(x), b |
|
|