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
144 changes: 144 additions & 0 deletions Р3213/molodichenko_409163/lab1/main1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import numpy as np





def read_matrix_from_file(filename):
"""Считывает матрицу A и вектор b из файла."""
with open(filename, 'r') as file:
while True:
try:
n = int(file.readline())
if n > 20:
print("ValueError: Размерность матрицы должна быть не более 20.")
continue
break
except ValueError:
print("ValueError: Размерность матрицы должна быть не более 20.")
A = [list(map(float, file.readline().split())) for _ in range(n)]
b = list(map(float, file.readline().split()))
return np.array(A), np.array(b)




def read_matrix_from_input():
"""Считывает матрицу A и вектор b с клавиатуры."""
while True:
try:
n = int(input("Введите размерность матрицы (не более 20): "))
if n > 20:
print("ValueError: Размерность матрицы должна быть не более 20.")
continue
break
except ValueError:
print("ValueError: Размерность матрицы должна быть не более 20.")
A = []
print("Введите коэффициенты матрицы A (по строкам, через пробел):")
for _ in range(n):
while True:
try:
row = list(map(float, input().split()))
if len(row) != n:
raise ValueError(f"Ожидалось {n} чисел, введено {len(row)}.")
A.append(row)
break
except ValueError as e:
print("Ошибка ввода! Повторите ввод строки:", e)
print("Введите коэффициенты вектора b (через пробел):")
while True:
try:
b = list(map(float, input().split()))
if len(b) != n:
raise ValueError(f"Ожидалось {n} чисел, введено {len(b)}.")
break
except ValueError as e:
print("Ошибка ввода! Повторите ввод:", e)
return np.array(A), np.array(b)


def check_diagonal_dominance(A):
"""Проверяет, обладает ли матрица диагональным преобладанием."""
n = A.shape[0]
for i in range(n):
sum_row = sum(abs(A[i, j]) for j in range(n) if i != j)
if abs(A[i, i]) < sum_row:
return False
return True




def enforce_diagonal_dominance(A, b):
"""Пытается добиться диагонального преобладания путем перестановки строк."""
n = A.shape[0]
indices = np.argsort(-np.abs(A.diagonal()))
A, b = A[indices], b[indices]
if not check_diagonal_dominance(A):
print("Невозможно достичь диагонального преобладания.")
return None, None
return A, b




def compute_determinant(A):
"""Вычисляет определитель матрицы A."""
return np.linalg.det(A)


def gauss_seidel(A, b, tol=1e-6, max_iterations=1000):
"""Решает систему методом Гаусса-Зейделя."""
n = len(A)
x = np.zeros(n)
for iteration in range(max_iterations):
x_new = np.copy(x)
for i in range(n):
sum1 = sum(A[i][j] * x_new[j] for j in range(i))
sum2 = sum(A[i][j] * x[j] for j in range(i + 1, n))
x_new[i] = (b[i] - sum1 - sum2) / A[i][i]
error = np.linalg.norm(x_new - x, ord=np.inf)
if error < tol:
return x_new, iteration + 1
x = x_new
print("Метод не сошелся за", max_iterations, "итераций.")
return x, max_iterations


def main():
choice = input("Вы хотите ввести данные с клавиатуры (k) или из файла (f)? ")
if choice.lower() == 'f':
filename = input("Введите имя файла: ")
A, b = read_matrix_from_file(filename)
else:
A, b = read_matrix_from_input()

print("Определитель матрицы:", compute_determinant(A))

if not check_diagonal_dominance(A):
print("Матрица не обладает диагональным преобладанием. Пытаемся переставить строки...")
A, b = enforce_diagonal_dominance(A, b)
if A is None:
return

print("Решаем методом Гаусса-Зейделя...")
solution, iterations = gauss_seidel(A, b)
print("Вектор неизвестных:", solution)
print("Количество итераций:", iterations)

# Вычисление невязки
residual = b - np.dot(A, solution)
print("Вектор невязок:", residual)

# Вычисление нормы погрешности
print("Норма погрешности:", np.linalg.norm(residual))

# Проверка с решением с помощью numpy.linalg.solve
lib_solution = np.linalg.solve(A, b)
print("Решение с использованием библиотеки:", lib_solution)
print("Разница между решениями:", np.linalg.norm(solution - lib_solution))


if __name__ == "__main__":
main()
Binary file not shown.
173 changes: 173 additions & 0 deletions Р3213/molodichenko_409163/lab2/lab2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import numpy as np
import matplotlib.pyplot as plt
from sympy import symbols, diff, sin, cos, lambdify


def get_input(prompt, type_func=float, from_file=None):
if from_file:
value = from_file.readline().strip()
print(f"{prompt} {value}")
return type_func(value)
while True:
try:
return type_func(input(prompt))
except ValueError:
print("Некорректный ввод. Попробуйте снова.")


