Beispiel #1
0
def all_solutions(a: list, d, p):
    if not any(a):
        raise ValueError('Найдена линейно-независимая строка')
    n = len(a)
    a_mat = [a[:]] + M.unit(n, n)
    while len(list(filter(lambda el: el != 0, a_mat[0]))) > 1:
        ai = min(filter(lambda el: el != 0, a_mat[0]))
        i = a_mat[0].index(ai)
        j = next(filter(lambda jj: i != jj and a_mat[0][jj] != 0, range(n)))
        q, r, = divmod(a_mat[0][j], a_mat[0][i])
        for row in range(n + 1):
            a_mat[row][j] = (a_mat[row][j] - a_mat[row][i] * q) % p
    lam = max(a_mat[0])
    s = a_mat[0].index(lam)
    dlam = ratio(d, lam, p)
    c = a_mat[1:]

    def solution(t):
        t.insert(s, dlam)
        # t[s:s] = dlam
        x = V.zero(n)
        for sol_i in range(n):
                x = V.add(x, V.mul_scalar(M.column(c, sol_i), t[sol_i], p), p)
        return x
    return solution
Beispiel #2
0
def wiedemann2(les: LinearEquationSystem):
    a, b, p, n = les.a, M.t(les.b)[0], les.p, les.n
    a_powers = [M.unit(n, n)]
    for i in range(1, 2 * n):
        a_powers.append(M.mul(a_powers[-1], a, p))
    aib = [M.mul_vec(ai, b, p) for ai in a_powers]
    k = 0
    gs = [[1]]
    uk1 = [0, 1] + ([0] * (n - 2))
    while Poly.deg(gs[k]) < n and k < n:
        seq = []
        for i in range(2 * n - Poly.deg(gs[k])):
            gab = M.mul_vec(fa(gs[k], a, p), aib[i], p)
            ugab = V.mul_sum(uk1, gab, p)
            seq.append(ugab)

        assert len(seq)
        f = berlekamp(seq, p)
        gs.append(Poly.mul(f, gs[k], p))
        k += 1
        uk1 = ([0] * k) + [1] + ([0] * (n - k - 1))

    print('k =', k)
    g = gs[-1]
    x = V.zero(n)
    for i in range(Poly.deg(g)):
        x = V.add(x, V.mul_scalar(aib[i], -g[i], p), p)
    return x