Пример #1
0
def dmp_zz_wang_lead_coeffs(f, T, cs, E, H, A, u, K):
    """Wang/EEZ: Compute correct leading coefficients. """
    C, J, v = [], [0]*len(E), u-1

    for h in H:
        c = dmp_one(v, K)
        d = dup_LC(h, K)*cs

        for i in reversed(xrange(len(E))):
            k, e, (t, _) = 0, E[i], T[i]

            while not (d % e):
                d, k = d//e, k+1

            if k != 0:
                c, J[i] = dmp_mul(c, dmp_pow(t, k, v, K), v, K), 1

        C.append(c)

    if any([ not j for j in J ]):
        raise ExtraneousFactors # pragma: no cover

    CC, HH = [], []

    for c, h in zip(C, H):
        d = dmp_eval_tail(c, A, v, K)
        lc = dup_LC(h, K)

        if K.is_one(cs):
            cc = lc//d
        else:
            g = K.gcd(lc, d)
            d, cc = d//g, lc//g
            h, cs = dup_mul_ground(h, d, K), cs//d

        c = dmp_mul_ground(c, cc, v, K)

        CC.append(c)
        HH.append(h)

    if K.is_one(cs):
        return f, HH, CC

    CCC, HHH = [], []

    for c, h in zip(CC, HH):
        CCC.append(dmp_mul_ground(c, cs, v, K))
        HHH.append(dmp_mul_ground(h, cs, 0, K))

    f = dmp_mul_ground(f, cs**(len(H)-1), u, K)

    return f, HHH, CCC
Пример #2
0
def dmp_zz_wang_hensel_lifting(f, H, LC, A, p, u, K):
    """Wang/EEZ: Parallel Hensel lifting algorithm. """
    S, n, v = [f], len(A), u-1

    H = list(H)

    for i, a in enumerate(reversed(A[1:])):
        s = dmp_eval_in(S[0], a, n-i, u-i, K)
        S.insert(0, dmp_ground_trunc(s, p, v-i, K))

    d = max(dmp_degree_list(f, u)[1:])

    for j, s, a in zip(xrange(2, n+2), S, A):
        G, w = list(H), j-1

        I, J = A[:j-2], A[j-1:]

        for i, (h, lc) in enumerate(zip(H, LC)):
            lc = dmp_ground_trunc(dmp_eval_tail(lc, J, v, K), p, w-1, K)
            H[i] = [lc] + dmp_raise(h[1:], 1, w-1, K)

        m = dmp_nest([K.one, -a], w, K)
        M = dmp_one(w, K)

        c = dmp_sub(s, dmp_expand(H, w, K), w, K)

        dj = dmp_degree_in(s, w, w)

        for k in xrange(0, dj):
            if dmp_zero_p(c, w):
                break

            M = dmp_mul(M, m, w, K)
            C = dmp_diff_eval_in(c, k+1, a, w, w, K)

            if not dmp_zero_p(C, w-1):
                C = dmp_quo_ground(C, K.factorial(k+1), w-1, K)
                T = dmp_zz_diophantine(G, C, I, d, p, w-1, K)

                for i, (h, t) in enumerate(zip(H, T)):
                    h = dmp_add_mul(h, dmp_raise(t, 1, w-1, K), M, w, K)
                    H[i] = dmp_ground_trunc(h, p, w, K)

                h = dmp_sub(s, dmp_expand(H, w, K), w, K)
                c = dmp_ground_trunc(h, p, w, K)

    if dmp_expand(H, u, K) != f:
        raise ExtraneousFactors # pragma: no cover
    else:
        return H
Пример #3
0
def dmp_zz_wang_test_points(f, T, ct, A, u, K):
    """Wang/EEZ: Test evaluation points for suitability. """
    if not dmp_eval_tail(dmp_LC(f, K), A, u-1, K):
        raise EvaluationFailed('no luck')

    g = dmp_eval_tail(f, A, u, K)

    if not dup_sqf_p(g, K):
        raise EvaluationFailed('no luck')

    c, h = dup_primitive(g, K)

    if K.is_negative(dup_LC(h, K)):
        c, h = -c, dup_neg(h, K)

    v = u-1

    E = [ dmp_eval_tail(t, A, v, K) for t, _ in T ]
    D = dmp_zz_wang_non_divisors(E, c, ct, K)

    if D is not None:
        return c, h, E
    else:
        raise EvaluationFailed('no luck')
