mirosh111000

Метод поворотів

Jun 10th, 2023
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.95 KB | None | 0 0
  1. import numpy as np
  2. import pandas as pd
  3.  
  4. def check(A):
  5.  
  6.     print('Перевірка на умови для застосування методу поворотів:\n')
  7.     if len(A[0]) != len(A):
  8.         print(f'Матриця "A" не є квадратною, метод не можна застосовувати.')
  9.         return False
  10.     else:
  11.         print('Матриця "A" - квадратна.')
  12.  
  13.     if np.linalg.det(A) == 0:
  14.         print(f'Матриця є виродженою. Метод поворотів може бути застосований тільки до невироджених матриць.')
  15.         return False
  16.     print(f'Матриця є виродженою(визначник != 0, det(A) = {round(np.linalg.det(A), 1)}). Умови для застосування методу виконані.\n')
  17.  
  18.     return True
  19.  
  20. def check_0_diag(A, B):
  21.  
  22.     A_copy = np.copy(A)
  23.     B_copy = np.copy(B)
  24.     check = 0
  25.     i = 0
  26.     while check != len(A):
  27.  
  28.         if A[i][i] != 0:
  29.             check += 1
  30.  
  31.         if A[i][i] == 0 and i+1 != len(A):
  32.             check = 0
  33.             A[i] = A_copy[i+1]
  34.             A[i+1] = A_copy[i]
  35.             B[i] = B_copy[i + 1]
  36.             B[i + 1] = B_copy[i]
  37.             i = -1
  38.  
  39.         elif A[i][i] == 0 and i+1 == len(A):
  40.             check = 0
  41.             A[-1] = A_copy[0]
  42.             A[0] = A_copy[-1]
  43.             B[-1] = B_copy[0]
  44.             B[0] = B_copy[-1]
  45.             i = -1
  46.  
  47.         i += 1
  48.         A_copy = np.copy(A)
  49.         B_copy = np.copy(B)
  50.  
  51.     print('Було здійснено перевірку на наявність "0" серед діагональних елементів,\nякщо "0" був знайдений то рядки були змінені так,\nщоб серед діагональних елементів не було "0".\n')
  52.  
  53.     return A
  54.  
  55. def table(A, X, B, exactness=4):
  56.  
  57.     A_df = np.zeros_like(A)
  58.     B_df = np.zeros_like(B)
  59.     X_df = np.zeros_like(X)
  60.     A_df[:][:] = np.round(A[:][:], exactness)
  61.     B_df[:][:] = np.round(B[:][:], exactness)
  62.     if X[0] != 'x_1':
  63.         X_df[:][:] = np.round(X[:][:], exactness)
  64.  
  65.     df = pd.DataFrame(data=A_df)
  66.     df['*'] = ['' for i in range(len(A))]
  67.     df['X'] = X_df
  68.     df['='] = ['' for i in range(len(A))]
  69.     df['B'] = B_df
  70.     col = []
  71.     for i in range(len(A[0])):
  72.         col.append(('A', ''))
  73.     col.append(('*', ''))
  74.     col.append(('X', ''))
  75.     col.append(('=', ''))
  76.     col.append(('B', ''))
  77.     df.columns = pd.MultiIndex.from_tuples(col)
  78.     df.index = [i for i in range(1, len(A) + 1)]
  79.  
  80.     return df
  81.  
  82. def rotation_method(A, B):
  83.  
  84.     # print(f'A\n{A}\n')
  85.     # print(f'B\n{B}\n')
  86.  
  87.     # cycle
  88.  
  89.     for i in range(0, len(A)-1):
  90.         for k in range(i+1, len(A)):
  91.  
  92.             sqrt = np.sqrt(A[i][i] ** 2 + A[k][i] ** 2)
  93.             c0 = A[i][i] / sqrt
  94.             s0 = A[k][i] / sqrt
  95.  
  96.             # print(f'c1 = {c0}  | s1 = {s0}')
  97.             # print(f'c1^2 + s1^2 = {c0 ** 2 + s0 ** 2}')
  98.  
  99.             A_temp = np.copy(A)
  100.             B_temp = np.copy(B)
  101.  
  102.             # row1
  103.             A[i][i:] = c0 * A_temp[i][i:] + s0 * A_temp[k][i:]
  104.             B[i] = c0 * B_temp[i] + s0 * B_temp[k]
  105.  
  106.             # row2
  107.             A[k][i:] = - s0 * A_temp[i][i:] + c0 * A_temp[k][i:]
  108.             B[k] = - s0 * B_temp[i] + c0 * B_temp[k]
  109.  
  110.             # print(f'A\n{A}\n')
  111.             # print(f'B\n{B}\n')
  112.  
  113.     X = np.zeros(len(A))
  114.     for i in range(len(A)-1, -1, -1):
  115.  
  116.         X[i] = (B[i] - sum(A[i][:] * X[:])) / A[i][i]
  117.  
  118.     return [X, A, B]
  119.  
  120. def print_X(X):
  121.     for i in range(len(X)):
  122.         print(f'x_{i+1} = {X[i]}')
  123.  
  124. def final_test(A, X, B, exactness=4):
  125.  
  126.     print(f'Перевірка на правильність роботи методу(A * X = B):\n')
  127.  
  128.     test_X = np.matmul(A, X)
  129.     for i in range(len(test_X)):
  130.         print(f'B_{i+1} = {np.round(test_X[i], exactness)}')
  131.     test_X[:] = np.round(test_X[:], exactness)
  132.  
  133.     if np.round(test_X[0], exactness) == np.round(B[0], exactness):
  134.         print('Програма працює коректно.\n')
  135.     else:
  136.         print('Програма працює не коректно.\n')
  137.  
  138.  
  139.  
  140.  
  141.  
  142. A = np.array([
  143.     [-3., 0, 2, 0, -6],
  144.     [-5, -5, -4, 3, 2],
  145.     [-3, -1, 3, -3, 4],
  146.     [2, 0, -5, 0, -3],
  147.     [0, -2, 2, -3, 0]
  148. ])
  149.  
  150. B = np.array([-23., -14, -23, -2, -9])
  151.  
  152. X = np.array([f'x_{i+1}' for i in range(len(B))])
  153.  
  154. test = check(A)
  155.  
  156. if test == True:
  157.  
  158.     table0 = table(A, X, B)
  159.     print(table0, '\n')
  160.  
  161.     A = check_0_diag(A, B)
  162.  
  163.     A_start = np.copy(A)
  164.     B_start = np.copy(B)
  165.  
  166.     table1 = table(A, X, B)
  167.     print(table1,'\n')
  168.  
  169.     X, A_res, B_res = rotation_method(A, B)
  170.  
  171.     print_X(X)
  172.     exact = 4
  173.     table2 = table(A=A_res, X=X, B=B_res, exactness=exact)
  174.     print('\n', table2, '\n')
  175.  
  176.     final_test(A_start, X, B_start, exact)
  177.  
  178.     table3 = table(A=A_start, X=X, B=B_start, exactness=exact)
  179.     print('\n', table3, '\n')
Add Comment
Please, Sign In to add comment