예제 #1
0
def zzx_hensel_lift(p, f, f_list, l):
    """Multifactor Hensel lifting.

       Given a prime p, polynomial f over Z[x] such that lc(f) is a
       unit modulo p,  monic pair-wise coprime polynomials f_i over
       Z[x] satisfying:

                    f = lc(f) f_1 ... f_r (mod p)

       and a positive integer l, returns a list of monic polynomials
       F_1, F_2, ..., F_r satisfying:

                    f = lc(f) F_1 ... F_r (mod p**l)

                    F_i = f_i (mod p), i = 1..r

       For more details on the implemented algorithm refer to:

       [1] J. von zur Gathen, J. Gerhard, Modern Computer Algebra,
           First Edition, Cambridge University Press, 1999, pp. 424

    """
    r = len(f_list)
    lc = zzx_LC(f)

    if r == 1:
        F = zzx_mul_term(f, igcdex(lc, p**l)[0], 0)
        return [zzx_trunc(F, p**l)]

    m = p
    k = int(r // 2)
    d = int(ceil(log(l, 2)))

    g = gf_from_int_poly([lc], p)

    for f_i in f_list[:k]:
        g = gf_mul(g, gf_from_int_poly(f_i, p), p)

    h = gf_from_int_poly(f_list[k], p)

    for f_i in f_list[k + 1:]:
        h = gf_mul(h, gf_from_int_poly(f_i, p), p)

    s, t, _ = gf_gcdex(g, h, p)

    g = gf_to_int_poly(g, p)
    h = gf_to_int_poly(h, p)
    s = gf_to_int_poly(s, p)
    t = gf_to_int_poly(t, p)

    for _ in range(1, d + 1):
        (g, h, s, t), m = zzx_hensel_step(m, f, g, h, s, t), m**2

    return zzx_hensel_lift(p, g, f_list[:k], l) \
         + zzx_hensel_lift(p, h, f_list[k:], l)
예제 #2
0
def zzx_hensel_lift(p, f, f_list, l):
    """Multifactor Hensel lifting.

       Given a prime p, polynomial f over Z[x] such that lc(f) is a
       unit modulo p,  monic pair-wise coprime polynomials f_i over
       Z[x] satisfying:

                    f = lc(f) f_1 ... f_r (mod p)

       and a positive integer l, returns a list of monic polynomials
       F_1, F_2, ..., F_r satisfying:

                    f = lc(f) F_1 ... F_r (mod p**l)

                    F_i = f_i (mod p), i = 1..r

       For more details on the implemented algorithm refer to:

       [1] J. von zur Gathen, J. Gerhard, Modern Computer Algebra,
           First Edition, Cambridge University Press, 1999, pp. 424

    """
    r = len(f_list)
    lc = zzx_LC(f)

    if r == 1:
        F = zzx_mul_term(f, igcdex(lc, p**l)[0], 0)
        return [ zzx_trunc(F, p**l) ]

    m = p
    k = int(r // 2)
    d = int(ceil(log(l, 2)))

    g = gf_from_int_poly([lc], p)

    for f_i in f_list[:k]:
        g = gf_mul(g, gf_from_int_poly(f_i, p), p)

    h = gf_from_int_poly(f_list[k], p)

    for f_i in f_list[k+1:]:
        h = gf_mul(h, gf_from_int_poly(f_i, p), p)

    s, t, _ = gf_gcdex(g, h, p)

    g = gf_to_int_poly(g, p)
    h = gf_to_int_poly(h, p)
    s = gf_to_int_poly(s, p)
    t = gf_to_int_poly(t, p)

    for _ in range(1, d+1):
        (g, h, s, t), m = zzx_hensel_step(m, f, g, h, s, t), m**2

    return zzx_hensel_lift(p, g, f_list[:k], l) \
         + zzx_hensel_lift(p, h, f_list[k:], l)
예제 #3
0
def test_gf_arith():
    assert gf_neg([], 11) == []
    assert gf_neg([1], 11) == [10]
    assert gf_neg([1,2,3], 11) == [10,9,8]

    assert gf_add_const([], 0, 11) == []
    assert gf_sub_const([], 0, 11) == []

    assert gf_add_const([], 3, 11) == [3]
    assert gf_sub_const([], 3, 11) == [8]

    assert gf_add_const([1], 3, 11) == [4]
    assert gf_sub_const([1], 3, 11) == [9]

    assert gf_add_const([8], 3, 11) == []
    assert gf_sub_const([3], 3, 11) == []

    assert gf_add_const([1,2,3], 3, 11) == [1,2,6]
    assert gf_sub_const([1,2,3], 3, 11) == [1,2,0]

    assert gf_mul_const([], 0, 11) == []
    assert gf_mul_const([], 1, 11) == []

    assert gf_mul_const([1], 0, 11) == []
    assert gf_mul_const([1], 1, 11) == [1]

    assert gf_mul_const([1,2,3], 0, 11) == []
    assert gf_mul_const([1,2,3], 1, 11) == [1,2,3]
    assert gf_mul_const([1,2,3], 7, 11) == [7,3,10]

    assert gf_add([], [], 11) == []
    assert gf_add([1], [], 11) == [1]
    assert gf_add([], [1], 11) == [1]
    assert gf_add([1], [1], 11) == [2]
    assert gf_add([1], [2], 11) == [3]

    assert gf_add([1,2], [1], 11) == [1,3]
    assert gf_add([1], [1,2], 11) == [1,3]

    assert gf_add([1,2,3], [8,9,10], 11) == [9,0,2]

    assert gf_sub([], [], 11) == []
    assert gf_sub([1], [], 11) == [1]
    assert gf_sub([], [1], 11) == [10]
    assert gf_sub([1], [1], 11) == []
    assert gf_sub([1], [2], 11) == [10]

    assert gf_sub([1,2], [1], 11) == [1,1]
    assert gf_sub([1], [1,2], 11) == [10,10]

    assert gf_sub([3,2,1], [8,9,10], 11) == [6,4,2]

    assert gf_add_mul([1,5,6], [7,3], [8,0,6,1], 11) == [1,2,10,8,9]
    assert gf_sub_mul([1,5,6], [7,3], [8,0,6,1], 11) == [10,9,3,2,3]

    assert gf_mul([], [], 11) == []
    assert gf_mul([], [1], 11) == []
    assert gf_mul([1], [], 11) == []
    assert gf_mul([1], [1], 11) == [1]
    assert gf_mul([5], [7], 11) == [2]

    assert gf_mul([3,0,0,6,1,2], [4,0,1,0], 11) == [1,0,3,2,4,3,1,2,0]
    assert gf_mul([4,0,1,0], [3,0,0,6,1,2], 11) == [1,0,3,2,4,3,1,2,0]

    assert gf_mul([2,0,0,1,7], [2,0,0,1,7], 11) == [4,0,0,4,6,0,1,3,5]

    assert gf_sqr([], 11) == []
    assert gf_sqr([2], 11) == [4]
    assert gf_sqr([1,2], 11) == [1,4,4]

    assert gf_sqr([2,0,0,1,7], 11) == [4,0,0,4,6,0,1,3,5]