Пример #4
0
def test_dmp_eval_tail():
    assert dmp_eval_tail([[]], [1], 1, ZZ) == []
    assert dmp_eval_tail([[[]]], [1], 2, ZZ) == [[]]
    assert dmp_eval_tail([[[]]], [1, 2], 2, ZZ) == []

    assert dmp_eval_tail(f_0, [], 2, ZZ) == f_0

    assert dmp_eval_tail(f_0, [1, -17, 8], 2, ZZ) == 84496
    assert dmp_eval_tail(f_0, [-17, 8], 2, ZZ) == [-1409, 3, 85902]
    assert dmp_eval_tail(f_0, [8], 2, ZZ) == [[83, 2], [3], [302, 81, 1]]

    assert dmp_eval_tail(f_1, [-17, 8], 2, ZZ) == [-136, 15699, 9166, -27144]

    assert dmp_eval_tail(
        f_2, [-12, 3], 2, ZZ) == [-1377, 0, -702, -1224, 0, -624]
    assert dmp_eval_tail(
        f_3, [-12, 3], 2, ZZ) == [144, 82, -5181, -28872, -14868, -540]

    assert dmp_eval_tail(
        f_4, [25, -1], 2, ZZ) == [152587890625, 9765625, -59605407714843750,
        -3839159765625, -1562475, 9536712644531250, 610349546750, -4, 24414375000, 1562520]
    assert dmp_eval_tail(f_5, [25, -1], 2, ZZ) == [-1, -78, -2028, -17576]

    assert dmp_eval_tail(f_6, [0, 2, 4], 3, ZZ) == [5040, 0, 0, 4480]
Пример #5
0
def test_dmp_eval_tail():
    assert dmp_eval_tail([[]], [1], 1, ZZ) == []
    assert dmp_eval_tail([[[]]], [1], 2, ZZ) == [[]]
    assert dmp_eval_tail([[[]]], [1, 2], 2, ZZ) == []

    assert dmp_eval_tail(f_0, [], 2, ZZ) == f_0

    assert dmp_eval_tail(f_0, [1, -17, 8], 2, ZZ) == 84496
    assert dmp_eval_tail(f_0, [-17, 8], 2, ZZ) == [-1409, 3, 85902]
    assert dmp_eval_tail(f_0, [8], 2, ZZ) == [[83, 2], [3], [302, 81, 1]]

    assert dmp_eval_tail(f_1, [-17, 8], 2, ZZ) == [-136, 15699, 9166, -27144]

    assert dmp_eval_tail(f_2, [-12, 3], 2,
                         ZZ) == [-1377, 0, -702, -1224, 0, -624]
    assert dmp_eval_tail(f_3, [-12, 3], 2,
                         ZZ) == [144, 82, -5181, -28872, -14868, -540]

    assert dmp_eval_tail(f_4, [25, -1], 2, ZZ) == [
        152587890625, 9765625, -59605407714843750, -3839159765625, -1562475,
        9536712644531250, 610349546750, -4, 24414375000, 1562520
    ]
    assert dmp_eval_tail(f_5, [25, -1], 2, ZZ) == [-1, -78, -2028, -17576]

    assert dmp_eval_tail(f_6, [0, 2, 4], 3, ZZ) == [5040, 0, 0, 4480]
