Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from fractions import Fraction as f
- import numpy as np, numpy.linalg as lg
- import sympy as s
- from sympy import pprint
- class GramGauss:
- def __init__(self, n, m, a):
- self._n = n
- self.m = m
- self.a = np.array(a)
- @property
- def n(self):
- return len(self.a)
- def ladder(self):
- # Приводим к ступенчатому виду
- # Ведущая строка k, Ведущий элемент q
- for k in range(self.n):
- q = k
- if k < self.n and q < self.m and not self.a[k][q] or not any(self.a[k]):
- self.a = np.append(self.a, [self.a[k]], axis=0)
- self.a = np.delete(self.a, k, axis=0)
- for i in range(1+k, self.n):
- # Проверка ведущего элемента на 0
- while q < self.m-1 and not self.a[k][q]:
- if self.a[k][q]:
- break
- q += 1
- # Если строка состоит из нулей или элемент равен нулю - продолжаем
- if q == self.m or not self.a[k][q]:
- continue
- x = -self.a[i][q]/self.a[k][q]
- for j in range(self.m):
- self.a[i][j] = self.a[k][j]*x + self.a[i][j]
- # Проверка нулевых строк
- for k in range(self.n):
- if not any(self.a[k]):
- self.a = np.append(self.a, [self.a[k]], axis=0)
- self.a = np.delete(self.a, k, axis=0)
- return self.a
- def find_free_variables(self):
- # Находим свободные переменные
- ans = set()
- for i in range(self.n):
- for j in range(self.m):
- if self.a[i][j] != 0:
- ans.add(j)
- break
- return set(range(self.m)).difference(ans)
- def identity_matrix(self):
- # Преобразуем матрицу до черты в единичную
- # Делим строки на ведущие элементы
- for i in range(self.n):
- self.a[i] /= self.a[i][i]
- for i in range(self.n-1, -1, -1):
- for j in range(i-1, -1, -1):
- self.a[j] += -self.a[j][i]*self.a[i]
- return self.a
- def general_solution(self):
- # Общее решение СЛАУ
- k = len(self.general)
- ans = self.m*[0]
- for i, x in enumerate(self.free):
- ans[x] = s.Symbol(f'x{x+1}')
- for ind, x in enumerate(self.general):
- res = []
- for i, elem in enumerate(self.a[ind][k:]):
- if elem != 0:
- res.append(s.Symbol(f'x{self.free[i]+1}')*elem)
- ans[x] = sum(res)
- return np.array([ans]).T
- def fundamental_solution(self):
- # ФСР СЛАУ
- k = len(self.general)
- ans = np.array([self.m*[f(0.)] for x in range(len(self.free))])
- for ind, x in enumerate(self.general):
- for i, elem in enumerate(self.a[ind][k:]):
- if elem != 0:
- ans[i][x] = elem
- for i, x in enumerate(self.free):
- ans[i][x] = 1
- return ans
- def format_mat(self, x):
- # Форматируем вывод матрицы
- return np.array([[f'{i}' for i in x] for x in x])
- def matrix_rank(self):
- # Если матрица в ступенчатом виде
- return len([1 for i in self.a if any(i)])
- def gram(self):
- # Процесс ортогонализации Грама-Шмидта
- b = np.array([[f(0)]*self.m for x in range(self.n)])
- b[0] = self.a[0]
- for i in range(1, self.n):
- b[i] = self.a[i] + sum([(-np.dot(self.a[i], b[j])/np.dot(b[j], b[j]))*b[j] for j in range(i)])
- return b
- def solve(self):
- self.a = self.ladder()
- print()
- print(self.format_mat(self.a))
- print()
- self.rank = self.matrix_rank()
- self.free = list(self.find_free_variables())
- self.a = self.a[:self.rank]
- self.general = list(set(range(self.m)).difference(set(self.free)))
- count_free = len(self.free)
- new_a = [[] for x in range(len(self.a))]
- for i in sorted(self.free, reverse=True):
- new_a = np.append(new_a, -1*self.a[:, i:i+1], axis=1)
- self.a = np.delete(self.a, i, axis=1)
- self.a = np.append(self.a, new_a[:, ::-1], axis=1)
- self.a = self.identity_matrix()
- print(self.format_mat(self.a))
- print()
- print("Общее решение матрицы:")
- print(self.general_solution())
- print()
- self.a = self.fundamental_solution()
- print("ФСР СЛАУ:")
- print(self.format_mat(self.a.T))
- print()
- print("Ортогональный базис пространства решений:")
- print(self.format_mat(self.gram().T))
- print()
- a_copy = [s.Matrix(x) for x in self.a]
- pprint(s.matrices.GramSchmidt(a_copy))
- def silent_solve(self):
- self.a = self.ladder()
- self.rank = self.matrix_rank()
- self.free = list(self.find_free_variables())
- self.a = self.a[:self.rank]
- self.general = list(set(range(self.m)).difference(set(self.free)))
- count_free = len(self.free)
- new_a = [[] for x in range(len(self.a))]
- for i in sorted(self.free, reverse=True):
- new_a = np.append(new_a, -1*self.a[:, i:i+1], axis=1)
- self.a = np.delete(self.a, i, axis=1)
- self.a = np.append(self.a, new_a[:, ::-1], axis=1)
- self.a = self.identity_matrix()
- self.a = self.fundamental_solution()
- return self.a
- #return self.gram()
- def main():
- n = int(input('Введите кол-во уравнений: '))
- a = np.array([[f(x) for x in input().split()] for i in range(n)])
- m = len(a[0])
- g = GramGauss(n, m, a)
- g.solve()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment