Exemplo n.º 1
0
def lanczos(les: LinearEquationSystem):
    assert les.n == les.m
    for row in range(les.n):
        for col in range(row + 1):
            if les.a[row][col] != les.a[col][row]:
                print('Алгоритм Ланцоша : определен только для симмтеричных матриц, '
                      'см. индексы ({0},{1}) и ({1},{0})'.format(row + 1, col + 1))
                return
    p = les.p
    ws = [M.column(les.b, 0)]
    vs = [None, M.mul_vec(les.a, ws[0], p)]
    ws.append(V.minus(vs[1],
                      V.mul_scalar(ws[0],
                                   ratio(V.mul_sum(vs[1], vs[1], p),
                                         V.mul_sum(ws[0], vs[1], p), p), p), p))

    for trial in range(max(MAX_TRIALS, les.n)):
        if V.mul_sum(ws[-1], M.mul_vec(les.a, ws[-1], p), p) == 0:
            if V.is_zero(ws[-1]):
                x = V.zero(les.n)
                for i in range(len(ws) - 1):
                    bi = ratio(V.mul_sum(ws[i], ws[0], p),
                               V.mul_sum(ws[i], vs[i + 1], p), p)
                    x = V.add(x, V.mul_scalar(ws[i], bi, p), p)
                return x

        vs.append(M.mul_vec(les.a, ws[-1], p))
        w1 = V.mul_scalar(ws[-1], ratio(V.mul_sum(vs[-1], vs[-1], p),
                                        V.mul_sum(ws[-1], vs[-1], p), p), p)
        w2 = V.mul_scalar(ws[-2], ratio(V.mul_sum(vs[-1], vs[-2], p),
                                        V.mul_sum(ws[-2], vs[-2], p), p), p)
        w_end = V.minus(V.minus(vs[-1], w1, p),
                        w2, p)
        ws.append(w_end)
Exemplo n.º 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
Exemplo n.º 3
0
def wiedemann1(les: LinearEquationSystem):
    a, b, p, n = les.a, M.t(les.b)[0], les.p, les.n
    for trial in range(MAX_TRIALS):
        bs = [b]
        ys = [[0] * n]
        ds = [0]
        k = 0

        while bs[k] != V.zero(n):
            u = [random.randint(0, p - 1) for _idx in range(n)]
            seq = []
            for i in range(2 * (n - ds[k])):
                ai = M.power(a, i, p)
                aib = M.mul_vec(ai, b, p)
                uaib = V.mul_sum(u, aib, p)
                seq.append(uaib)

            if not len(seq):
                break
            f = berlekamp(seq, p)
            if f is None:
                break

            ys.append(V.add(ys[k], M.mul_vec(f_tilda(f, a, p), b, p), p))
            bs.append(V.add(b, M.mul_vec(a, ys[k + 1], p), p))
            ds.append(ds[k] + len(f))
            k += 1
        if bs[k] != V.zero(n):
            print(trial, end='\r')
            continue
        return V.mul_scalar(ys[k], -1, p)
Exemplo n.º 4
0
def alpha_ij(wi, wj, a, p):
    nom = mul_a(M.mul_vec(a, wi, p), wj, a, p)
    rat = mul_a(wj, wj, a, p)
    return ratio(nom, rat, p)
Exemplo n.º 5
0
def mul_a(x, y, a, p):
    return V.mul_sum(M.mul_vec(a, x, p), y, p)