Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import pandas as pd
- def check(A):
- print('Перевірка на умови для застосування методу поворотів:\n')
- if len(A[0]) != len(A):
- print(f'Матриця "A" не є квадратною, метод не можна застосовувати.')
- return False
- else:
- print('Матриця "A" - квадратна.')
- if np.linalg.det(A) == 0:
- print(f'Матриця є виродженою. Метод поворотів може бути застосований тільки до невироджених матриць.')
- return False
- print(f'Матриця є виродженою(визначник != 0, det(A) = {round(np.linalg.det(A), 1)}). Умови для застосування методу виконані.\n')
- return True
- def check_0_diag(A, B):
- A_copy = np.copy(A)
- B_copy = np.copy(B)
- check = 0
- i = 0
- while check != len(A):
- if A[i][i] != 0:
- check += 1
- if A[i][i] == 0 and i+1 != len(A):
- check = 0
- A[i] = A_copy[i+1]
- A[i+1] = A_copy[i]
- B[i] = B_copy[i + 1]
- B[i + 1] = B_copy[i]
- i = -1
- elif A[i][i] == 0 and i+1 == len(A):
- check = 0
- A[-1] = A_copy[0]
- A[0] = A_copy[-1]
- B[-1] = B_copy[0]
- B[0] = B_copy[-1]
- i = -1
- i += 1
- A_copy = np.copy(A)
- B_copy = np.copy(B)
- print('Було здійснено перевірку на наявність "0" серед діагональних елементів,\nякщо "0" був знайдений то рядки були змінені так,\nщоб серед діагональних елементів не було "0".\n')
- return A
- def table(A, X, B, exactness=4):
- A_df = np.zeros_like(A)
- B_df = np.zeros_like(B)
- X_df = np.zeros_like(X)
- A_df[:][:] = np.round(A[:][:], exactness)
- B_df[:][:] = np.round(B[:][:], exactness)
- if X[0] != 'x_1':
- X_df[:][:] = np.round(X[:][:], exactness)
- df = pd.DataFrame(data=A_df)
- df['*'] = ['' for i in range(len(A))]
- df['X'] = X_df
- df['='] = ['' for i in range(len(A))]
- df['B'] = B_df
- col = []
- for i in range(len(A[0])):
- col.append(('A', ''))
- col.append(('*', ''))
- col.append(('X', ''))
- col.append(('=', ''))
- col.append(('B', ''))
- df.columns = pd.MultiIndex.from_tuples(col)
- df.index = [i for i in range(1, len(A) + 1)]
- return df
- def rotation_method(A, B):
- # print(f'A\n{A}\n')
- # print(f'B\n{B}\n')
- # cycle
- for i in range(0, len(A)-1):
- for k in range(i+1, len(A)):
- sqrt = np.sqrt(A[i][i] ** 2 + A[k][i] ** 2)
- c0 = A[i][i] / sqrt
- s0 = A[k][i] / sqrt
- # print(f'c1 = {c0} | s1 = {s0}')
- # print(f'c1^2 + s1^2 = {c0 ** 2 + s0 ** 2}')
- A_temp = np.copy(A)
- B_temp = np.copy(B)
- # row1
- A[i][i:] = c0 * A_temp[i][i:] + s0 * A_temp[k][i:]
- B[i] = c0 * B_temp[i] + s0 * B_temp[k]
- # row2
- A[k][i:] = - s0 * A_temp[i][i:] + c0 * A_temp[k][i:]
- B[k] = - s0 * B_temp[i] + c0 * B_temp[k]
- # print(f'A\n{A}\n')
- # print(f'B\n{B}\n')
- X = np.zeros(len(A))
- for i in range(len(A)-1, -1, -1):
- X[i] = (B[i] - sum(A[i][:] * X[:])) / A[i][i]
- return [X, A, B]
- def print_X(X):
- for i in range(len(X)):
- print(f'x_{i+1} = {X[i]}')
- def final_test(A, X, B, exactness=4):
- print(f'Перевірка на правильність роботи методу(A * X = B):\n')
- test_X = np.matmul(A, X)
- for i in range(len(test_X)):
- print(f'B_{i+1} = {np.round(test_X[i], exactness)}')
- test_X[:] = np.round(test_X[:], exactness)
- if np.round(test_X[0], exactness) == np.round(B[0], exactness):
- print('Програма працює коректно.\n')
- else:
- print('Програма працює не коректно.\n')
- A = np.array([
- [-3., 0, 2, 0, -6],
- [-5, -5, -4, 3, 2],
- [-3, -1, 3, -3, 4],
- [2, 0, -5, 0, -3],
- [0, -2, 2, -3, 0]
- ])
- B = np.array([-23., -14, -23, -2, -9])
- X = np.array([f'x_{i+1}' for i in range(len(B))])
- test = check(A)
- if test == True:
- table0 = table(A, X, B)
- print(table0, '\n')
- A = check_0_diag(A, B)
- A_start = np.copy(A)
- B_start = np.copy(B)
- table1 = table(A, X, B)
- print(table1,'\n')
- X, A_res, B_res = rotation_method(A, B)
- print_X(X)
- exact = 4
- table2 = table(A=A_res, X=X, B=B_res, exactness=exact)
- print('\n', table2, '\n')
- final_test(A_start, X, B_start, exact)
- table3 = table(A=A_start, X=X, B=B_start, exactness=exact)
- print('\n', table3, '\n')
Add Comment
Please, Sign In to add comment