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)
def gaussian(les: LinearEquationSystem): a, b = copy.deepcopy(les.a), copy.deepcopy(les.b) n, m, p = les.n, les.m, les.p for col in range(m): row_replaced = find_nonzero(a, col) if row_replaced == -1: continue if row_replaced != col: a[col], a[row_replaced] = a[row_replaced], a[col] b[col], b[row_replaced] = b[row_replaced], b[col] for row in range(col + 1, n): if a[row][col] != 0: scalar = get_inverse(a[row][col], p) * a[col][col] % p a[row] = V.mul_scalar(a[row], scalar, p) a[row] = V.minus(a[row], a[col], p) brow = b[row][0] b[row] = [(brow * scalar - b[col][0]) % p] assert a[row][col] == 0 func = all_solutions(a[-1][n - 1:], b[-1][0], p) def solution(t): x = [0] * m x[n - 1:] = func(t) for row in range(n - 1, -1, -1): xcol = b[row][0] for col in range(m - 1, row, -1): xcol = (xcol - a[row][col] * x[col]) % p xcol = xcol * get_inverse(a[row][row], p) % p x[row] = xcol return x return solution, m - n