def plot_function(f, a, b, root):
x_vals = np.linspace(a, b, 400)
y_vals = [f(x) for x in x_vals]

plt.figure(figsize=(8, 5))
plt.plot(x_vals, y_vals, label="f(x)", color="blue")
plt.axhline(0, color="black", linewidth=1)
plt.axvline(root, color="red", linestyle="--", label="Найденный корень")
plt.grid()
plt.legend()
plt.title("График функции")
plt.xlabel("x")
plt.ylabel("f(x)")
plt.show()


def bisection_method(f, a, b, tol):
if f(a) * f(b) >= 0:
print("Некорректный интервал: f(a) и f(b) должны иметь разные знаки.")
return None, []

iterations = []
while abs(b - a) > tol:
c = (a + b) / 2
iterations.append([a, b, c, f(a), f(b), f(c), abs(b - a)])

if f(c) == 0:
break
elif f(a) * f(c) < 0:
b = c
else:
a = c

return c, iterations


def secant_method(f, x0, x1, tol):
iterations = []
while abs(x1 - x0) > tol:
if f(x1) - f(x0) == 0:
print("Ошибка: Деление на ноль в методе секущих.")
return None, []
x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0))
iterations.append([x0, x1, f(x0), f(x1), abs(x1 - x0)])
x0, x1 = x1, x2
return x1, iterations


def newton_method(f, df, x0, tol):
iterations = []
while True:
if df(x0) == 0:
print("Ошибка: Производная равна нулю, метод Ньютона не применим.")
return None, []
x1 = x0 - f(x0) / df(x0)
iterations.append([x0, f(x0), df(x0), x1, abs(x1 - x0)])
if abs(x1 - x0) < tol:
break
x0 = x1
return x1, iterations


def simple_iteration_method(g, x0, tol):
iterations = []
while True:
x1 = g(x0)
iterations.append([x0, x1, abs(x1 - x0)])
if abs(x1 - x0) < tol:
break
x0 = x1
return x1, iterations


def solve_nonlinear_equation():
x = symbols('x')
functions = {
1: sin(x) - x / 2,
2: x ** 3 - 4 * x + 1,
3: x ** 2 - 2,
}

from_file = None
if input("Ввести данные из файла? (y/n): ").strip().lower() == 'y':
filename = input("Введите имя файла: ").strip()
from_file = open(filename, "r")

print("Выберите уравнение:")
for k, v in functions.items():
print(f"{k}: {v}")
choice = get_input("Введите номер уравнения: ", int, from_file)
if choice not in functions:
print("Некорректный выбор уравнения.")
return

f_sym = functions[choice]
f = lambdify(x, f_sym, 'numpy')
df = lambdify(x, diff(f_sym, x), 'numpy')

method = input("Выберите метод (bisection, secant, newton, iteration): ").strip().lower()
if method not in ["bisection", "secant", "newton", "iteration"]:
print("Некорректный метод.")
return

tol = get_input("Введите точность: ", float, from_file)

if method == "bisection":
a = get_input("Введите левую границу: ", float, from_file)
b = get_input("Введите правую границу: ", float, from_file)
root, iterations = bisection_method(f, a, b, tol)
else:
x0 = get_input("Введите начальное приближение: ", float, from_file)
if method == "secant":
x1 = get_input("Введите x1: ", float, from_file)
root, iterations = secant_method(f, x0, x1, tol)
elif method == "newton":
root, iterations = newton_method(f, df, x0, tol)
elif method == "iteration":
g = lambdify(x, x - f_sym, 'numpy')
root, iterations = simple_iteration_method(g, x0, tol)
a, b = root - 2, root + 2

if from_file:
from_file.close()

if root is None:
print("Ошибка вычислений. Попробуйте снова с другим интервалом или методом.")
return

function_value = f(root)
result = f"Найденный корень: {root}\nЗначение функции в корне: {function_value}\nЧисло итераций: {len(iterations)}\n"
print(result)

save_to_file = input("Сохранить результат в файл? (y/n): ").strip().lower()
if save_to_file == 'y':
with open("result.txt", "w") as file:
file.write(result)
print("Результат сохранен в result.txt")

plot_function(f, a, b, root)


def main():
while True:
mode = input("Выберите режим (equation/system) или 'exit' для выхода: ").strip().lower()
if mode == "equation":
solve_nonlinear_equation()
elif mode == "system":
print("Функционал для систем еще не реализован.")
elif mode == "exit":
break
else:
print("Неверный выбор. Попробуйте снова.")


if __name__ == "__main__":
main()
Binary file not shown.
Loading