コード例 #1
0
def poly_prime_gcd(f,g,p):
    """
    Algorithm 2.2.1 (gcd for polynomials), p. 90
    from Crandall and Pomerance,
    Prime Numbers, A Computational Perspective.

    For given polynomials f(x),
    g(x) in F[x], not both zero, this algorithm
    returns d(x) = gcd(f(x),g(x)
    """


    # 1. [initialize]

    zero = poly1d([0])
    if f.order < g.order or f == zero:
        f,g = g,f

        
    # 2. [Euclid loop]

    while g != zero:
        f,g = g, poly_prime_mod(f,g,p)

        
    # 3. [Make Monic]
    # take the leading coefficient.
    flc = f.c[0]
    
    # invert it.
    c = inverse(flc,p)
    
    # and multiply with f.
    return reduce_prime_poly(f*c,p)
コード例 #2
0
def poly_prime_divmod(f,g,p):

    """ 
    f and g are polynomials in F_p[x]
    return q,r such that 
    f = q*g + r 
    and r.order < g.order
    """
    zero = poly1d([0])
    x = poly1d([1,0])

    d = f.order - g.order
    if d < 0:
        return zero, f

    if g == zero:
        raise ZeroDivisionError ("divmod(f,0) is undefined for all f")
    # this is a case which requires some thought.
    
    if f.order == 0:
        
        flc,glc = f.c[0],g.c[0] # get leading terms
        c = poly1d([inverse(glc,p)*flc % p])
        c = reduce_prime_poly(c,p)
        return c,zero
        
            
    count = 0
    while d >= 0 and f != zero:
        flc,glc = f.c[0],g.c[0] # get leading terms

        c = poly1d([inverse(glc,p)*flc % p])
        term = c*(x**d)

        # term*g has same degree and same leading coefficient as f.
        # The following is calculated to reduce degree of f.

        f = f - term*g  
        f = reduce_prime_poly(f,p)
       
        count += term
        d = f.order - g.order

    count = reduce_prime_poly(count,p)
    return count, f
コード例 #3
0
def poly_prime_divmod(f, g, p):
    """ 
    f and g are polynomials in F_p[x]
    return q,r such that 
    f = q*g + r 
    and r.order < g.order
    """
    zero = poly1d([0])
    x = poly1d([1, 0])

    d = f.order - g.order
    if d < 0:
        return zero, f

    if g == zero:
        raise ZeroDivisionError("divmod(f,0) is undefined for all f")
    # this is a case which requires some thought.

    if f.order == 0:

        flc, glc = f.c[0], g.c[0]  # get leading terms
        c = poly1d([inverse(glc, p) * flc % p])
        c = reduce_prime_poly(c, p)
        return c, zero

    count = 0
    while d >= 0 and f != zero:
        flc, glc = f.c[0], g.c[0]  # get leading terms

        c = poly1d([inverse(glc, p) * flc % p])
        term = c * (x**d)

        # term*g has same degree and same leading coefficient as f.
        # The following is calculated to reduce degree of f.

        f = f - term * g
        f = reduce_prime_poly(f, p)

        count += term
        d = f.order - g.order

    count = reduce_prime_poly(count, p)
    return count, f
コード例 #4
0
def poly_gcd_extended(f,g,p):
    """
    Algorithm 2.2.2 (Extended gcd for polynomials)
    p. 91 from Crandall and Pomerance, 
    Prime Numbers, a Computational Perspective.

    Let F be a field.  For given polynomials,
    f(x), g(x) in F[x], not both zero, with
    either deg f(x) >= deg g(x) or g(x) == 0,
    this algorithm returns (s(x),t(x),d(x)) in
    F[x] such that d = gcd (f,g) and sf + tg =
    d.  (For ease of notation, we may drop the
    x argument). 
    """
    def rpp(f):
        return reduce_prime_poly(f,p)
    

    # 1. [initialize]

    zero = poly1d([0])
    one = poly1d([1])
    f = reduce_prime_poly(f,p)
    g = reduce_prime_poly(g,p)
    swap = False
    if f.order < g.order or f == zero:
        f,g = g,f
        swap = True

    s,t,d,u,v,w = one,zero,f,zero,one,g


        
    # 2. [Extended Euclid loop]

    while w != zero:
        q,r = poly_prime_divmod(d,w,p)
        s,t,d,u,v,w = u,v,w,rpp(s-q*u), rpp(t-q*v), r        

    
    # 3. [Make Monic]
    
    # take the leading coefficient of d.
    # invert it.
    
    c = poly1d([inverse(d.c[0],p)])
    if swap:
        s,t = t,s
    s,t,d = rpp(c*s), rpp(c*t), rpp(c*d)

    return s,t,d
コード例 #5
0
def poly_gcd_extended(f, g, p):
    """
    Algorithm 2.2.2 (Extended gcd for polynomials)
    p. 91 from Crandall and Pomerance, 
    Prime Numbers, a Computational Perspective.

    Let F be a field.  For given polynomials,
    f(x), g(x) in F[x], not both zero, with
    either deg f(x) >= deg g(x) or g(x) == 0,
    this algorithm returns (s(x),t(x),d(x)) in
    F[x] such that d = gcd (f,g) and sf + tg =
    d.  (For ease of notation, we may drop the
    x argument). 
    """
    def rpp(f):
        return reduce_prime_poly(f, p)

    # 1. [initialize]

    zero = poly1d([0])
    one = poly1d([1])
    f = reduce_prime_poly(f, p)
    g = reduce_prime_poly(g, p)
    swap = False
    if f.order < g.order or f == zero:
        f, g = g, f
        swap = True

    s, t, d, u, v, w = one, zero, f, zero, one, g

    # 2. [Extended Euclid loop]

    while w != zero:
        q, r = poly_prime_divmod(d, w, p)
        s, t, d, u, v, w = u, v, w, rpp(s - q * u), rpp(t - q * v), r

    # 3. [Make Monic]

    # take the leading coefficient of d.
    # invert it.

    c = poly1d([inverse(d.c[0], p)])
    if swap:
        s, t = t, s
    s, t, d = rpp(c * s), rpp(c * t), rpp(c * d)

    return s, t, d
コード例 #6
0
def make_monic(f,p):
    if type(f) == int:
        f = poly1d([f])
    f = reduce_prime_poly(f,p)
    r = deque(f.c.tolist())

    # multiply each term by inverse of leading coefficient

    factor = inverse(f.c[0],p)
    l = []
    while r:
        # take c off of the right
        c = r.popleft()
        # reduce it mod p and append it to the left.
        l.append(int(factor * c)%p)
    # return a monic poly
    return poly1d(l)