Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 187 additions & 0 deletions Р3212/dmitriev_408542/lab1/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import numpy as np


def gauss_with_pivoting(A, b):
n = len(b)
# задаём вот здеся матрицу (A|B)
Ab = np.hstack([A, b.reshape(n, 1)])
# инициализируем определитель. Будем его вычислять с помощью знания
# гласящего что при диагональной матрице определитель равен произведению диагоналей на перестановки
det = 1.0

# Для начала прямой ход - подробно описан в отчёте
for k in range(n):
# Здесь выбор главного элемента по столбцу(для сути нашего метода)
max_row = np.argmax(np.abs(Ab[k:, k])) + k
if Ab[max_row, k] == 0:
raise ValueError("Матрица вырождена, система не имеет единственного решения или решений нет.")

# Здесь меняем строки местами
if max_row != k:
Ab[[k, max_row]] = Ab[[max_row, k]]
det *= -1

# Зануляем элементы ниже главного элемента для приведения к диагональному виду
for i in range(k + 1, n):
factor = Ab[i, k] / Ab[k, k]
Ab[i, k:] -= factor * Ab[k, k:]

# про то что говорили ранее: получаем определитель путём умножения диагональных элементов
det *= Ab[k, k]

# Обратный ход - нахождение самого решения.
x = np.zeros(n)
for i in range(n - 1, -1, -1):
x[i] = (Ab[i, -1] - np.dot(Ab[i, i + 1:n], x[i + 1:])) / Ab[i, i]

return x, Ab, det


def input_manual(n):
print(f"Введите матрицу A ({n}x{n}):")
A = []
for i in range(n):
while True:
row_input = input(f"Строка {i + 1}: ")
try:
row = list(map(float, row_input.split()))
if len(row) != n:
print(f"В строке должно быть ровно {n} чисел, го снова.")
continue
A.append(row)
break
except ValueError:
print("Введите числа которые разделены пробелами, го снова.")
A = np.array(A)

print("Введите вектор b:")
while True:
b_input = input()
try:
b = list(map(float, b_input.split()))
if len(b) != n:
print(f"В векторе должно быть ровно {n} чисел, не забудьте попробовать снова ;)")
continue
break
except ValueError:
print("Введите числа, разделённые пробелами. Попробуйте снова.")
b = np.array(b)

return A, b


def input_file(filename):
try:
with open(filename, 'r') as file:
lines = file.readlines()
if not lines:
raise ValueError("Файл пуст.")

n = len(lines) - 1
A = []
for line in lines:
try:
row = list(map(float, line.split()))
A.append(row)
except ValueError as e:
raise ValueError(f"Ошибка в данных файла: {e}")
A = np.array(A)
b = A[-1]
A = A[:-1]
except FileNotFoundError:
raise FileNotFoundError("Файл не найден.")
except Exception as e:
raise ValueError(e)

return A, b


def generate_random_matrix(n):
A = np.random.uniform(-10, 10, (n, n))
for i in range(n):
row_sum = np.sum(np.abs(A[i, :])) - np.abs(A[i, i])
A[i, i] = row_sum + np.random.uniform(1, 10)
b = np.random.uniform(-10, 10, n)
return A, b




def main():
print("Выберите способ ввода данных:")
print("1. Вручную")
print("2. Из файла")
print("3. Блесс РНГ или рандомная матрица.")
choice = input("Выберите ваш способ ввода данных из двух: ")

try:
if choice == '1':
while True:
try:
n = int(input("Введите размерность системы (n, не более 20): "))
if n <= 0 or n > 20:
print("Размерность должна быть от 1 до 20, постарайтесь в этот раз не ошибиться!")
continue
break
except ValueError:
print("Введите целое число, а также опробуйте снова!")
A, b = input_manual(n)
elif choice == '2':
filename = input("Введите имя файла: ")
A, b = input_file(filename)
elif choice == '3':
while True:
try:
n = int(input("Введите размерность системы (n, не более 20): "))
if n <= 0 or n > 20:
print("Размерность должна быть от 1 до 20, постарайтесь в этот раз не ошибиться!")
continue
break
except ValueError:
print("Введите целое число, а также опробуйте снова!")
A, b = generate_random_matrix(n)
print("\nСгенерированная матрица A:")
print(A)
print("\nСгенерированный вектор b:")
print(b)
else:
print("Неверный выбор.")
return
print(A)

if A.shape[0] != A.shape[1]:
raise ValueError("Матрица A должна быть квадратной.")


x, Ab_triangular, det = gauss_with_pivoting(A, b)

print("\nТреугольная матрица (с преобразованным столбцом B):")
print(Ab_triangular)
print("\nВектор неизвестных x:")
print(x)
print("\nОпределитель матрицы A:")
print(det)

residual = np.dot(A, x) - b
print("\nВектор невязок:")
print(residual)

x_numpy = np.linalg.solve(A, b)
det_numpy = np.linalg.det(A)

print("\nРешение с использованием бииииблиотеки NumPy:")
print(x_numpy)
print("\nОпределитель с использованием биииииблиотеки NumPy:")
print(det_numpy)

print("\nРазница между решениями (метод Гаусса и NumPy):")
print(x - x_numpy)
print("\nРазница между определителями (метод Гаусса и NumPy):")
print(det - det_numpy)

except Exception as e:
print(f"Ошибка: {e}")


if __name__ == "__main__":
main()
Loading