def strong_pseudoprimes(a):
    """
    Strong Pseudoprimes to Base a
    
    Args:
        a -- integer greater than 1
    
    OEIS
    """

    require_integers(["a"], [a])
    require_geq(["a"], [a], 2)

    for c in composites():
        if c % 2 == 1:
            d = c - 1
            r = 0

            d, r = factor_out_twos(d)

            if (a**d) % c == 1:
                yield c
                continue

            for e in range(0, r):
                if pow(a, (d * 2**e), c) == c - 1:
                    yield c
                    continue
def lucas_pseudoprimes(P, Q):
    """
    Lucas Pseudoprimes: Composite number passing the Lucas primality test for P and Q
    
    Args:
        P -- integer greater than zero
        Q -- integer
    
    OEIS
    """

    require_integers(["P", "Q"], [P, Q])
    require_geq(["P"], [P], 1)

    D = P * P - 4 * Q

    #rather than recompute we will step the sequence as needed
    lucas_pos = 0
    a, b = 0, 1

    for c in composites():
        if c % 2 == 1:
            if gcd(c, Q) == 1:
                delta = c - jacobi_symbol(D, c)

                if delta > lucas_pos:
                    for i in range(delta - lucas_pos):
                        a, b = b, P * b - Q * a

                    lucas_pos += delta - lucas_pos

                if a % c == 0:
                    yield c
def euler_jacobi_pseudoprimes():
    """
    Euler-Jacobi Pseudoprimes\n
    OEIS A047713
    """

    for c in composites():
        if c % 2 == 1:
            if 2**((c - 1) // 2) % c == jacobi_symbol(2, c) % c:
                yield c
def euler_pseudoprimes():
    """
    Euler Pseudoprimes\n
    OEIS A006970
    """

    for c in composites():
        if c % 2 == 1:
            if 2**((c - 1) // 2) % c in (1, c - 1):
                yield c
def strong_lucas_pseudoprimes(P, Q):
    """
    Lucas Pseudoprimes: Composite numbers passing either of two the Lucas primality tests for P and Q\n
    OEIS
    """
    def lucas_U_test(n, d, P, Q):
        a, b = 0, 1
        for i in range(d):
            a, b = b, (P * b - Q * a) % n
        if a == 0:
            return True
        return False

    def lucas_V_test(n, d, s, P, Q):
        a, b = 2, P
        ctr = d
        nctr = 0
        for k in range(ctr):
            a, b = b, (P * b - Q * a) % n
            nctr += 1
        if a == 0:
            return True
        while ctr < d * (2**(s - 1)):
            for k in range(ctr):
                a, b = b, (P * b - Q * a) % n
                nctr += 1
            ctr *= 2
            if a == 0:
                return True
        return False

    D = P * P - 4 * Q

    for n in composites():
        if n % 2 == 0:
            continue

        if gcd(n, D) != 1:
            continue

        delta = n - jacobi_symbol(D, n)
        d, s = factor_out_twos(delta)

        # Check with a Lucas V-Sequence
        if lucas_U_test(n, d, P, Q):
            yield n
            continue

        # Check with a Lucas V-Sequence
        if lucas_V_test(n, d, s, P, Q):
            yield n
def carmichael_numbers():
    """
    Charmichael Numbers: Composite numbers that are Fermat Pseudoprimes to all bases\n
    OEIS A002997
    """
    def all_fermat_test(n):
        B = coprime_to(n)
        for b in B:
            if pow(b, n - 1, n) != 1:
                return False
        return True

    for c in composites():
        if all_fermat_test(c):
            yield c
def fermat_pseudoprimes(a):
    """
    Fermat Pseudoprimes to Base a
    
    Args:
        a -- integer greater than 1
    
    OEIS A001567, A005935-A005939
    """

    require_integers(["a"], [a])
    require_geq(["a"], [a], 2)

    for c in composites():
        if pow(a, c - 1, c) == 1:
            yield c
def weak_pseudoprimes(a):
    """
    Weak Pseudoprimes to Base a
    
    Args:
        a -- integer greater than 1
    
    OEIS
    """

    require_integers(["a"], [a])
    require_geq(["a"], [a], 2)

    yield 1

    for c in composites():
        if pow(a, c, c) == a:
            yield c
def pell_pseudoprimes_2():
    """
    Pell Pseudoprimes: Passes a version of the Pell primality test\n
    OEIS A099011
    """

    lucas_pos = 0
    a, b = 0, 1

    for c in composites():
        if c % 2 == 1:

            for i in range(c - lucas_pos):
                a, b = b, 2 * b + a

            lucas_pos += c - lucas_pos

            if (a - jacobi_symbol(2, c)) % c == 0:
                yield c
Esempio n. 10
0
def fibonacci_pseudoprimes():
    """
    Fibonacci Pseudoprimes: Special case of Lucas Pseudoprimes, also excluding multiples of 5\n
    OEIS A081264
    """

    lucas_pos = 0
    a, b = 0, 1

    for c in composites():
        if c % 2 == 1 and c % 5 != 0:
            delta = c - jacobi_symbol(5, c)

            if delta > lucas_pos:
                for i in range(delta - lucas_pos):
                    a, b = b, b + a

                lucas_pos += delta - lucas_pos

            if a % c == 0:
                yield c