Exemplo n.º 1
0
    def test_integer_nth_root(self):
        self.assertRaisesRegexp(ValueError, "integer_nth_root: Must have n >= 1", integer_nth_root, 0, 10)
        self.assertRaisesRegexp(ValueError, "integer_nth_root: Must have m >= 0", integer_nth_root, 3, -1)

        self.assertEqual(integer_nth_root(1, 10), 10)
        self.assertEqual(integer_nth_root(3, 1), 1)

        for i in xrange(100):
            a = random.randint(100, 1000)
            b = random.randint(100, 1000)
            m = a**b

            n = random.randint(2, 200)

            r = integer_nth_root(n, m)
            self.assertTrue(r**n <= m < (r + 1)**n)
Exemplo n.º 2
0
def lehman(n):
    """
    Returns a nontrivial divisor of n, or proves primality.

    Given an integer n > 1, this algorithm finds a nontrivial factor of n if
    n is not prime, or returns n if n is prime.

    Input:
        * n: int (n >= 3)

    Output:
        * d: int
            If d == n, then n is proven prime. Otherwise, d is a nontrivial
            divisor of n.

    Examples:
        >>> l = 1112470797641561909
        >>> lehman(l)
        1056689261L

    Details:
        The algorithm used is Lehman's Method. This algorithm runs in time
        O(n^(1/3)), where n is the number to be factored / proven prime. This is
        substantially better than O(n^(1/2)) trial division for reasonably small
        value of n, but this algorithm is not suited for large values of n. See
        section 8.4 of "A Course in Computational Algebraic Number Theory" by
        Cohen or section 5.1.2 of "Prime Numbers - A Computational Perspective"
        by Crandall and Pomerance for more details.


    """
    # first, we trial divide up to floor(n^(1/3))
    bound = integer_nth_root(3, n)
    d = trial_division(n, bound)
    if d < n:
        return d

    for k in xrange(1, bound + 1):
        if k % 2 == 0:
            r = 1
            m = 2
        else:
            r = k + n
            m = 4
        # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2
        # and a = r (mod m)
        fkn = 4*k*n
        a = integer_sqrt(fkn)
        # now, increase a until a = r (mod m)
        rm = r % m
        while a % m != rm:
            a += 1
        ub = fkn + bound**2
        while fkn <= a*a <= ub:
            c = a*a - fkn
            b = integer_sqrt(c)
            if b*b == c:
                return gcd(a + b, n)
            a += m
    return n
Exemplo n.º 3
0
    def test_integer_nth_root(self):
        self.assertRaisesRegexp(ValueError, "integer_nth_root: Must have n >= 1", integer_nth_root, 0, 10)
        self.assertRaisesRegexp(ValueError, "integer_nth_root: Must have m >= 0", integer_nth_root, 3, -1)

        self.assertEqual(integer_nth_root(1, 10), 10)
        self.assertEqual(integer_nth_root(3, 1), 1)

        for i in xrange(100):
            a = random.randint(100, 1000)
            b = random.randint(100, 1000)
            m = a**b

            n = random.randint(2, 200)

            r = integer_nth_root(n, m)
            self.assertTrue(r**n <= m < (r + 1)**n)
Exemplo n.º 4
0
def is_power2(n):
    k = 2
    while 2**k <= n:
        r = integer_nth_root(k, n)
        if r**k == n:
            return (r, k)
        k += 1
    return False
Exemplo n.º 5
0
def meissel(n):
    if n <= 1:
        return 0
    elif n <= _PRIME_LIST[-1]:
        return bisect(_PRIME_LIST, n)

    root = integer_nth_root(3, n**2)
    primes, pi_cache = pi_table(root)

    a = pi_cache[integer_nth_root(3, n)]
    b = pi_cache[integer_nth_root(2, n)]

    def phi(x, a, cache={}):
        if (x, a) in cache:
            return cache[x, a]

        b = pi_cache[int((x + 0.5)**(0.5))]
        c = pi_cache[int((x + 0.5)**(1.0 / 3.0))]

        if a <= 7:
            if a == 1:
                value = x - x // 2

            elif a == 2:
                value = x - x // 2 - x // 3 + x // 6

            elif a == 3:
                value = x - x // 2 - x // 3 - x // 5 + x // 6 + x // 10 + x // 15 - x // 30

            elif a == 4:
                value = (x - x // 2 - x // 3 - x // 5 - x // 7 + x // 6 +
                         x // 10 + x // 14 + x // 15 + x // 21 + x // 35 -
                         x // 30 - x // 42 - x // 70 - x // 105 + x // 210)
            elif a == 5:
                value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 +
                         x // 6 + x // 10 + x // 14 + x // 22 + x // 15 +
                         x // 21 + x // 33 + x // 35 + x // 55 + x // 77 -
                         x // 30 - x // 42 - x // 66 - x // 70 - x // 110 -
                         x // 154 - x // 105 - x // 165 - x // 231 - x // 385 +
                         x // 210 + x // 330 + x // 462 + x // 770 +
                         x // 1155 - x // 2310)
            elif a == 6:
                value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 -
                         x // 13 + x // 6 + x // 10 + x // 14 + x // 22 +
                         x // 26 + x // 15 + x // 21 + x // 33 + x // 39 +
                         x // 35 + x // 55 + x // 65 + x // 77 + x // 91 +
                         x // 143 - x // 30 - x // 42 - x // 66 - x // 78 -
                         x // 70 - x // 110 - x // 130 - x // 154 - x // 182 -
                         x // 286 - x // 105 - x // 165 - x // 195 - x // 231 -
                         x // 273 - x // 429 - x // 385 - x // 455 - x // 715 -
                         x // 1001 + x // 210 + x // 330 + x // 390 +
                         x // 462 + x // 546 + x // 858 + x // 770 + x // 910 +
                         x // 1430 + x // 2002 + x // 1155 + x // 1365 +
                         x // 2145 + x // 3003 + x // 5005 - x // 2310 -
                         x // 2730 - x // 4290 - x // 6006 - x // 10010 -
                         x // 15015 + x // 30030)
            else:
                value = (
                    x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 -
                    x // 17 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 +
                    x // 34 + x // 15 + x // 21 + x // 33 + x // 39 + x // 51 +
                    x // 35 + x // 55 + x // 65 + x // 85 + x // 77 + x // 91 +
                    x // 119 + x // 143 + x // 187 + x // 221 - x // 30 -
                    x // 42 - x // 66 - x // 78 - x // 102 - x // 70 -
                    x // 110 - x // 130 - x // 170 - x // 154 - x // 182 -
                    x // 238 - x // 286 - x // 374 - x // 442 - x // 105 -
                    x // 165 - x // 195 - x // 255 - x // 231 - x // 273 -
                    x // 357 - x // 429 - x // 561 - x // 663 - x // 385 -
                    x // 455 - x // 595 - x // 715 - x // 935 - x // 1105 -
                    x // 1001 - x // 1309 - x // 1547 - x // 2431 + x // 210 +
                    x // 330 + x // 390 + x // 510 + x // 462 + x // 546 +
                    x // 714 + x // 858 + x // 1122 + x // 1326 + x // 770 +
                    x // 910 + x // 1190 + x // 1430 + x // 1870 + x // 2210 +
                    x // 2002 + x // 2618 + x // 3094 + x // 4862 + x // 1155 +
                    x // 1365 + x // 1785 + x // 2145 + x // 2805 + x // 3315 +
                    x // 3003 + x // 3927 + x // 4641 + x // 7293 + x // 5005 +
                    x // 6545 + x // 7735 + x // 12155 + x // 17017 -
                    x // 2310 - x // 2730 - x // 3570 - x // 4290 - x // 5610 -
                    x // 6630 - x // 6006 - x // 7854 - x // 9282 -
                    x // 14586 - x // 10010 - x // 13090 - x // 15470 -
                    x // 24310 - x // 34034 - x // 15015 - x // 19635 -
                    x // 23205 - x // 36465 - x // 51051 - x // 85085 +
                    x // 30030 + x // 39270 + x // 46410 + x // 72930 +
                    x // 102102 + x // 170170 + x // 255255 - x // 510510)

        elif b > a >= c and x <= root:
            value = pi_cache[x] - a + 1 + phi2(x, a, b)

        elif a >= b and x <= root:
            value = pi_cache[x] - a + 1

        else:
            value = (x + 1) // 2
            for i in xrange(1, a):
                if primes[i] > x:
                    break
                value -= phi(x // primes[i], i)

        cache[x, a] = value
        return value

    def phi2(n, a, b):
        total = (a - b) * (b + a - 1) // 2
        for i in xrange(a, b):
            total += pi_cache[n // primes[i]]
        return total

    value = phi(n, a) - 1 + a - phi2(n, a, b)
    return value
Exemplo n.º 6
0
def lmo(x):
    if x <= 1:
        return 0
    elif x <= _PRIME_LIST[-1]:
        return bisect(_PRIME_LIST, x)

    root = integer_nth_root(3, x**2)
    primes = sieves.primes(root)

    t = integer_nth_root(3, x)
    c = bisect(primes, t)
    b = bisect(primes, integer_nth_root(2, x))

    value = (b + c - 2) * (b - c + 1) // 2

    for i in xrange(c, b):
        idx = bisect(primes, x // primes[i])
        value -= idx

    special = defaultdict(list)

    stack = [(1, c, 1)]
    push = stack.append
    pop = stack.pop

    # print "recursing"

    while stack:
        (n, a, sign) = pop()

        if a == 1 and n <= t:
            if sign > 0:
                value += (x // n + 1) // 2
            else:
                value -= (x // n + 1) // 2
        elif n > t:
            special[a].append((x // n, sign))
        else:
            push((n, a - 1, sign))
            push((n * primes[a - 1], a - 1, -sign))

    block = [1] * (root + 1)
    block[0] = 0

    for a in sorted(special):
        p = primes[a - 1]

        block[p::p] = [0] * (root // p)
        last_v = 0
        last_s = 0

        for v, sign in sorted(special[a]):
            last_s += sum(block[last_v:v + 1])
            last_v = v + 1

            if sign > 0:
                value += last_s
            else:
                value -= last_s

    return value
Exemplo n.º 7
0
def lehmer(n):
    if n <= 1:
        return 0
    elif n <= _PRIME_LIST[-1]:
        return bisect(_PRIME_LIST, n)

    root = integer_nth_root(4, n**3)
    primes = sieves.primes(root)

    a = bisect(primes, integer_nth_root(4, n))
    b = bisect(primes, integer_sqrt(n))
    c = bisect(primes, integer_nth_root(3, n))

    def phi(x, a, cache={}):
        if (x, a) in cache:
            return cache[x, a]

        if a <= 7:
            if a == 1:
                value = x - x // 2

            elif a == 2:
                value = x - x // 2 - x // 3 + x // 6

            elif a == 3:
                value = x - x // 2 - x // 3 - x // 5 + x // 6 + x // 10 + x // 15 - x // 30

            elif a == 4:
                value = (x - x // 2 - x // 3 - x // 5 - x // 7 + x // 6 +
                         x // 10 + x // 14 + x // 15 + x // 21 + x // 35 -
                         x // 30 - x // 42 - x // 70 - x // 105 + x // 210)
            elif a == 5:
                value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 +
                         x // 6 + x // 10 + x // 14 + x // 22 + x // 15 +
                         x // 21 + x // 33 + x // 35 + x // 55 + x // 77 -
                         x // 30 - x // 42 - x // 66 - x // 70 - x // 110 -
                         x // 154 - x // 105 - x // 165 - x // 231 - x // 385 +
                         x // 210 + x // 330 + x // 462 + x // 770 +
                         x // 1155 - x // 2310)
            elif a == 6:
                value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 -
                         x // 13 + x // 6 + x // 10 + x // 14 + x // 22 +
                         x // 26 + x // 15 + x // 21 + x // 33 + x // 39 +
                         x // 35 + x // 55 + x // 65 + x // 77 + x // 91 +
                         x // 143 - x // 30 - x // 42 - x // 66 - x // 78 -
                         x // 70 - x // 110 - x // 130 - x // 154 - x // 182 -
                         x // 286 - x // 105 - x // 165 - x // 195 - x // 231 -
                         x // 273 - x // 429 - x // 385 - x // 455 - x // 715 -
                         x // 1001 + x // 210 + x // 330 + x // 390 +
                         x // 462 + x // 546 + x // 858 + x // 770 + x // 910 +
                         x // 1430 + x // 2002 + x // 1155 + x // 1365 +
                         x // 2145 + x // 3003 + x // 5005 - x // 2310 -
                         x // 2730 - x // 4290 - x // 6006 - x // 10010 -
                         x // 15015 + x // 30030)
            else:
                value = (
                    x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 -
                    x // 17 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 +
                    x // 34 + x // 15 + x // 21 + x // 33 + x // 39 + x // 51 +
                    x // 35 + x // 55 + x // 65 + x // 85 + x // 77 + x // 91 +
                    x // 119 + x // 143 + x // 187 + x // 221 - x // 30 -
                    x // 42 - x // 66 - x // 78 - x // 102 - x // 70 -
                    x // 110 - x // 130 - x // 170 - x // 154 - x // 182 -
                    x // 238 - x // 286 - x // 374 - x // 442 - x // 105 -
                    x // 165 - x // 195 - x // 255 - x // 231 - x // 273 -
                    x // 357 - x // 429 - x // 561 - x // 663 - x // 385 -
                    x // 455 - x // 595 - x // 715 - x // 935 - x // 1105 -
                    x // 1001 - x // 1309 - x // 1547 - x // 2431 + x // 210 +
                    x // 330 + x // 390 + x // 510 + x // 462 + x // 546 +
                    x // 714 + x // 858 + x // 1122 + x // 1326 + x // 770 +
                    x // 910 + x // 1190 + x // 1430 + x // 1870 + x // 2210 +
                    x // 2002 + x // 2618 + x // 3094 + x // 4862 + x // 1155 +
                    x // 1365 + x // 1785 + x // 2145 + x // 2805 + x // 3315 +
                    x // 3003 + x // 3927 + x // 4641 + x // 7293 + x // 5005 +
                    x // 6545 + x // 7735 + x // 12155 + x // 17017 -
                    x // 2310 - x // 2730 - x // 3570 - x // 4290 - x // 5610 -
                    x // 6630 - x // 6006 - x // 7854 - x // 9282 -
                    x // 14586 - x // 10010 - x // 13090 - x // 15470 -
                    x // 24310 - x // 34034 - x // 15015 - x // 19635 -
                    x // 23205 - x // 36465 - x // 51051 - x // 85085 +
                    x // 30030 + x // 39270 + x // 46410 + x // 72930 +
                    x // 102102 + x // 170170 + x // 255255 - x // 510510)

        elif a >= bisect(primes, x**(0.5)) and x < primes[-1]:
            pi = bisect(primes, x)
            value = pi - a + 1

        else:
            value = (x + 1) // 2
            for i in xrange(1, a):
                if primes[i] > x:
                    break
                value -= phi(x // primes[i], i)

        cache[x, a] = value
        return value

    def phi2(n, a, b):
        s1 = 0
        for i in xrange(a, b):
            s1 += phi(n // primes[i], b) + b - 1
        return s1

    def phi3(n, a, b, c):
        s2 = 0
        for i in xrange(a, c):
            bi = phi(integer_sqrt(n // primes[i]), b) + b - 1
            for j in xrange(i, bi):
                idx = phi(n // (primes[i] * primes[j]), b) + b - 1
                s2 += idx - j
        return s2

    value = (b + a - 2) * (b - a + 1) // 2 + phi(n, a) - phi2(n, a, b) - phi3(
        n, a, b, c)
    return value
Exemplo n.º 8
0
def is_power(n, k=None, detect_only=False):
    """Determines if n is a perfect power.

    If n is a perfect power, this returns (b, k) where n = b^k with k maximal.
    If the optional parameter k is given, this returns (b, k) if n = b^k for
    some b. Otherwise, returns False.

    Input:
        * n: int or list (n >= 1)
            The value of n can be an int or a factorization.

        * k: int (k >= 1) (default=None)

    Returns:
        * (b, k): tuple of ints
            Values such that n = b^k if such values exist.

        * Returns False if no such values exist.

    Raises:
        * ValueError: If n <= 0 or k <= 0.

    Examples:
        >>> is_power(36)
        (6, 2)
        >>> is_power(81)
        (3, 4)
        >>> is_power(81, 2)
        (9, 2)
        >>> is_power(1330)
        False
        >>> is_power([(2, 4), (5, 4)])
        (10, 4)
        >>> is_power([(2, 4), (5, 4)], 2)
        (100, 2)
        >>> is_power([(2, 3), (5, 2)])
        False
        >>> is_power(17, 0)
        Traceback (most recent call last):
        ...
        ValueError: is_power: Must have k >= 1.
        >>> is_power(0)
        Traceback (most recent call last):
        ...
        ValueError: is_power: Must have n >= 1.

    Details:
        If n is given as an int and a value of k is given, then this function
        computes the integer kth root r of n and checks if r^k = n. In the case
        where no such k is given, this looks at each k >= 2, extracts the
        integer kth root of n, and uses this to determine if n is a kth power.

        If n is given as a factorization and a value of k is given, this
        function checks if each exponent in the prime factorization of n is
        divisible by k. If no such k is given, this computes the gcd d of the
        exponents in the prime factorization and checks if d > 1.
    """
    if k is not None and k < 1:
        raise ValueError("is_power: Must have k >= 1.")

    if isinstance(n, list):
        if n[0][0] == -1:
            raise ValueError("is_power: Must have n >= 1.")
        n_factorization = n[:]

        kth_root = 1
        if k is not None:
            for (p, e) in n_factorization:
                if e % k == 0:
                    kth_root *= p**(e // k)
                else:
                    return False
            return (kth_root, k)
        else:
            exponents = [e for (p, e) in n_factorization]
            d = gcd_list(exponents)
            if d == 1:
                return False
            else:
                kth_root = 1
                for (p, e) in n_factorization:
                    kth_root *= p**(e // d)
                return (kth_root, d)
    else:
        if n < 1:
            raise ValueError("is_power: Must have n >= 1.")

        if k is not None:
            if k == 1:
                return (n, 1)
            root = integer_nth_root(k, n)
            if root**k == n:
                return (root, k)
            return False

        for k in xrange(2, n.bit_length() + 1):
            base = integer_nth_root(k, n)
            if base**k == n:
                exponent = k

                while True:
                    next_step = is_power(base)
                    if next_step:
                        base = next_step[0]
                        exponent *= next_step[1]
                    else:
                        return (base, exponent)

        return False
Exemplo n.º 9
0
def lehman(n):
    r"""Returns a nontrivial divisor of `n`, or proves primality.

    Given an integer `n` > 1, this algorithm attempts to find a factor of
    `n` using Lehman's method.

    Parameters
    ----------
    n : int (n > 1)

    Returns
    -------
    d : int
        If d == n, then n is proven prime. Otherwise, d is a nontrivial
        divisor of n.

    Notes
    -----
    This algorithm runs in time O(n^(1/3)). This is substantially better
    than O(n^(1/2)) trial division for reasonably small value of n, but
    this algorithm is not suited for large values of n. See section 8.4 of
    [1] or section 5.1.2 of [2] for more details.

    References
    ----------
    .. [1] H. Cohen, "A Course in Computational Algebraic Number Theory",
    Springer-Verlag, New York, 2000.

    .. [2] R. Crandall, C. Pomerance, "Prime Numbers: A Computational
    Perspective", Springer-Verlag, New York, 2001.

    Examples
    --------
    >>> lehman(100)
    2
    >>> lehman(1112470797641561909)
    1056689261L
    """
    # first, we trial divide up to floor(n^(1/3))
    bound = integer_nth_root(3, n)
    d = trial_division(n, bound)
    if d < n:
        return d

    for k in xrange(1, bound + 1):
        if k % 2 == 0:
            r = 1
            m = 2
        else:
            r = k + n
            m = 4
        # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2
        # and a = r (mod m)
        fkn = 4 * k * n
        a = integer_sqrt(fkn)
        # now, increase a until a = r (mod m)
        rm = r % m
        while a % m != rm:
            a += 1
        ub = fkn + bound**2
        while fkn <= a * a <= ub:
            c = a * a - fkn
            b = integer_sqrt(c)
            if b * b == c:
                return gcd(a + b, n)
            a += m
    return n
Exemplo n.º 10
0
def meissel(n):
    if n <= 1:
        return 0
    elif n <= _PRIME_LIST[-1]:
        return bisect(_PRIME_LIST, n)

    root = integer_nth_root(3, n**2)
    primes, pi_cache = pi_table(root)

    a = pi_cache[integer_nth_root(3, n)]
    b = pi_cache[integer_nth_root(2, n)]

    def phi(x, a, cache={}):
        if (x, a) in cache:
            return cache[x, a]

        b = pi_cache[int((x + 0.5)**(0.5))]
        c = pi_cache[int((x + 0.5)**(1.0/3.0))]

        if a <= 7:
            if a == 1:
                value = x - x//2

            elif a == 2:
                value = x - x//2 - x//3 + x//6

            elif a == 3:
                value = x - x//2 - x//3 - x//5 + x//6 + x//10 + x//15 - x//30

            elif a == 4:
                value = (x - x//2 - x//3 - x//5 - x//7 + x//6 + x//10 + x//14 + x//15 + x//21 + x//35 - x//30 - x//42 -
                         x//70 - x//105 + x//210)
            elif a == 5:
                value = (x - x//2 - x//3 - x//5 - x//7 - x//11 + x//6 + x//10 + x//14 + x//22 + x//15 + x//21 + x//33 +
                         x//35 + x//55 + x//77 - x//30 - x//42 - x//66 - x//70 - x//110 - x//154 - x//105 - x//165 -
                         x//231 - x//385 + x//210 + x//330 + x//462 + x//770 + x//1155 - x//2310)
            elif a == 6:
                value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 + x//6 + x//10 + x//14 + x//22 + x//26 + x//15 +
                         x//21 + x//33 + x//39 + x//35 + x//55 + x//65 + x//77 + x//91 + x//143 - x//30 - x//42 - x//66
                         - x//78 - x//70 - x//110 - x//130 - x//154 - x//182 - x//286 - x//105 - x//165 - x//195 -
                         x//231 - x//273 - x//429 - x//385 - x//455 - x//715 - x//1001 + x//210 + x//330 + x//390 +
                         x//462 + x//546 + x//858 + x//770 + x//910 + x//1430 + x//2002 + x//1155 + x//1365 + x//2145 +
                         x//3003 + x//5005 - x//2310 - x//2730 - x//4290 - x//6006 - x//10010 - x//15015 + x//30030)
            else:
                value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 - x//17 + x//6 + x//10 + x//14 + x//22 + x//26 +
                         x//34 + x//15 + x//21 + x//33 + x//39 + x//51 + x//35 + x//55 + x//65 + x//85 + x//77 + x//91 +
                         x//119 + x//143 + x//187 + x//221 - x//30 - x//42 - x//66 - x//78 - x//102 - x//70 - x//110 -
                         x//130 - x//170 - x//154 - x//182 - x//238 - x//286 - x//374 - x//442 - x//105 - x//165 -
                         x//195 - x//255 - x//231 - x//273 - x//357 - x//429 - x//561 - x//663 - x//385 - x//455 -
                         x//595 - x//715 - x//935 - x//1105 - x//1001 - x//1309 - x//1547 - x//2431 + x//210 + x//330 +
                         x//390 + x//510 + x//462 + x//546 + x//714 + x//858 + x//1122 + x//1326 + x//770 + x//910 +
                         x//1190 + x//1430 + x//1870 + x//2210 + x//2002 + x//2618 + x//3094 + x//4862 + x//1155 +
                         x//1365 + x//1785 + x//2145 + x//2805 + x//3315 + x//3003 + x//3927 + x//4641 + x//7293 +
                         x//5005 + x//6545 + x//7735 + x//12155 + x//17017 - x//2310 - x//2730 - x//3570 - x//4290 -
                         x//5610 - x//6630 - x//6006 - x//7854 - x//9282 - x//14586 - x//10010 - x//13090 - x//15470 -
                         x//24310 - x//34034 - x//15015 - x//19635 - x//23205 - x//36465 - x//51051 - x//85085 +
                         x//30030 + x//39270 + x//46410 + x//72930 + x//102102 + x//170170 + x//255255 - x//510510)

        elif b > a >= c and x <= root:
            value = pi_cache[x] - a + 1 + phi2(x, a, b)

        elif a >= b and x <= root:
            value = pi_cache[x] - a + 1

        else:
            value = (x + 1)//2
            for i in xrange(1, a):
                if primes[i] > x:
                    break
                value -= phi(x//primes[i], i)

        cache[x, a] = value
        return value

    def phi2(n, a, b):
        total = (a - b)*(b + a - 1)//2
        for i in xrange(a, b):
            total += pi_cache[n//primes[i]]
        return total

    value = phi(n, a) - 1 + a - phi2(n, a, b)
    return value
Exemplo n.º 11
0
def lmo(x):
    if x <= 1:
        return 0
    elif x <= _PRIME_LIST[-1]:
        return bisect(_PRIME_LIST, x)

    root = integer_nth_root(3, x**2)
    primes = rosemary.number_theory.sieves.primes(root)

    t = integer_nth_root(3, x)
    c = bisect(primes, t)
    b = bisect(primes, integer_nth_root(2, x))

    value = (b + c - 2)*(b - c + 1)//2

    for i in xrange(c, b):
        idx = bisect(primes, x//primes[i])
        value -= idx

    special = defaultdict(list)

    stack = [(1, c, 1)]
    push = stack.append
    pop = stack.pop

    # print "recursing"

    while stack:
        (n, a, sign) = pop()

        if a == 1 and n <= t:
            if sign > 0:
                value += (x//n + 1)//2
            else:
                value -= (x//n + 1)//2
        elif n > t:
            special[a].append((x//n, sign))
        else:
            push((n, a - 1, sign))
            push((n*primes[a - 1], a - 1, -sign))

    block = [1]*(root + 1)
    block[0] = 0

    for a in sorted(special):
        p = primes[a - 1]

        block[p::p] = [0]*(root//p)
        last_v = 0
        last_s = 0

        for v, sign in sorted(special[a]):
            last_s += sum(block[last_v:v + 1])
            last_v = v + 1

            if sign > 0:
                value += last_s
            else:
                value -= last_s

    return value
Exemplo n.º 12
0
def lehmer(n):
    if n <= 1:
        return 0
    elif n <= _PRIME_LIST[-1]:
        return bisect(_PRIME_LIST, n)

    root = integer_nth_root(4, n**3)
    primes = rosemary.number_theory.sieves.primes(root)

    a = bisect(primes, integer_nth_root(4, n))
    b = bisect(primes, integer_sqrt(n))
    c = bisect(primes, integer_nth_root(3, n))

    def phi(x, a, cache={}):
        if (x, a) in cache:
            return cache[x, a]

        if a <= 7:
            if a == 1:
                value = x - x//2

            elif a == 2:
                value = x - x//2 - x//3 + x//6

            elif a == 3:
                value = x - x//2 - x//3 - x//5 + x//6 + x//10 + x//15 - x//30

            elif a == 4:
                value = (x - x//2 - x//3 - x//5 - x//7 + x//6 + x//10 + x//14 + x//15 + x//21 + x//35 - x//30 - x//42 -
                         x//70 - x//105 + x//210)
            elif a == 5:
                value = (x - x//2 - x//3 - x//5 - x//7 - x//11 + x//6 + x//10 + x//14 + x//22 + x//15 + x//21 + x//33 +
                         x//35 + x//55 + x//77 - x//30 - x//42 - x//66 - x//70 - x//110 - x//154 - x//105 - x//165 -
                         x//231 - x//385 + x//210 + x//330 + x//462 + x//770 + x//1155 - x//2310)
            elif a == 6:
                value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 + x//6 + x//10 + x//14 + x//22 + x//26 + x//15 +
                         x//21 + x//33 + x//39 + x//35 + x//55 + x//65 + x//77 + x//91 + x//143 - x//30 - x//42 - x//66
                         - x//78 - x//70 - x//110 - x//130 - x//154 - x//182 - x//286 - x//105 - x//165 - x//195 -
                         x//231 - x//273 - x//429 - x//385 - x//455 - x//715 - x//1001 + x//210 + x//330 + x//390 +
                         x//462 + x//546 + x//858 + x//770 + x//910 + x//1430 + x//2002 + x//1155 + x//1365 + x//2145 +
                         x//3003 + x//5005 - x//2310 - x//2730 - x//4290 - x//6006 - x//10010 - x//15015 + x//30030)
            else:
                value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 - x//17 + x//6 + x//10 + x//14 + x//22 + x//26 +
                         x//34 + x//15 + x//21 + x//33 + x//39 + x//51 + x//35 + x//55 + x//65 + x//85 + x//77 + x//91 +
                         x//119 + x//143 + x//187 + x//221 - x//30 - x//42 - x//66 - x//78 - x//102 - x//70 - x//110 -
                         x//130 - x//170 - x//154 - x//182 - x//238 - x//286 - x//374 - x//442 - x//105 - x//165 -
                         x//195 - x//255 - x//231 - x//273 - x//357 - x//429 - x//561 - x//663 - x//385 - x//455 -
                         x//595 - x//715 - x//935 - x//1105 - x//1001 - x//1309 - x//1547 - x//2431 + x//210 + x//330 +
                         x//390 + x//510 + x//462 + x//546 + x//714 + x//858 + x//1122 + x//1326 + x//770 + x//910 +
                         x//1190 + x//1430 + x//1870 + x//2210 + x//2002 + x//2618 + x//3094 + x//4862 + x//1155 +
                         x//1365 + x//1785 + x//2145 + x//2805 + x//3315 + x//3003 + x//3927 + x//4641 + x//7293 +
                         x//5005 + x//6545 + x//7735 + x//12155 + x//17017 - x//2310 - x//2730 - x//3570 - x//4290 -
                         x//5610 - x//6630 - x//6006 - x//7854 - x//9282 - x//14586 - x//10010 - x//13090 - x//15470 -
                         x//24310 - x//34034 - x//15015 - x//19635 - x//23205 - x//36465 - x//51051 - x//85085 +
                         x//30030 + x//39270 + x//46410 + x//72930 + x//102102 + x//170170 + x//255255 - x//510510)

        elif a >= bisect(primes, x**(0.5)) and x < primes[-1]:
            pi = bisect(primes, x)
            value = pi - a + 1

        else:
            value = (x + 1)//2
            for i in xrange(1, a):
                if primes[i] > x:
                    break
                value -= phi(x//primes[i], i)

        cache[x, a] = value
        return value

    def phi2(n, a, b):
        s1 = 0
        for i in xrange(a, b):
            s1 += phi(n//primes[i], b) + b - 1
        return s1

    def phi3(n, a, b, c):
        s2 = 0
        for i in xrange(a, c):
            bi = phi(integer_sqrt(n//primes[i]), b) + b - 1
            for j in xrange(i, bi):
                idx = phi(n//(primes[i]*primes[j]), b) + b - 1
                s2 += idx - j
        return s2

    value = (b + a - 2)*(b - a + 1)//2 + phi(n, a) - phi2(n, a, b) - phi3(n, a, b, c)
    return value
Exemplo n.º 13
0
def lehman(n):
    r"""Returns a nontrivial divisor of `n`, or proves primality.

    Given an integer `n` > 1, this algorithm attempts to find a factor of
    `n` using Lehman's method.

    Parameters
    ----------
    n : int (n > 1)

    Returns
    -------
    d : int
        If d == n, then n is proven prime. Otherwise, d is a nontrivial
        divisor of n.

    Notes
    -----
    This algorithm runs in time O(n^(1/3)). This is substantially better
    than O(n^(1/2)) trial division for reasonably small value of n, but
    this algorithm is not suited for large values of n. See section 8.4 of
    [1] or section 5.1.2 of [2] for more details.

    References
    ----------
    .. [1] H. Cohen, "A Course in Computational Algebraic Number Theory",
    Springer-Verlag, New York, 2000.

    .. [2] R. Crandall, C. Pomerance, "Prime Numbers: A Computational
    Perspective", Springer-Verlag, New York, 2001.

    Examples
    --------
    >>> lehman(100)
    2
    >>> lehman(1112470797641561909)
    1056689261L
    """
    # first, we trial divide up to floor(n^(1/3))
    bound = integer_nth_root(3, n)
    d = trial_division(n, bound)
    if d < n:
        return d

    for k in xrange(1, bound + 1):
        if k % 2 == 0:
            r = 1
            m = 2
        else:
            r = k + n
            m = 4
        # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2
        # and a = r (mod m)
        fkn = 4*k*n
        a = integer_sqrt(fkn)
        # now, increase a until a = r (mod m)
        rm = r % m
        while a % m != rm:
            a += 1
        ub = fkn + bound**2
        while fkn <= a*a <= ub:
            c = a*a - fkn
            b = integer_sqrt(c)
            if b*b == c:
                return gcd(a + b, n)
            a += m
    return n