Пример #6
0
def test_dmp_zz_wang():
    p = ZZ(nextprime(dmp_zz_mignotte_bound(w_1, 2, ZZ)))

    assert p == ZZ(6291469)

    t_1, k_1, e_1 = dmp_normal([[1], []], 1, ZZ), 1, ZZ(-14)
    t_2, k_2, e_2 = dmp_normal([[1, 0]], 1, ZZ), 2, ZZ(3)
    t_3, k_3, e_3 = dmp_normal([[1], [1, 0]], 1, ZZ), 2, ZZ(-11)
    t_4, k_4, e_4 = dmp_normal([[1], [-1, 0]], 1, ZZ), 1, ZZ(-17)

    T = [t_1, t_2, t_3, t_4]
    K = [k_1, k_2, k_3, k_4]
    E = [e_1, e_2, e_3, e_4]

    T = zip(T, K)

    A = [ZZ(-14), ZZ(3)]

    S = dmp_eval_tail(w_1, A, 2, ZZ)
    cs, s = dup_primitive(S, ZZ)

    assert cs == 1 and s == S == \
        dup_normal([1036728, 915552, 55748, 105621, -17304, -26841, -644], ZZ)

    assert dmp_zz_wang_non_divisors(E, cs, 4, ZZ) == [7, 3, 11, 17]
    assert dup_sqf_p(s, ZZ) and dup_degree(s) == dmp_degree(w_1, 2)

    _, H = dup_zz_factor_sqf(s, ZZ)

    h_1 = dup_normal([44, 42, 1], ZZ)
    h_2 = dup_normal([126, -9, 28], ZZ)
    h_3 = dup_normal([187, 0, -23], ZZ)

    assert H == [h_1, h_2, h_3]

    lc_1 = dmp_normal([[-4], [-4, 0]], 1, ZZ)
    lc_2 = dmp_normal([[-1, 0, 0], []], 1, ZZ)
    lc_3 = dmp_normal([[1], [], [-1, 0, 0]], 1, ZZ)

    LC = [lc_1, lc_2, lc_3]

    assert dmp_zz_wang_lead_coeffs(w_1, T, cs, E, H, A, 2, ZZ) == (w_1, H, LC)

    H_1 = [
        dmp_normal(t, 0, ZZ)
        for t in [[44L, 42L, 1L], [126L, -9L, 28L], [187L, 0L, -23L]]
    ]
    H_2 = [
        dmp_normal(t, 1, ZZ)
        for t in [[[-4, -12], [-3, 0], [1]], [[-9, 0], [-9], [-2, 0]],
                  [[1, 0, -9], [], [1, -9]]]
    ]
    H_3 = [
        dmp_normal(t, 1, ZZ)
        for t in [[[-4, -12], [-3, 0], [1]], [[-9, 0], [-9], [-2, 0]],
                  [[1, 0, -9], [], [1, -9]]]
    ]

    c_1 = dmp_normal([-70686, -5863, -17826, 2009, 5031, 74], 0, ZZ)
    c_2 = dmp_normal(
        [[9, 12, -45, -108, -324], [18, -216, -810, 0],
         [2, 9, -252, -288, -945], [-30, -414, 0], [2, -54, -3, 81], [12, 0]],
        1, ZZ)
    c_3 = dmp_normal(
        [[-36, -108, 0], [-27, -36, -108], [-8, -42, 0], [-6, 0, 9], [2, 0]],
        1, ZZ)

    T_1 = [dmp_normal(t, 0, ZZ) for t in [[-3, 0], [-2], [1]]]
    T_2 = [dmp_normal(t, 1, ZZ) for t in [[[-1, 0], []], [[-3], []], [[-6]]]]
    T_3 = [dmp_normal(t, 1, ZZ) for t in [[[]], [[]], [[-1]]]]

    assert dmp_zz_diophantine(H_1, c_1, [], 5, p, 0, ZZ) == T_1
    assert dmp_zz_diophantine(H_2, c_2, [ZZ(-14)], 5, p, 1, ZZ) == T_2
    assert dmp_zz_diophantine(H_3, c_3, [ZZ(-14)], 5, p, 1, ZZ) == T_3

    factors = dmp_zz_wang_hensel_lifting(w_1, H, LC, A, p, 2, ZZ)

    assert dmp_expand(factors, 2, ZZ) == w_1
