Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from fractions import Fraction
- import sympy, numpy as np
- def matrix_rang(A):
- return len([1 for i in A if any(i)])
- def edin_matrix(n, m, A):
- for i in range(n):
- A[i] /= A[i][i]
- for i in range(n-1, -1, -1):
- for j in range(i-1, -1, -1):
- A[j] += -A[j][i]*A[i]
- return A
- def svobodnie_znach(n, m, A):
- res = set()
- for i in range(n):
- for j in range(m):
- if A[i][j] != 0:
- res.add(j)
- break
- return set(range(m)).difference(res)
- def stupen_matrix(n, m, A):
- for x in range(n):
- y = x
- if x < n and y < m and not A[x][y] or not any(A[x]):
- A = np.append(A, [A[x]], axis=0)
- A = np.delete(A, x, axis=0)
- for i in range(1+x, n):
- while y < m-1 and not A[x][y]:
- if A[x][y]:
- break
- y += 1
- if y == m or not A[x][y]:
- continue
- K = -A[i][y]/A[x][y]
- for j in range(m):
- A[i][j] = A[x][j]*K + A[i][j]
- for x in range(n):
- if not any(A[x]):
- A = np.append(A, [A[x]], axis=0)
- A = np.delete(A, x, axis=0)
- return A
- def fsr(n, m, A, basisnie, svobodnie):
- k = len(basisnie)
- ans = np.array([m*[Fraction(0.)] for x in range(len(svobodnie))])
- for ind, x in enumerate(basisnie):
- for i, elem in enumerate(A[ind][k:]):
- if elem != 0:
- ans[i][x] = elem
- for i, x in enumerate(svobodnie):
- ans[i][x] = 1
- return ans
- def reshit_slau(n, m, A):
- A = stupen_matrix(n, m, A)
- A = A[:matrix_rang(A)]
- n = len(A)
- svobodnie = list(svobodnie_znach(n, m, A))
- basisnie = list(set(range(m)).difference(set(svobodnie)))
- a = [[] for x in range(len(A))]
- for i in sorted(svobodnie, reverse=True):
- a = np.append(a, -1*A[:, i:i+1], axis=1)
- A = np.delete(A, i, axis=1)
- A = np.append(A, a[:, ::-1], axis=1)
- return fsr(n, m, edin_matrix(n, m, A), basisnie, svobodnie)
- def main():
- var = sympy.Symbol('x')
- n = int(input())
- A = sympy.Matrix([[Fraction(x) for x in input().split()] for i in range(n)])
- B = sympy.matrices.eye(n, n)*var
- print('\nСоставляем характеристическое уравнение:')
- sympy.pprint(A-B)
- print()
- eq = sympy.Eq(sympy.det(A-B), 0)
- print('det(A − x*E)=')
- sympy.pprint(eq)
- print()
- roots = sympy.roots(eq, var)
- print('Собственные значения и их кратности:')
- print(roots, '\n')
- print('Матрица линейного оператора A в базисе, состоящем из собственных векторов:')
- sympy.pprint(sympy.matrices.diag(*[x for x, i in sorted(roots.items()) for y in range(i)]))
- print()
- result = sympy.Matrix([])
- for step, root in enumerate(sorted(roots.keys()), start=1):
- # Находим собственные вектора
- a = reshit_slau(n, n, np.array(A - sympy.matrices.eye(n, n)*root))
- # Ортонормируем собственные вектора
- a = sympy.matrices.GramSchmidt(reversed([sympy.Matrix(i) for i in a]))
- a = [sympy.Matrix(i)/sympy.Matrix(i).norm() for i in a]
- for i in a:
- result = result.col_insert(step, sympy.Matrix(i))
- print('Ортнормированный базис')
- sympy.pprint(result)
- # print('\nПроверка')
- # print('S^-1 * A * S = A(s)')
- # sympy.pprint([result.T, '*', A, '*', result, '=', result.T*A*result])
- if __name__ == '__main__':
- main()
Add Comment
Please, Sign In to add comment