kxcoze

tanya4

Feb 24th, 2022 (edited)
1,115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.82 KB | None | 0 0
  1. import sympy as sym
  2. import numpy as np
  3.  
  4. from fractions import Fraction
  5.  
  6. def rank(a):
  7.     return len([1 for i in a if any(i)])
  8.  
  9. def gauss_method(a):
  10.     n, m = len(a), len(a[0])
  11.     for k in range(n):
  12.         t = k
  13.         if k < n and t < m and not a[k][t] or not any(a[k]):
  14.             a = np.append(a, [a[k]], axis=0)
  15.             a = np.delete(a, k, axis=0)
  16.         for i in range(1+k, n):
  17.             while t < m-1 and not a[k][t]:
  18.                 if a[k][t]:
  19.                     break
  20.                 t += 1
  21.             if t == m or not a[k][t]:
  22.                 continue
  23.  
  24.             K = -a[i][t]/a[k][t]
  25.             for j in range(m):
  26.                 a[i][j] = a[k][j]*K + a[i][j]
  27.  
  28.     for x in range(n):
  29.         if not any(a[x]):
  30.             a = np.append(a, [a[x]], axis=0)
  31.             a = np.delete(a, x, axis=0)
  32.     return a
  33.  
  34. def find_free(a):
  35.     n, m = len(a), len(a[0])
  36.     res = set()
  37.     for i in range(n):
  38.         for j in range(m):
  39.             if a[i][j] != 0:
  40.                 res.add(j)
  41.                 break
  42.     return set(range(m)).difference(res)
  43.  
  44. def identity_matrix(a):
  45.     n, m = len(a), len(a[0])
  46.     for i in range(n):
  47.         a[i] /= a[i][i]
  48.  
  49.     for i in range(n-1, -1, -1):
  50.         for j in range(i-1, -1, -1):
  51.             a[j] += -a[j][i]*a[i]
  52.  
  53.     return a
  54.  
  55. def fundamental_solve(a, general_variables, free_variables):
  56.     n, m, k = len(a), len(a[0]), len(general_variables)
  57.     ans = np.array([m*[Fraction(0.)] for x in range(len(free_variables))])
  58.     for ind, x in enumerate(general_variables):
  59.         for i, elem in enumerate(a[ind][k:]):
  60.             if elem != 0:
  61.                 ans[i][x] = elem
  62.     for i, x in enumerate(free_variables):
  63.         ans[i][x] = 1
  64.     return ans
  65.  
  66. def solve_slau(a):
  67.     n, m = len(a), len(a[0])
  68.     a = gauss_method(a)
  69.     a = a[:rank(a)]
  70.     free_variables = list(find_free(a))
  71.     general_variables = list(set(range(m)).difference(set(free_variables)))
  72.     temp = [[] for i in range(len(a))]
  73.     for i in sorted(free_variables, reverse=True):
  74.         temp = np.append(temp, -1*a[:, i:i+1], axis=1)
  75.         a = np.delete(a, i, axis=1)
  76.     a = np.append(a, temp[:, ::-1], axis=1)
  77.     return fundamental_solve(identity_matrix(a), general_variables, free_variables)
  78.  
  79. def gram(a):
  80.     n, m = len(a), len(a[0])
  81.     b = np.array([[Fraction(0)]*m for x in range(n)])
  82.     b[0] = a[0]
  83.     for i in range(1, n):
  84.         b[i] = a[i] + sum([(-np.dot(a[i], b[j])/np.dot(b[j], b[j]))*b[j] for j in range(i)])
  85.     return b
  86.  
  87. def main():
  88.     print("Введите размерность: ")
  89.     n = int(input())
  90.     print("Введите элементы матрицы: ")
  91.     a = sym.Matrix([[Fraction(x) for x in input().split()] for i in range(n)])
  92.     b = sym.matrices.eye(n, n)*sym.Symbol('λ')
  93.     print('\nСоставляем характеристическое уравнение:')
  94.     sym.pprint(a-b)
  95.     print()
  96.     equation = sym.Eq(sym.det(a-b), 0)
  97.     roots = sym.roots(equation, sym.Symbol('λ'))
  98.     print('Матрица линейного оператора a в базисе, состоящем из собственных векторов:')
  99.     sym.pprint(sym.matrices.diag(*[x for x, i in sorted(roots.items()) for t in range(i)]))
  100.     print()
  101.  
  102.     answer = sym.Matrix([])
  103.     for step, root in enumerate(sorted(roots.keys()), start=1):
  104.         # Находим собственные вектора
  105.         temp = solve_slau(np.array(a - sym.matrices.eye(n, n)*root))
  106.         # Ортонормируем собственные вектора
  107.         temp = [sym.Matrix(i)/sym.Matrix(i).norm() for i in gram(temp[::-1])]
  108.         for i in temp:
  109.             answer = answer.col_insert(step, sym.Matrix(i))
  110.  
  111.     print('Ортнормированный базис')
  112.     sym.pprint(answer)
  113.  
  114. if __name__ == '__main__':
  115.     main()
  116.  
Advertisement
Add Comment
Please, Sign In to add comment