Пример #7
0
def test_dmp_zz_wang():
    p = ZZ(nextprime(dmp_zz_mignotte_bound(w_1, 2, ZZ)))

    assert p == ZZ(6291469)

    t_1, k_1, e_1 = dmp_normal([[1],[]], 1, ZZ), 1, ZZ(-14)
    t_2, k_2, e_2 = dmp_normal([[1, 0]], 1, ZZ), 2, ZZ(3)
    t_3, k_3, e_3 = dmp_normal([[1],[ 1, 0]], 1, ZZ), 2, ZZ(-11)
    t_4, k_4, e_4 = dmp_normal([[1],[-1, 0]], 1, ZZ), 1, ZZ(-17)

    T = [t_1, t_2, t_3, t_4]
    K = [k_1, k_2, k_3, k_4]
    E = [e_1, e_2, e_3, e_4]

    T = zip(T, K)

    A = [ZZ(-14), ZZ(3)]

    S = dmp_eval_tail(w_1, A, 2, ZZ)
    cs, s = dup_primitive(S, ZZ)

    assert cs == 1 and s == S == \
        dup_normal([1036728, 915552, 55748, 105621, -17304, -26841, -644], ZZ)

    assert dmp_zz_wang_non_divisors(E, cs, 4, ZZ) == [7, 3, 11, 17]
    assert dup_sqf_p(s, ZZ) and dup_degree(s) == dmp_degree(w_1, 2)

    _, H = dup_zz_factor_sqf(s, ZZ)

    h_1 = dup_normal([44,  42,   1], ZZ)
    h_2 = dup_normal([126, -9,  28], ZZ)
    h_3 = dup_normal([187,  0, -23], ZZ)

    assert H == [h_1, h_2, h_3]

    lc_1 = dmp_normal([[-4], [-4,0]], 1, ZZ)
    lc_2 = dmp_normal([[-1,0,0], []], 1, ZZ)
    lc_3 = dmp_normal([[1], [], [-1,0,0]], 1, ZZ)

    LC = [lc_1, lc_2, lc_3]

    assert dmp_zz_wang_lead_coeffs(w_1, T, cs, E, H, A, 2, ZZ) == (w_1, H, LC)

    H_1 = [ dmp_normal(t, 0, ZZ) for t in [[44L,42L,1L],[126L,-9L,28L],[187L,0L,-23L]] ]
    H_2 = [ dmp_normal(t, 1, ZZ) for t in [[[-4,-12],[-3,0],[1]],[[-9,0],[-9],[-2,0]],[[1,0,-9],[],[1,-9]]] ]
    H_3 = [ dmp_normal(t, 1, ZZ) for t in [[[-4,-12],[-3,0],[1]],[[-9,0],[-9],[-2,0]],[[1,0,-9],[],[1,-9]]] ]

    c_1 = dmp_normal([-70686,-5863,-17826,2009,5031,74], 0, ZZ)
    c_2 = dmp_normal([[9,12,-45,-108,-324],[18,-216,-810,0],[2,9,-252,-288,-945],[-30,-414,0],[2,-54,-3,81],[12,0]], 1, ZZ)
    c_3 = dmp_normal([[-36,-108,0],[-27,-36,-108],[-8,-42,0],[-6,0,9],[2,0]], 1, ZZ)

    T_1 = [ dmp_normal(t, 0, ZZ) for t in [[-3,0],[-2],[1]] ]
    T_2 = [ dmp_normal(t, 1, ZZ) for t in [[[-1,0],[]],[[-3],[]],[[-6]]] ]
    T_3 = [ dmp_normal(t, 1, ZZ) for t in [[[]],[[]],[[-1]]] ]

    assert dmp_zz_diophantine(H_1, c_1,        [], 5, p, 0, ZZ) == T_1
    assert dmp_zz_diophantine(H_2, c_2, [ZZ(-14)], 5, p, 1, ZZ) == T_2
    assert dmp_zz_diophantine(H_3, c_3, [ZZ(-14)], 5, p, 1, ZZ) == T_3

    factors = dmp_zz_wang_hensel_lifting(w_1, H, LC, A, p, 2, ZZ)

    assert dmp_expand(factors, 2, ZZ) == w_1