Esempio n. 1
0
def aks(n):
    """
    AKS ( Cyclotomic Congruence Test ) primality test for a natural number.
    
    Input: a natural number n ( n > 1 ).
    Output: n is prime => return True
            n is not prime => return False.
    """
    import nzmath.multiplicative as multiplicative

    if arith1.powerDetection(n)[1] != 1:  #Power Detection
        return False

    lg = math.log(n, 2)
    k = int(lg * lg)

    start = 3
    while 1:
        d = gcd.gcd(start, n)
        if 1 < d < n:
            return False
        x = n % start
        N = x
        for i in range(1, k + 1):
            if N == 1:
                break
            N = (N * x) % start
        if i == k:
            r = start
            break
        start += 1
    d = gcd.gcd(r, n)
    if 1 < d < n:
        return False
    if n <= r:
        return True

    e = multiplicative.euler(r)  #Cyclotomic Conguence
    e = math.sqrt(e)
    e = int(e * lg)
    for b in range(1, e + 1):
        f = array_poly.ArrayPolyMod([b, 1], n)
        total = array_poly.ArrayPolyMod([1], n)
        count = n
        while count > 0:
            if count & 1:
                total = total * f
                total = _aks_mod(total, r)
            f = f.power()
            f = _aks_mod(f, r)
            count = count >> 1
        total_poly = total.coefficients_to_dict()
        if total_poly != {0: b, n % r: 1}:
            return False
    return True
Esempio n. 2
0
def log(x, base=None, err=defaultError):
    """
    log(x) returns logarithm of a positive number x.  If an additional
    argument base is given, it returns logarithm of x to the base.
    """
    if isinstance(x, complex):
        raise TypeError("real.log is not for complex numbers.")
    if x <= 0:
        raise ValueError("log is not defined for %s" % str(x))
    if err <= defaultError:
        if base:
            d = log(base, err=err)
        else:
            d = 1
        rx = rational.Rational(x)
        upper = rational.Rational(4, 3)
        lower = rational.Rational(2, 3)
        shift = 0
        while rx > upper:
            rx /= 2
            shift += 1
        while rx < lower:
            rx *= 2
            shift -= 1
        if rx == 1:
            return shift * _log2(err) / d
        value = oldvalue = 0
        for term in log1piter(rx - 1):
            value += term
            if err.nearlyEqual(value, oldvalue):
                break
            oldvalue = +value
        if shift != 0:
            return (value + shift * _log2(err)) / d
    else:
        if base:
            value = rational.Rational(math.log(x, base))
        else:
            value = rational.Rational(math.log(x))
        return value