diff --git "a/\320\2403213/khalikov_409785/.gitignore" "b/\320\2403213/khalikov_409785/.gitignore" new file mode 100644 index 0000000..ba0430d --- /dev/null +++ "b/\320\2403213/khalikov_409785/.gitignore" @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab1/reports/report.docx" "b/\320\2403213/khalikov_409785/lab1/reports/report.docx" new file mode 100644 index 0000000..6ae437d Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab1/reports/report.docx" differ diff --git "a/\320\2403213/khalikov_409785/lab1/reports/report.pdf" "b/\320\2403213/khalikov_409785/lab1/reports/report.pdf" new file mode 100644 index 0000000..8607196 Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab1/reports/report.pdf" differ diff --git "a/\320\2403213/khalikov_409785/lab1/src/exceptions.py" "b/\320\2403213/khalikov_409785/lab1/src/exceptions.py" new file mode 100644 index 0000000..8a4e18e --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab1/src/exceptions.py" @@ -0,0 +1,22 @@ +class TooBigN(Exception): + pass + + +class TooSmallN(Exception): + pass + + +class NMustBeInt(Exception): + pass + + +class NoNInFile(Exception): + pass + + +class TooShortRow(Exception): + pass + + +class IncorrectMatrix(Exception): + pass diff --git "a/\320\2403213/khalikov_409785/lab1/src/main.py" "b/\320\2403213/khalikov_409785/lab1/src/main.py" new file mode 100644 index 0000000..e734520 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab1/src/main.py" @@ -0,0 +1,47 @@ +import numpy as np +import copy +import method +from method import * +from reader import * +from utils import * +import numpy as np + + +def main(): + n = read_n() + + matrix = read_matrix(n) + + b = get_vector_from_matrix(matrix) + + matrix = separate_matrix_from_vector(matrix) + + A = np.array(matrix) + + B = np.array(b) + + matrix_copy = copy.deepcopy(matrix) + b_copy = b.copy() + + answer = gaussian_elimination_modified(matrix, b) + + print("\nОтвет:") + print_vector(answer) + + print( + f"\nОпределитель:\n{calc_determinant_triangle(diagonal(matrix), method.permutations)}") + + print("\nНевязка:") + print_vector(calc_residual(matrix_copy, b_copy, answer)) + + numpy_answer = np.linalg.solve(A, B) + numpy_det = np.linalg.det(A) + + print("\nОтвет, полученный с помощью библиотек:") + print_vector(numpy_answer) + print("\nОпределитель, полученный с помощью библиотек:") + print(numpy_det) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab1/src/method.py" "b/\320\2403213/khalikov_409785/lab1/src/method.py" new file mode 100644 index 0000000..869e7ce --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab1/src/method.py" @@ -0,0 +1,107 @@ +from printer import * +from utils import * +import math + +permutations = 0 + +# метод Гаусса с выбором главного элемента + + +def gaussian_elimination_modified(matrix, b): + last_permutations = permutations + + print("Исходная матрица:") + print_matrix(matrix) + print() + + n = len(matrix) + x = [0]*n + + # прямой ход + for i in range(n-1): + print("\nДо:") + print_matrix(matrix) + print() + + modified_replace(matrix, i, b) + + print(f"Меняем строки местами... (k = {i})") + print_matrix(matrix) + + print("\nНичего не изменилось" if last_permutations == permutations else "") + + last_permutations = permutations + + for k in range(i+1, n): + + c = matrix[k][i] / matrix[i][i] + + matrix[k][i] = 0 + + for j in range(i+1, n): + matrix[k][j] = matrix[k][j] - c*matrix[i][j] + + b[k] = b[k] - c * b[i] + + print("\nИтоговая матрица:") + append_vector_to_matrix(b, matrix) + print_matrix(matrix) + print() + + # обратный ход + + for i in range(n-1, -1, -1): + try: + s = 0 + for j in range(i+1, n): + s += matrix[i][j]*x[j] + x[i] = (b[i] - s) / matrix[i][i] + except ZeroDivisionError: + print("Решени либо нет, либо их бесконечно много") + exit(0) + + return x + +# перестановка строк + + +def modified_replace(matrix, i, b): + global permutations + l = i + n = len(matrix) + for m in range(i+1, n): + if abs(matrix[m][i]) > abs(matrix[l][i]): + l = m + if l == i: + return + else: + matrix[i], matrix[l] = matrix[l], matrix[i] + b[i], b[l] = b[l], b[i] + permutations += 1 + +# невязка Ax* - b = r + + +def calc_residual(matrix, b, x): + + n = len(matrix) + residual = [] + for i in range(n): + r = 0 + for j in range(n): + r += matrix[i][j] * x[j] + r -= b[i] + residual.append(r) + return residual + +# получить главную диагональ + + +def diagonal(matrix): + return [matrix[i][i] for i in range(len(matrix))] + + +# посчитать определитель треугольной матрицы +def calc_determinant_triangle(diagonal, k): + + return (-1)**k * math.prod(diagonal) diff --git "a/\320\2403213/khalikov_409785/lab1/src/printer.py" "b/\320\2403213/khalikov_409785/lab1/src/printer.py" new file mode 100644 index 0000000..40efef1 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab1/src/printer.py" @@ -0,0 +1,13 @@ +from tabulate import tabulate + + +def print_matrix(matrix): + print(tabulate(matrix, tablefmt="rounded_grid")) + + +def print_vector(vector): + vector_t = [] + for x in vector: + vector_t.append([x]) + + print(tabulate(vector_t, tablefmt="rounded_grid")) diff --git "a/\320\2403213/khalikov_409785/lab1/src/reader.py" "b/\320\2403213/khalikov_409785/lab1/src/reader.py" new file mode 100644 index 0000000..406aa67 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab1/src/reader.py" @@ -0,0 +1,130 @@ +from printer import print_matrix +from utils import validate_n +from tabulate import tabulate +from exceptions import * + + +def read_n(): + try: + while True: + in_n = input( + "Введите размерность матрицы (n ≤ 20).\nВыберите способ:\n1. Вручную\n2. Из файла\n" + ).strip().lower() + + if in_n in ("1", "вручную"): + return read_n_manual() + + elif in_n in ("2", "из файла"): + return read_n_from_file() + + except KeyboardInterrupt: + print("\nВыход...\n") + exit(0) + + +def read_n_manual(): + while True: + n = input("Введите размерность матрицы:\n").strip() + n = validate_n(n) + if n is not None: + return n + + +def read_n_from_file(): + while True: + file = input("Введите имя файла, в первой строке которого содержится размерность матрицы:\n").strip() + try: + with open(file, "r") as f: + n = f.readline().strip() + if not n: + raise NoNInFile + + + n = validate_n(n) + if n is not None: + return n + + + except NoNInFile: + print("Ошибка: файл пустой или первая строка отсутствует.") + continue + except FileNotFoundError: + print("Файл не найден\n") + except OSError: + print("Ошибка при открытии файла\n") + + +def read_matrix(n): + try: + while True: + in_matrix = input( + f"Введите коэффициенты матрицы {n}x{n}.\nВыберите способ:\n1. Вручную\n2. Из файла\n" + ).strip().lower() + + if in_matrix in ("1", "вручную"): + return read_matrix_manual(n) + + elif in_matrix in ("2", "из файла"): + return read_matrix_from_file(n) + + except KeyboardInterrupt: + print("\nВыход...\n") + exit(0) + + +def read_matrix_manual(n): + matrix = [] + print(f"Введите коэффициенты матрицы {n}x{n}, включая вектор свободных членов, построчно через пробел:") + + for i in range(n): + while True: + try: + row = list( + map(float, input(f"Строка {i+1}: ").replace(",", ".").split())) + if len(row) != n + 1: + raise TooShortRow + matrix.append(row) + break + except TooShortRow: + print(f"Строка должна быть длины {n + 1}") + continue + except ValueError: + print("Некорректный ввод") + except KeyboardInterrupt: + print("\nВыход...\n") + exit(0) + + print("Вы ввели матрицу:") + print_matrix(matrix) + return matrix + + +def read_matrix_from_file(n): + while True: + file = input("Введите имя файла:\n").strip() + + try: + with open(file, "r") as f: + matrix = [list(map(float, line.replace(",", ".").split())) + for line in f] + + if len(matrix) != n or any(len(row) != (n + 1) for row in matrix): + raise IncorrectMatrix + + print("Матрица, полученная из файла:") + print_matrix(matrix) + return matrix + + + except IncorrectMatrix: + print(f"Ошибка: матрица должна быть размером {n}x{n}, включая вектор свободных членов") + continue + except FileNotFoundError: + print("Файл с таким именем не найден") + except ValueError: + print("Некорректная матрица в файле") + except OSError: + print("Некорректное имя файла") + except KeyboardInterrupt: + print("\nВыход...\n") + exit(0) diff --git "a/\320\2403213/khalikov_409785/lab1/src/utils.py" "b/\320\2403213/khalikov_409785/lab1/src/utils.py" new file mode 100644 index 0000000..2242c3f --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab1/src/utils.py" @@ -0,0 +1,60 @@ +import random +from exceptions import * + + +def validate_n(n): + + try: + n = float(n.replace(",", ".")) + if not n.is_integer(): + raise NMustBeInt + n = int(n) + if n > 20: + raise TooBigN + elif n <= 0: + raise ValueError + return n + + except NMustBeInt: + print("Число должно быть целым") + return None + except TooBigN: + print("Размерность матрицы слишком большая") + return None + except ValueError: + print("Размерность должна быть натуральным числом") + return None + except KeyboardInterrupt: + print("\nВыход...\n") + exit(0) + + +def append_vector_to_matrix(vector, matrix): + for i in range(len(matrix)): + matrix[i].append(vector[i]) + + +def get_vector_from_matrix(matrix): + vector = [] + for row in matrix: + vector.append(row[-1]) + return vector + + +def separate_matrix_from_vector(matrix): + new_matrix = [] + n = len(matrix) + for i in range(n): + new_matrix.append(matrix[i][:-1]) + return new_matrix + + + +def generate_matrix_and_save(filename): + + matrix = [[random.randint(-10, 10) for _ in range(21)] for _ in range(20)] + + + with open(filename, "w") as f: + for i in range(20): + f.write(" ".join(map(str, matrix[i])) + "\n") \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab2/reports/report.docx" "b/\320\2403213/khalikov_409785/lab2/reports/report.docx" new file mode 100644 index 0000000..379b8cc Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab2/reports/report.docx" differ diff --git "a/\320\2403213/khalikov_409785/lab2/reports/report.pdf" "b/\320\2403213/khalikov_409785/lab2/reports/report.pdf" new file mode 100644 index 0000000..4a4528a Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab2/reports/report.pdf" differ diff --git "a/\320\2403213/khalikov_409785/lab2/src/exceptions.py" "b/\320\2403213/khalikov_409785/lab2/src/exceptions.py" new file mode 100644 index 0000000..2d36c31 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab2/src/exceptions.py" @@ -0,0 +1,4 @@ +class NotMonotonic(Exception): + pass +class NotCoverage(Exception): + pass \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab2/src/main.py" "b/\320\2403213/khalikov_409785/lab2/src/main.py" new file mode 100644 index 0000000..8dbc514 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab2/src/main.py" @@ -0,0 +1,178 @@ +from read_write import * +import sympy as sp +from single_methods import * +from system_method import * +from plots import * + +def main(): + while True: + print("Выберите тип задачи:") + print("1 - Нелинейное уравнение") + print("2 - Система нелинейных уравнений") + task_choice = input("Введите 1 или 2 (или 'q' для выхода): ").strip() + + if task_choice.lower() == 'q': + break + + if task_choice == "1": + # Выбор уравнения + while True: + print("Выберите уравнение:") + print("1 - f(x) = x^3 - 6x^2 + 11x - 6") + print("2 - f(x) = x^4 - 10x^2 + 9") + print("3 - f(x) = sin(x) - 0.5*x") + print("4 - f(x) = x^20 - x^3 - x^2 - 2") + eq_choice = input("Введите номер: ").strip() + + if eq_choice == "1": + f = lambda x: x**3 - 6*x**2 + 11*x - 6 + f_expr = sp.sympify("x**3 - 6*x**2 + 11*x - 6") + break + elif eq_choice == "2": + f = lambda x: x**4 - 10*x**2 + 9 + f_expr = sp.sympify("x**4 - 10*x**2 + 9") + break + elif eq_choice == "3": + f = lambda x: sp.sin(x) - 0.5*x + f_expr = sp.sympify("sin(x) - 0.5*x") + break + elif eq_choice == "4": + f = lambda x: x**20 - x**3 - x**2 - 2 + f_expr = sp.sympify("x**20 - x**3 - x**2 - 2") + break + else: + print("Некорректный выбор, попробуйте снова.") + + + while True: + print("Выберите метод решения:") + print("1 - Метод половинного деления") + print("2 - Метод Ньютона") + print("3 - Метод простой итерации") + method_choice = input("Введите номер: ").strip() + + if method_choice in ["1", "2", "3"]: + break + print("Некорректный выбор метода, попробуйте снова.") + + + while True: + print("Выберите способ ввода исходных данных:") + print("1 - С клавиатуры") + print("2 - Из файла") + input_choice = input("Введите 1 или 2: ").strip() + + if input_choice == "1": + try: + a, b, eps = input_data(["Введите левую границу интервала a: ", + "Введите правую границу интервала b: ", + "Введите точность eps: "]) + break + except Exception as e: + print("Ошибка ввода:", e) + continue + elif input_choice == "2": + filename = input("Введите имя файла для чтения данных: ").strip() + data = read_data_from_file(filename) + if data is not None and len(data) >= 3: + a, b, eps = data[0], data[1], data[2] + break + print("Некорректные данные в файле, попробуйте снова.") + else: + print("Некорректный выбор, попробуйте снова.") + + + sign_changes = count_sign_changes(f, a, b) + if sign_changes == 0: + print("На данном интервале корней не обнаружено. Попробуйте другой интервал.") + continue + elif sign_changes > 1: + print("На данном интервале обнаружено несколько корней. Уточните границы.") + continue + + + try: + if method_choice == "1": + root, f_val, iterations = bisection(f, a, b, eps) + elif method_choice == "2": + root, f_val, iterations = newton_single(f, a, b, eps) + elif method_choice == "3": + root, f_val, iterations = simple_iteration(lambda x: sp.sympify(f(x)), a, b, eps) + except Exception as e: + print("Ошибка при решении уравнения:", e) + continue + + + output_str = (f"Найденный корень: {root}\n" + f"Значение функции в корне: {f_val}\n" + f"Число итераций: {iterations}\n") + + while True: + print("Выберите способ вывода результатов:") + print("1 - На экран") + print("2 - В файл") + output_choice = input("Введите 1 или 2: ").strip() + + if output_choice == "1": + print(output_str) + break + elif output_choice == "2": + out_filename = input("Введите имя файла для записи результатов: ").strip() + write_results_to_file(out_filename, output_str) + break + else: + print("Некорректный выбор, попробуйте снова.") + + plot_function(f, a, b, root) + + elif task_choice == "2": + + while True: + print("Выберите систему уравнений:") + print("1 - Система 1: x^2 + y^2 - 4 = 0, exp(x) + y - 1 = 0") + print("2 - Система 2: sin(x) + y^2 - 1 = 0, x^2 + cos(y) - 1 = 0") + sys_choice = input("Введите 1 или 2: ").strip() + + if sys_choice == "1": + F, J, system_label = F1, J1, "Система 1" + break + elif sys_choice == "2": + F, J, system_label = F2, J2, "Система 2" + break + else: + print("Некорректный выбор, попробуйте снова.") + + + while True: + try: + x0 = parse_float(input("Введите начальное приближение для x: ")) + y0 = parse_float(input("Введите начальное приближение для y: ")) + break + except Exception as e: + print("Ошибка ввода:", e) + continue + + z0 = np.array([x0, y0]) + try: + root, iterations, errors = newton_system(F, J, z0, 0.01) + except Exception as e: + print("Ошибка при решении системы методом Ньютона:", e) + continue + + print(f"Найденное решение: {root}\nКоличество итераций: {iterations}\nВектор погрешностей:") + for i in errors: + print(i) + + + x_interval = [root[0] - 2, root[0] + 2] + y_interval = [root[1] - 2, root[1] + 2] + plot_system(F, x_interval, y_interval, root, system_label) + + else: + print("Некорректный выбор, попробуйте снова.") + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("\nВыход...") diff --git "a/\320\2403213/khalikov_409785/lab2/src/plots.py" "b/\320\2403213/khalikov_409785/lab2/src/plots.py" new file mode 100644 index 0000000..c409032 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab2/src/plots.py" @@ -0,0 +1,43 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_function(f, a, b, root=None): + x_vals = np.linspace(a, b, 400) + y_vals = np.array([f(x) for x in x_vals]) + + plt.figure() + plt.plot(x_vals, y_vals, label="y") + plt.axhline(0, color='black', linewidth=0.5) + + if root is not None: + plt.scatter(root, f(root), color='green', zorder=3, label="Корень") + + plt.title("График функции") + plt.xlabel("x") + plt.ylabel("f(x)") + plt.legend() + plt.grid(True) + plt.show() + +def plot_system(F, interval_x, interval_y, root=None, system_label="Система"): + x_vals = np.linspace(interval_x[0], interval_x[1], 400) + y_vals = np.linspace(interval_y[0], interval_y[1], 400) + X, Y = np.meshgrid(x_vals, y_vals) + + + Z1 = F(np.array([X, Y]))[0] + Z2 = F(np.array([X, Y]))[1] + + plt.figure() + plt.contour(X, Y, Z1, levels=[0], colors='blue') + plt.contour(X, Y, Z2, levels=[0], colors='red') + + if root is not None: + plt.scatter(root[0], root[1], color='green', marker='o', s=50, zorder=3, label="Решение") + + plt.title(f"График системы: {system_label}") + plt.xlabel("x") + plt.ylabel("y") + plt.legend() + plt.grid(True) + plt.show() diff --git "a/\320\2403213/khalikov_409785/lab2/src/read_write.py" "b/\320\2403213/khalikov_409785/lab2/src/read_write.py" new file mode 100644 index 0000000..7e03afe --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab2/src/read_write.py" @@ -0,0 +1,38 @@ +import numpy as np + +def parse_float(user_input): + try: + return float(user_input.replace(',', '.')) + except Exception as e: + raise ValueError("Некорректное число: " + user_input) + +def input_data(prompt_list): + data = [] + for prompt in prompt_list: + user_input = input(prompt) + data.append(parse_float(user_input)) + return data + +def read_data_from_file(filename): + try: + with open(filename, "r", encoding="utf-8") as f: + lines = f.readlines() + data = [] + if len(lines) == 1: + data = [parse_float(x) for x in lines[0].split()] + else: + for line in lines: + line = line.strip() + if line: + data.append(parse_float(line)) + return data + except Exception as e: + print("Ошибка при чтении файла:", e) + return None + +def write_results_to_file(filename, results): + try: + with open(filename, "w", encoding="utf-8") as f: + f.write(results) + except Exception as e: + print("Ошибка при записи в файл:", e) \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab2/src/single_methods.py" "b/\320\2403213/khalikov_409785/lab2/src/single_methods.py" new file mode 100644 index 0000000..c93751d --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab2/src/single_methods.py" @@ -0,0 +1,104 @@ +import sympy as sp +from scipy.optimize import minimize_scalar +import numpy as np +from exceptions import * +from utils import * +# 1 – Метод половинного деления +# 3 – Метод Ньютона +# 5 – Метод простой итерации +# 6 – Метод Ньютона (для системы) + + +def bisection(f, a, b, eps): + n = 0 + x = (a + b) / 2 + while (abs(a - b) > eps or abs(f(x)) >= eps): + x = (a + b) / 2 + if f(a) * f(x) > 0: + a = x + else: + b = x + n += 1 + + return x, f(x), n + + + +def newton_single(g, a, b, eps): + + n = 0 + x = sp.symbols('x') + + f = g(x) + + df = sp.diff(f, x) + d2f = sp.diff(f, x, 2) + + + # условие сходимости, выбор x0 + if f.subs(x, a).evalf() * d2f.subs(x, a).evalf() > 0: + x_i = a + elif f.subs(x, b).evalf() * d2f.subs(x, b).evalf() > 0: + x_i = b + else: + x_i = (a + b) / 2 + + while True: + n += 1 + x_prev = x_i + x_i = x_prev - f.subs(x, x_prev).evalf() / df.subs(x, x_prev).evalf() + + if abs(x_i - x_prev) <= eps or abs(f.subs(x, x_i).evalf() / df.subs(x, x_prev).evalf()) <= eps or abs(f.subs(x, x_i).evalf()) <= eps: + break + + return x_i, f.subs(x, x_i).evalf(), n + + +def simple_iteration(g, a, b, eps): + n = 0 + x = sp.symbols('x') + + f = g(x) + + if not (is_increasing(f, a, b) or is_decreasing(f, a, b)): + raise NotMonotonic("Функция не монотонна на заданном отрезке") + + + df = sp.diff(f, x) + d2f = sp.diff(f, x, 2) + + # выбор x0 + if f.subs(x, a).evalf() * d2f.subs(x, a).evalf() > 0: + x_i = a + elif f.subs(x, b).evalf() * d2f.subs(x, b).evalf() > 0: + x_i = b + else: + x_i = (a + b) / 2 + + + mx = max(abs( df.subs(x, a).evalf() ), abs( df.subs(x, b).evalf() )) + lmbd = 1 / mx + + if is_increasing(df, a, b): + pass + + elif is_decreasing(df, a, b): + lmbd = -lmbd + + phi = x + lmbd * f + + + dphi = sp.diff(phi, x) + for point in np.linspace(a, b, 100): # 100 точек на отрезке [a, b] + value = abs( dphi.subs(x, point).evalf() ) + if value > 1: + raise NotCoverage("Метод не сходится на заданном отрезке") + + while True: + n += 1 + prev = x_i + x_i = phi.subs(x, prev).evalf() + if abs(x_i - prev) <= eps: + break + return prev, g(prev), n + diff --git "a/\320\2403213/khalikov_409785/lab2/src/system_method.py" "b/\320\2403213/khalikov_409785/lab2/src/system_method.py" new file mode 100644 index 0000000..2834f45 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab2/src/system_method.py" @@ -0,0 +1,54 @@ +import numpy as np +from utils import * + + +def F1(z): + + x, y = z[0], z[1] + return np.array([ + x**2 + y**2 - 4, + np.exp(x) + y - 1 + ]) + +def J1(z): + + x, y = z[0], z[1] + return np.array([ + [2*x, 2*y], + [np.exp(x), 1] + ]) + + +def F2(z): + + x, y = z[0], z[1] + return np.array([ + np.sin(x) + y**2 - 1, + x**2 + np.cos(y) - 1 + ]) + +def J2(z): + + x, y = z[0], z[1] + return np.array([ + [np.cos(x), 2*y], + [2*x, -np.sin(y)] + ]) + +def newton_system(F, J, z0, eps): + n = 0 + error_history = [] + z = z0.copy() + while True: + n += 1 + Fz = F(z) + Jz = J(z) + delta = np.linalg.solve(Jz, Fz) + z_new = z - delta + error_vector = np.abs(z_new - z) + error_history.append(error_vector.copy()) + if np.all(np.abs(z_new - z) <= eps) and np.all(np.abs(F(z_new) - F(z)) <= eps): + return z_new, n, error_history + + z = z_new + diff --git "a/\320\2403213/khalikov_409785/lab2/src/utils.py" "b/\320\2403213/khalikov_409785/lab2/src/utils.py" new file mode 100644 index 0000000..a0e89c0 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab2/src/utils.py" @@ -0,0 +1,48 @@ +import sympy as sp +from scipy.optimize import minimize_scalar +import numpy as np +from exceptions import * + + +def get_max_f(f, a, b): + result = minimize_scalar(lambda z: -f(z), bounds=(a, b), method='bounded') + return result.x + +def get_min_f(f, a, b): + result = minimize_scalar(f, bounds=(a, b), method='bounded') + return result.x + +def get_max_abs_f(f, a, b): + return max(abs(f(a)), abs(f(b))) + +def is_increasing(f, a, b): + is_increasing = True + + x = sp.symbols('x') + df = sp.diff(f, x) + + for point in np.linspace(a, b, 100): # 100 точек на отрезке [a, b] + value = df.subs(x, point).evalf() + if value < 0: + is_increasing = False + + return is_increasing + +def is_decreasing(f, a, b): + is_decreasing = True + + x = sp.symbols('x') + df = sp.diff(f, x) + + for point in np.linspace(a, b, 100): # 100 точек на отрезке [a, b] + value = df.subs(x, point).evalf() + if value > 0: + is_decreasing = False + + return is_decreasing + +def count_sign_changes(f, a, b, num_points=2000): + x_vals = np.linspace(a, b, num_points) + f_vals = np.array([f(x) for x in x_vals]) + sign_changes = np.sum(np.diff(np.sign(f_vals)) != 0) + return sign_changes \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab3/reports/report.docx" "b/\320\2403213/khalikov_409785/lab3/reports/report.docx" new file mode 100644 index 0000000..bcc189b Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab3/reports/report.docx" differ diff --git "a/\320\2403213/khalikov_409785/lab3/reports/report.pdf" "b/\320\2403213/khalikov_409785/lab3/reports/report.pdf" new file mode 100644 index 0000000..5caa7a7 Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab3/reports/report.pdf" differ diff --git "a/\320\2403213/khalikov_409785/lab3/src/main.py" "b/\320\2403213/khalikov_409785/lab3/src/main.py" new file mode 100644 index 0000000..c4ba69b --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/main.py" @@ -0,0 +1,85 @@ +from utils import * +import numpy as np +from methods.left_rect import left_rectangle +from methods.right_rect import right_rectangle +from methods.mid_rect import mid_rectangle +from methods.simpson import simpson +from methods.trapezoid import trapezoid +from methods.runge_rule import runge_rule + + +N = 4 +dict = {"1": {"1": (left_rectangle, 1), "2": (right_rectangle, 1), "3": (mid_rectangle, 2)}, + "2": (trapezoid, 2), "3": (simpson, 4)} + + +def main(): + while True: + while True: + print("Выберите функцию:") + print("1 - f(x) = x^3 - 6x^2 + 11x - 6") + print("2 - f(x) = x^4 - 10x^2 + 9") + print("3 - f(x) = sin(x) - 0.5*x") + print("4 - f(x) = x^20 - x^3 - x^2 - 2") + eq_choice = input("Введите номер: ").strip() + if eq_choice == "1": + f = lambda x: x**3 - 6*x**2 + 11*x - 6 + break + elif eq_choice == "2": + f = lambda x: x**4 - 10*x**2 + 9 + break + elif eq_choice == "3": + f = lambda x: np.sin(x) - 0.5*x + break + elif eq_choice == "4": + f = lambda x: x**20 - x**3 - x**2 - 2 + break + else: + print("Некорректный выбор, попробуйте снова.") + + while True: + print("Выберите метод:") + print("1 - Метод прямоугольников") + print("2 - Метод трапеции") + print("3 - Метод Симпсона") + method_choice = input("Введите номер: ").strip() + + if method_choice == "1": + print("Выберите модификацию:") + print("1 - левые") + print("2 - правые") + print("3 - средние") + mod_choice = input("Введите номер: ").strip() + if mod_choice in ["1", "2", "3"]: + method = dict.get(method_choice).get(mod_choice)[0] + k = dict.get(method_choice).get(mod_choice)[1] + break + print("Некорректный выбор модификации.") + if method_choice in ["2", "3"]: + method = dict.get(method_choice)[0] + k = dict.get(method_choice)[1] + break + print("Некорректный выбор метода.") + + while True: + try: + a, b, eps = input_data(["Введите левый предел: ", + "Введите правый предел: ", + "Введите точность: "]) + break + except Exception as e: + print("Ошибка ввода:", e) + continue + + n = runge_rule(method, f, a, b, N, eps, k) + answer = method(f, a, b, n) + + + print(f"Вычисленный интеграл: {answer}\nЧисло отрезков для точности {eps}: {n}") + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("\nВыход...") diff --git "a/\320\2403213/khalikov_409785/lab3/src/methods/left_rect.py" "b/\320\2403213/khalikov_409785/lab3/src/methods/left_rect.py" new file mode 100644 index 0000000..ada85cf --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/methods/left_rect.py" @@ -0,0 +1,8 @@ +def left_rectangle(f, a, b, n): + h = (b - a) / n + sum = 0 + for i in range(n): + sum += f(a) + a += h + + return h * sum diff --git "a/\320\2403213/khalikov_409785/lab3/src/methods/mid_rect.py" "b/\320\2403213/khalikov_409785/lab3/src/methods/mid_rect.py" new file mode 100644 index 0000000..749bfa0 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/methods/mid_rect.py" @@ -0,0 +1,9 @@ +def mid_rectangle(f, a, b, n): + h = (b - a) / n + sum = 0 + a += h / 2 + for i in range(n): + sum += f(a) + a += h + + return h * sum diff --git "a/\320\2403213/khalikov_409785/lab3/src/methods/right_rect.py" "b/\320\2403213/khalikov_409785/lab3/src/methods/right_rect.py" new file mode 100644 index 0000000..ac6f012 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/methods/right_rect.py" @@ -0,0 +1,8 @@ +def right_rectangle(f, a, b, n): + h = (b - a) / n + sum = 0 + for i in range(n): + a += h + sum += f(a) + + return h * sum diff --git "a/\320\2403213/khalikov_409785/lab3/src/methods/runge_rule.py" "b/\320\2403213/khalikov_409785/lab3/src/methods/runge_rule.py" new file mode 100644 index 0000000..8914930 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/methods/runge_rule.py" @@ -0,0 +1,13 @@ +def runge_rule(method, f, a, b, n, eps, k): + integral = method(f, a, b, n) + + integral_2n = method(f, a, b, 2 * n) + error = (integral_2n - integral) / (2**k - 1) + + while abs(error) >= eps: + n = 2 * n + integral = integral_2n + integral_2n = method(f, a, b, 2 * n) + error = (integral_2n - integral) / (2**k - 1) + + return 2*n \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab3/src/methods/simpson.py" "b/\320\2403213/khalikov_409785/lab3/src/methods/simpson.py" new file mode 100644 index 0000000..d8a587f --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/methods/simpson.py" @@ -0,0 +1,13 @@ +def simpson(f, a, b, n): + h = (b - a) / n + sum = 0 + y0 = f(a) + yn = f(b) + for i in range(1, n): + a += h + if i % 2 == 0: + sum += 2 * f(a) + else: + sum += 4 * f(a) + + return h / 3 * (y0 + sum + yn) diff --git "a/\320\2403213/khalikov_409785/lab3/src/methods/trapezoid.py" "b/\320\2403213/khalikov_409785/lab3/src/methods/trapezoid.py" new file mode 100644 index 0000000..ba416ff --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/methods/trapezoid.py" @@ -0,0 +1,12 @@ +def trapezoid(f, a, b, n): + h = (b - a) / n + sum = 0 + y0 = f(a) + yn = f(b) + + for i in range(1, n): + a += h + sum += f(a) + + + return h * ( (y0 + yn) / 2 + sum ) diff --git "a/\320\2403213/khalikov_409785/lab3/src/utils.py" "b/\320\2403213/khalikov_409785/lab3/src/utils.py" new file mode 100644 index 0000000..efd8a09 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab3/src/utils.py" @@ -0,0 +1,12 @@ +def parse_float(user_input): + try: + return float(user_input.replace(',', '.')) + except Exception as e: + raise ValueError("Некорректное число: " + user_input) + +def input_data(prompt_list): + data = [] + for prompt in prompt_list: + user_input = input(prompt) + data.append(parse_float(user_input)) + return data \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab4/reports/report.docx" "b/\320\2403213/khalikov_409785/lab4/reports/report.docx" new file mode 100644 index 0000000..1cd5f72 Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab4/reports/report.docx" differ diff --git "a/\320\2403213/khalikov_409785/lab4/reports/report.pdf" "b/\320\2403213/khalikov_409785/lab4/reports/report.pdf" new file mode 100644 index 0000000..d1e4289 Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab4/reports/report.pdf" differ diff --git "a/\320\2403213/khalikov_409785/lab4/src/lianerize.py" "b/\320\2403213/khalikov_409785/lab4/src/lianerize.py" new file mode 100644 index 0000000..d9fe017 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/lianerize.py" @@ -0,0 +1,36 @@ +import math + +def lianerize_power_table(table): + x = table[0] + y = table[1] + + try: + for i in range(len(x)): + table[0][i] = math.log(table[0][i]) + + for j in range(len(y)): + table[1][j] = math.log(table[1][j]) + except ValueError: + raise ValueError("Ошибка: невозможно лианезировать таблицу.\nДопустимы только ненулевые числа") + + return table + +def lianerize_exp_table(table): + y = table[1] + try: + for j in range(len(y)): + table[1][j] = math.log(table[1][j]) + except ValueError: + raise ValueError("Ошибка: невозможно лианезировать таблицу.\nДопустимы только ненулевые числа") + + return table + +def lianerize_log_table(table): + x = table[0] + try: + for i in range(len(x)): + table[0][i] = math.log(table[0][i]) + except ValueError: + raise ValueError("Ошибка: невозможно лианезировать таблицу.\nДопустимы только ненулевые числа") + + return table \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab4/src/main.py" "b/\320\2403213/khalikov_409785/lab4/src/main.py" new file mode 100644 index 0000000..d0a2c83 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/main.py" @@ -0,0 +1,189 @@ +from matrix_solver import * +from read import * +import math +from lianerize import * +from utils import * +from min_squares import * +from r_coeffs import * +from print import * +import matplotlib.pyplot as plt +import numpy as np + + +def plot_all_functions(table, coeffs_lin=None, coeffs_pol2=None, coeffs_pol3=None, + coeffs_exp=None, coeffs_log=None, coeffs_pow=None): + x = np.array(table[0]) + y = np.array(table[1]) + x_min, x_max = min(x), max(x) + x_dense = np.linspace(x_min, x_max, 500) + + plt.figure(figsize=(10, 6)) + plt.scatter(x, y, color='black', label="Исходные точки") + + if coeffs_lin: + y_lin = coeffs_lin[0] + coeffs_lin[1] * x_dense + plt.plot(x_dense, y_lin, label=f"Линейная: {coeffs_lin[0]:.2f} + {coeffs_lin[1]:.2f}x", linewidth=2) + + if coeffs_pol2: + y_pol2 = coeffs_pol2[0] + coeffs_pol2[1] * x_dense + coeffs_pol2[2] * x_dense**2 + plt.plot(x_dense, y_pol2, label=f"Полином 2-й: {coeffs_pol2[0]:.2f} + {coeffs_pol2[1]:.2f}x + {coeffs_pol2[2]:.2f}x²", linewidth=2) + if coeffs_pol3: + y_pol3 = coeffs_pol3[0] + coeffs_pol3[1] * x_dense + coeffs_pol3[2] * x_dense**2 + coeffs_pol3[3] * x_dense**3 + plt.plot(x_dense, y_pol3, label=f"Полином 3-й: {coeffs_pol3[0]:.2f} + {coeffs_pol3[1]:.2f}x + {coeffs_pol3[2]:.2f}x² + {coeffs_pol3[3]:.2f}x³", linewidth=2) + + if coeffs_exp: + try: + y_exp = coeffs_exp[0] * np.exp(coeffs_exp[1] * x_dense) + plt.plot(x_dense, y_exp, label=f"Экспоненциальная: {coeffs_exp[0]:.2f}e^({coeffs_exp[1]:.2f}x)", linewidth=2) + except (ValueError, OverflowError): + print("Ошибка при построении экспоненциальной функции") + + x_dense_pos = x_dense[x_dense > 0] + if len(x_dense_pos) > 0: + if coeffs_log: + try: + y_log = coeffs_log[0] + coeffs_log[1] * np.log(x_dense_pos) + plt.plot(x_dense_pos, y_log, label=f"Логарифмическая: {coeffs_log[0]:.2f} + {coeffs_log[1]:.2f}ln(x)", linewidth=2) + except ValueError: + print("Ошибка при построении логарифмической функции") + if coeffs_pow: + try: + y_pow = coeffs_pow[0] * x_dense_pos**coeffs_pow[1] + plt.plot(x_dense_pos, y_pow, label=f"Степенная: {coeffs_pow[0]:.2f}x^{coeffs_pow[1]:.2f}", linewidth=2) + except ValueError: + print("Ошибка при построении степенной функции") + else: + print("Пропущены логарифмическая и степенная функции — нет положительных x") + + plt.title("Графики") + plt.xlabel("x") + plt.ylabel("y") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def main(): + while True: + try: + s = input("Выберите способ ввода данных:\n1. Вручную\n2. Из файла\n") + if s == '1': + table = read_number_table() + elif s == '2': + file = input("Введите имя файла:\n") + table = read_number_table(file) + else: + continue + except (FileNotFoundError, ValueError) as e: + print(e) + continue + + try: + coeffs_lin = min_squares_method(table[0], table[1], 1) + coeffs_pol2 = min_squares_method(table[0], table[1], 2) + coeffs_pol3 = min_squares_method(table[0], table[1], 3) + except ZeroDivisionError: + print("Ошибка: проверьте, не повторяются ли числа") + continue + + coeffs_exp = [math.exp(coeffs_lin[0]), coeffs_lin[1]] + coeffs_pow = [math.exp(coeffs_lin[0]), coeffs_lin[1]] + coeffs_log = coeffs_lin + + phi_lin = phi_poly(coeffs_lin, 1) + phi_poly2 = phi_poly(coeffs_pol2, 2) + phi_poly3 = phi_poly(coeffs_pol3, 3) + phi_exp_f = phi_exp(coeffs_exp) + phi_log_f = phi_log(coeffs_log) + phi_power_f = phi_power(coeffs_pow) + + available_models = {} + + for name, phi, coeffs in [ + ("Линейная функция", phi_lin, coeffs_lin), + ("Полином 2-й степени", phi_poly2, coeffs_pol2), + ("Полином 3-й степени", phi_poly3, coeffs_pol3), + ("Экспоненциальная функция", phi_exp_f, coeffs_exp), + ("Логарифмическая функция", phi_log_f, coeffs_log), + ("Степенная функция", phi_power_f, coeffs_pow) + ]: + try: + phi_arr = phi_x_arr(phi, table[0]) + phi_eps = phi_epsilons(phi, table) + available_models[name] = (phi, coeffs, phi_arr, phi_eps) + except ValueError as e: + print(f"Ошибка в {name.lower()}: {e}") + + s = input("Выберите способ вывода данных:\n1. В консоль\n2. В файл\n") + if s == '1': + print(f"X:\n{format_arr(table[0])}") + print(f"Y:\n{format_arr(table[1])}") + for name, (phi, coeffs, arr, eps) in available_models.items(): + try: + print_cli_res(name, format_arr(coeffs), MSE(phi, table), + format_arr(arr), format_arr(eps), determination(phi, table)) + print() + except ValueError as e: + print(e) + elif s == '2': + file = input("Введите имя файла:\n") + with open(file, "w", encoding="utf-8") as f: + for name, (phi, coeffs, arr, eps) in available_models.items(): + try: + write_res_to_file(f, name, format_arr(coeffs), MSE(phi, table), + format_arr(arr), format_arr(eps), determination(phi, table)) + f.write('\n') + except ValueError as e: + print(e) + else: + continue + + + best_model = None + min_mse = float('inf') + + for name, (phi, *_rest) in available_models.items(): + try: + mse = MSE(phi, table) + if mse < min_mse: + min_mse = mse + best_model = (name, phi) + except ValueError as e: + print(f"Ошибка при вычислении СКО для '{name}': {e}") + continue + + if not best_model: + print("Нет подходящих моделей для оценки.") + continue + + best_name, best_phi = best_model + + + try: + r2 = determination(best_phi, table) + if r2 >= 0.95: + message = "Высокая точность" + elif 0.75 <= r2 < 0.95: + message = "Удовлетворительная точность" + elif 0.5 <= r2 < 0.75: + message = "Слабая точность" + else: + message = "Недостаточная точность" + print("Наилучшее приближение:") + print(f"{best_name}: MSE = {min_mse:.5f}, R^2 = {r2:.3f}. {message}") + except ValueError as e: + print(f"{best_name}: MSE = {min_mse:.5f}, но не удалось вычислить R^2: {e}") + + + + plot_all_functions(table, coeffs_lin, coeffs_pol2, coeffs_pol3, coeffs_exp, coeffs_log, coeffs_pow) + + + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("Выход...") diff --git "a/\320\2403213/khalikov_409785/lab4/src/matrix_solver.py" "b/\320\2403213/khalikov_409785/lab4/src/matrix_solver.py" new file mode 100644 index 0000000..e493766 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/matrix_solver.py" @@ -0,0 +1,80 @@ +import math + +permutations = 0 + +# метод Гаусса с выбором главного элемента +def gaussian_elimination_modified(matrix, b): + last_permutations = permutations + + n = len(matrix) + x = [0]*n + + # прямой ход + for i in range(n-1): + + modified_replace(matrix, i, b) + + last_permutations = permutations + + for k in range(i+1, n): + + c = matrix[k][i] / matrix[i][i] + + matrix[k][i] = 0 + + for j in range(i+1, n): + matrix[k][j] = matrix[k][j] - c*matrix[i][j] + + b[k] = b[k] - c * b[i] + + # обратный ход + + for i in range(n-1, -1, -1): + try: + s = 0 + for j in range(i+1, n): + s += matrix[i][j]*x[j] + x[i] = (b[i] - s) / matrix[i][i] + except ZeroDivisionError: + raise ZeroDivisionError("Решени либо нет, либо их бесконечно много") + + + return x + +# перестановка строк +def modified_replace(matrix, i, b): + global permutations + l = i + n = len(matrix) + for m in range(i+1, n): + if abs(matrix[m][i]) > abs(matrix[l][i]): + l = m + if l == i: + return + else: + matrix[i], matrix[l] = matrix[l], matrix[i] + b[i], b[l] = b[l], b[i] + permutations += 1 + +# невязка Ax* - b = r +def calc_residual(matrix, b, x): + + n = len(matrix) + residual = [] + for i in range(n): + r = 0 + for j in range(n): + r += matrix[i][j] * x[j] + r -= b[i] + residual.append(r) + return residual + +# получить главную диагональ +def diagonal(matrix): + return [matrix[i][i] for i in range(len(matrix))] + + +# посчитать определитель треугольной матрицы +def calc_determinant_triangle(diagonal, k): + + return (-1)**k * math.prod(diagonal) diff --git "a/\320\2403213/khalikov_409785/lab4/src/min_squares.py" "b/\320\2403213/khalikov_409785/lab4/src/min_squares.py" new file mode 100644 index 0000000..b926dc8 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/min_squares.py" @@ -0,0 +1,29 @@ +from matrix_solver import * +import math +from utils import * + +# m -- polynom power +def min_squares_method(x_arr, y_arr, m): + n = len(x_arr) + sums_x = [] + sums_y = [] + + + for i in range(m*2+1): + pows = [i for _ in range(n)] + + sums_x.append(sum( map( math.pow, x_arr, pows) )) + + def mult(x, y): + return x*y + + for i in range(m+1): + x_pow_m = [x**i for x in x_arr] + sums_y.append( sum( map( mult, x_pow_m, y_arr) ) ) + + + matrix = sym_matrix(sums_x, m) + b = sums_y + ans = gaussian_elimination_modified(matrix, b) + return ans + \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab4/src/print.py" "b/\320\2403213/khalikov_409785/lab4/src/print.py" new file mode 100644 index 0000000..cc830cb --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/print.py" @@ -0,0 +1,15 @@ +def print_cli_res(label, coeffs, mse, phi_i, eps_i, det): + print(label) + print(f"Коэффициенты:\n{coeffs}") + print(f"СКО:\n{mse:.3f}") + print(f"φ(x_i):\n{phi_i}") + print(f"ε_i:\n{eps_i}") + print(f"Достоверность аппроксимации:\n{det:.3f}") + +def write_res_to_file(file, name, coeffs, mse, phi_arr, eps_arr, r2): + file.write(f"{name}\n") + file.write(f"Коэффициенты:\n{coeffs}\n") + file.write(f"СКО:\n{mse:.3f}\n") + file.write(f"φ(x_i):\n{phi_arr}\n") + file.write(f"ε_i:\n{eps_arr}\n") + file.write(f"Достоверность аппроксимации:\n{r2:.3f}\n\n") diff --git "a/\320\2403213/khalikov_409785/lab4/src/r_coeffs.py" "b/\320\2403213/khalikov_409785/lab4/src/r_coeffs.py" new file mode 100644 index 0000000..e9fb34c --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/r_coeffs.py" @@ -0,0 +1,38 @@ +from utils import * + +def corr_coeff(table): + x = table[0] + y = table[1] + n = len(x) + + x_avg = sum(x) / n + y_avg = sum(y) / n + + numerator = 0 + denominator_x = 0 + denominator_y = 0 + + for i in range(n): + numerator += (x[i] - x_avg) * (y[i] - y_avg) + denominator_x += (x[i] - x_avg) ** 2 + denominator_y += (y[i] - y_avg) ** 2 + + denominator = (denominator_x * denominator_y) ** 0.5 + + r = numerator / denominator + return r + +def determination(phi, table): + n = len(table[0]) + y = table[1] + mse = MSE(phi, table) + phi_i = phi_x_arr(phi, table[0]) + phi_i_avg = sum(phi_i) / n + + denominator = 0 + for i in range(n): + denominator += (y[i] - phi_i_avg)**2 + + R2 = 1 - mse / denominator + + return R2 \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab4/src/read.py" "b/\320\2403213/khalikov_409785/lab4/src/read.py" new file mode 100644 index 0000000..c979bd0 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/read.py" @@ -0,0 +1,37 @@ +def read_number_table(source=None): + table = [] + if source is None: + x = read_number_arr(input("Введите точки x:\n")) + y = read_number_arr(input("Введите значения y:\n")) + else: + try: + with open(source, 'r', encoding='utf-8') as f: + lines = f.readlines() + except FileNotFoundError: + raise FileNotFoundError(f"Файл '{source}' не найден") + + if len(lines) < 2: + raise ValueError("Ошибка: файл должен содержать как минимум две строки (x и y)") + + x = read_number_arr(lines[0]) + y = read_number_arr(lines[1]) + + if len(x) != len(y): + raise ValueError("Ошибка: число точек и значений должно совпадать") + + table.append(x) + table.append(y) + return table + + +def read_number_arr(s): + s = s.replace(',', '.') + try: + arr = list(map(float, s.split())) + except ValueError: + raise ValueError("Ошибка: строка содержит нечисловые значения") + + if not (8 <= len(arr) <= 12): + raise ValueError("Ошибка: количество точек должно быть от 8 до 12") + + return arr diff --git "a/\320\2403213/khalikov_409785/lab4/src/utils.py" "b/\320\2403213/khalikov_409785/lab4/src/utils.py" new file mode 100644 index 0000000..e586b17 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab4/src/utils.py" @@ -0,0 +1,101 @@ +import math + +def sym_matrix(arr, m): + matrix = [] + for i in range(m + 1): + row = [] + for j in range(m + 1): + row.append(arr[i + j]) + matrix.append(row) + return matrix + +def str_approx_poly(coeffs): + s = [] + + n = len(coeffs) + s.append(str(coeffs[0])) + s.append(str(coeffs[1]) + "x") + for i in range(2, n): + s.append(str(coeffs[i]) + "x^" + str(i)) + return (" + ".join(s).replace("+ -", "- ")) + +def str_approx_power(coeffs): + a = coeffs[0] + b = coeffs[1] + return (f"{a}x^{b}") + +def str_approx_exp(coeffs): + a = coeffs[0] + b = coeffs[1] + return (f"{a}e^{b}x") + +def str_approx_log(coeffs): + a = coeffs[0] + b = coeffs[1] + return (f"{a} + {b}ln(x)") + +def phi_poly(coeffs, m): + def f(x): + return sum(coeffs[i] * x**i for i in range(m + 1)) + return f + +def phi_power(coeffs): + a = coeffs[0] + b = coeffs[1] + def f(x): + return a * x ** b + return f + +def phi_exp(coeffs): + a = coeffs[0] + b = coeffs[1] + def f(x): + return a * math.pow(math.e, b*x) + return f + +def phi_log(coeffs): + a = coeffs[0] + b = coeffs[1] + def f(x): + return a + b * math.log(x) + return f + + +def S(phi, table): + x = table[0] + y = table[1] + sum = 0 + for i in range(len(x)): + sum += (phi(x[i]) - y[i])**2 + + return sum + +def MSE(phi, table): + try: + s = S(phi, table) + n = len(table[0]) + mse = s / n + return math.sqrt(mse) + except Exception as e: + raise ValueError(f"СКО не удалось вычислить: {e}") + + +def phi_epsilons(phi, table): + x = table[0] + y = table[1] + eps = [] + for i in range(len(y)): + eps.append( phi(x[i]) - y[i] ) + return eps + +def phi_x_arr(phi, x_arr): + y_arr = [] + try: + for i in x_arr: + y_arr.append(phi(i)) + except (ValueError, ZeroDivisionError): + raise ValueError(f"Недопустимая операция с нулем") + return y_arr + +def format_arr(arr, precision=3): + return "[" + ", ".join(f"{x:.{precision}f}" for x in arr) + "]" diff --git "a/\320\2403213/khalikov_409785/lab5/reports/report.docx" "b/\320\2403213/khalikov_409785/lab5/reports/report.docx" new file mode 100644 index 0000000..79ffbff Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab5/reports/report.docx" differ diff --git "a/\320\2403213/khalikov_409785/lab5/reports/report.pdf" "b/\320\2403213/khalikov_409785/lab5/reports/report.pdf" new file mode 100644 index 0000000..789920c Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab5/reports/report.pdf" differ diff --git "a/\320\2403213/khalikov_409785/lab5/src/datasources.py" "b/\320\2403213/khalikov_409785/lab5/src/datasources.py" new file mode 100644 index 0000000..1f3b705 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab5/src/datasources.py" @@ -0,0 +1,85 @@ +import sys +import math +import csv + +def get_data_keyboard(): + x_vals, y_vals = [], [] + print("Введите точки интерполяции (x y), по одной на строке. Пустая строка для завершения:") + while True: + try: + line = input().strip() + if not line: + break + parts = line.replace(',', '.').split() + if len(parts) != 2: + print("Ожидаются два числа: x и y") + continue + x_new = float(parts[0]) + y_new = float(parts[1]) + if x_new in x_vals: + print(f"Значение x={x_new} уже введено, повторения запрещены.") + continue + x_vals.append(x_new) + y_vals.append(y_new) + except KeyboardInterrupt: + raise + except Exception: + print("Некорректный ввод.") + return x_vals, y_vals + + +def get_data_file(): + filename = input("Введите путь к файлу: ") + x_vals, y_vals = [], [] + try: + with open(filename, newline='', encoding='utf-8') as csvfile: + reader = csv.reader(csvfile) + for row in reader: + if len(row) < 2: + continue + try: + x_new = float(row[0].replace(',', '.')) + y_new = float(row[1].replace(',', '.')) + except Exception: + print(f"Пропущена строка с некорректными числами: {row}") + continue + if x_new in x_vals: + print(f"Пропущен дубликат x={x_new} из файла.") + continue + x_vals.append(x_new) + y_vals.append(y_new) + except Exception as e: + print(f"Ошибка чтения файла: {e}") + return x_vals, y_vals + + +def get_data_function(): + functions = {'1': ('sin(x)', math.sin), '2': ('cos(x)', math.cos)} + while True: + print("Выберите функцию для генерации данных:") + for key, (name, _) in functions.items(): + print(f"{key}: {name}") + choice = input("Ваш выбор: ").strip() + if choice not in functions: + print("Некорректный выбор.") + continue + _, func = functions[choice] + try: + a = float(input("Введите левую границу: ").replace(',', '.')) + b = float(input("Введите правую границу: ").replace(',', '.')) + n = int(input("Введите число точек (>=2): ")) + if n < 2 or a >= b: + print("Параметры интервала некорректны.") + continue + except KeyboardInterrupt: + raise + except Exception: + print("Неверный ввод.") + continue + xs = [] + ys = [] + for i in range(n): + x_val = a + i*(b-a)/(n-1) + xs.append(x_val) + ys.append(func(x_val)) + return xs, ys \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab5/src/difference_table.py" "b/\320\2403213/khalikov_409785/lab5/src/difference_table.py" new file mode 100644 index 0000000..d84189f --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab5/src/difference_table.py" @@ -0,0 +1,31 @@ +from interpolators import _divided_differences + +def build_table(y): + n = len(y) + table = [y[:]] + for level in range(1, n): + prev = table[level-1] + curr = [prev[i+1] - prev[i] for i in range(n-level)] + table.append(curr) + return table + + +def print_finite_table(x, y): + table = build_table(y) + headers = [f"Δ^{i}" for i in range(len(table))] + print("| x | " + " | ".join(headers) + " |") + print("|" + "-------|"*(len(headers)+1)) + for i, xv in enumerate(x): + row = [f"{xv:.4f}"] + [f"{table[level][i]:.4f}" if i < len(table[level]) else "" for level in range(len(table))] + print("| " + " | ".join(row) + " |") + + +def print_divided_table(x, y): + table = _divided_differences(x, y) + n = len(x) + print("Разделенные разности:") + for i in range(n): + print(f"x[{i}]={x[i]:.4f}", end=": ") + for j in range(n-i): + print(f"{table[j][i]:.4f}", end=" ") + print() \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab5/src/interpolators.py" "b/\320\2403213/khalikov_409785/lab5/src/interpolators.py" new file mode 100644 index 0000000..dc24e1e --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab5/src/interpolators.py" @@ -0,0 +1,70 @@ +def lagrange_poly(x, y): + def poly(x0): + total = 0.0 + n = len(x) + for i in range(n): + term = y[i] + for j in range(n): + if i != j: + term *= (x0 - x[j])/(x[i] - x[j]) + total += term + return total + return poly + + +def _divided_differences(x, y): + n = len(x) + table = [row[:] for row in [y] + [[0]*n for _ in range(n-1)]] + for level in range(1, n): + for i in range(n-level): + table[level][i] = (table[level-1][i+1] - table[level-1][i])/(x[i+level] - x[i]) + return table + + +def newton_coeffs(x, y): + table = _divided_differences(x, y) + return [table[i][0] for i in range(len(x))] + + +def newton_poly(x, coeffs): + def poly(x0): + result = coeffs[0] + for i in range(1, len(coeffs)): + term = coeffs[i] + for j in range(i): + term *= (x0 - x[j]) + result += term + return result + return poly + + +def forward_newton(x, y, x0): + n = len(y) + h = x[1] - x[0] + diffs = [y[:]] + for level in range(1, n): + prev = diffs[level-1] + diffs.append([prev[i+1] - prev[i] for i in range(n-level)]) + t = (x0 - x[0]) / h + result = diffs[0][0] + prod = 1.0 + for i in range(1, n): + prod *= (t - (i-1)) / i + result += prod * diffs[i][0] + return result + + +def backward_newton(x, y, x0): + n = len(y) + h = x[1] - x[0] + diffs = [y[:]] + for level in range(1, n): + prev = diffs[level-1] + diffs.append([prev[i+1] - prev[i] for i in range(n-level)]) + t = (x0 - x[-1]) / h + result = diffs[0][-1] + prod = 1.0 + for i in range(1, n): + prod *= (t + (i-1)) / i + result += prod * diffs[i][-1] + return result \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab5/src/main.py" "b/\320\2403213/khalikov_409785/lab5/src/main.py" new file mode 100644 index 0000000..296ac58 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab5/src/main.py" @@ -0,0 +1,72 @@ +import sys +import math +from datasources import get_data_keyboard, get_data_file, get_data_function +from interpolators import lagrange_poly, newton_coeffs, newton_poly, forward_newton, backward_newton +from difference_table import print_finite_table, print_divided_table +from plotter import plot_all_methods + +def main(): + try: + while True: + print("Выберите источник данных (1-клавиатура, 2-файл, 3-функция, q-выход):") + choice = input().strip().lower() + if choice == 'q': + break + if choice == '1': + x, y = get_data_keyboard(); real_func=None + elif choice == '2': + x, y = get_data_file(); real_func=None + elif choice == '3': + x, y = get_data_function(); real_func=math.sin if abs(y[1]-math.sin(x[1]))<1e-6 else math.cos + else: + print("Неверный выбор."); continue + + if len(x)<2 or len(set(x))!=len(x): + print("Проверьте, что узлов не менее двух и все x уникальны."); continue + + h = x[1]-x[0] + equal = all(abs((x[i+1]-x[i])-h)<1e-8 for i in range(len(x)-1)) + print() + if equal: + print("Таблица конечных разностей:") + print_finite_table(x,y) + else: + print("Таблица разделенных разностей:") + print_divided_table(x,y) + + try: + x0=float(input("\nВведите аргумент для интерполяции: ").replace(',','.')) + except KeyboardInterrupt: + raise + except Exception: + print("Некорректный ввод аргумента."); continue + + # Создаем полиномы + lag=lagrange_poly(x,y) + coeffs=newton_coeffs(x,y) + newt=newton_poly(x,coeffs) + # Вычисляем значения + r_lag=lag(x0) + r_newt=newt(x0) + vals={'lag':r_lag,'newt':r_newt} + print(f"Lagrange: {r_lag:.6f}") + print(f"Newton (divided): {r_newt:.6f}") + fwd,bwd=None,None + if equal: + mid=(x[0]+x[-1])/2 + if x0<=mid: + fwd=lambda z: forward_newton(x,y,z) + vals['fwd']=forward_newton(x,y,x0) + print(f"Newton forward: {vals['fwd']:.6f}") + else: + bwd=lambda z: backward_newton(x,y,z) + vals['bwd']=backward_newton(x,y,x0) + print(f"Newton backward: {vals['bwd']:.6f}") + + print("Построение графика... ") + plot_all_methods(x,y,lag,newt,fwd,bwd,x0,vals,real_func) + except KeyboardInterrupt: + print("\nВыход."); sys.exit(0) + +if __name__=='__main__': + main() diff --git "a/\320\2403213/khalikov_409785/lab5/src/plotter.py" "b/\320\2403213/khalikov_409785/lab5/src/plotter.py" new file mode 100644 index 0000000..f6df700 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab5/src/plotter.py" @@ -0,0 +1,24 @@ +import matplotlib.pyplot as plt + +def plot_all_methods(x, y, lag, newt, eq_fwd=None, eq_bwd=None, x0=None, vals=None, real_func=None): + xs_cont = [min(x) + i*(max(x)-min(x))/1000 for i in range(1001)] + ys_lag = [lag(xi) for xi in xs_cont] + ys_newt = [newt(xi) for xi in xs_cont] + plt.figure() + if real_func: + ys_real = [real_func(xi) for xi in xs_cont] + plt.plot(xs_cont, ys_real, label="Исходная функция") + plt.plot(xs_cont, ys_lag, linestyle='--', label="Лагранж") + plt.plot(xs_cont, ys_newt, linestyle='-.', label="Ньютон (разделенные)") + if eq_fwd: + ys_fwd = [eq_fwd(xi) for xi in xs_cont] + plt.plot(xs_cont, ys_fwd, linestyle=':', label="Ньютон (вперед)") + if eq_bwd: + ys_bwd = [eq_bwd(xi) for xi in xs_cont] + plt.plot(xs_cont, ys_bwd, linestyle=':', label="Ньютон (назад)") + plt.plot(x, y, marker='o', linestyle='', label="Узлы") + plt.legend() + plt.title("Сравнение методов интерполяции") + plt.xlabel("x") + plt.ylabel("y") + plt.show() \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab6/reports/report.docx" "b/\320\2403213/khalikov_409785/lab6/reports/report.docx" new file mode 100644 index 0000000..391ccef Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab6/reports/report.docx" differ diff --git "a/\320\2403213/khalikov_409785/lab6/reports/report.pdf" "b/\320\2403213/khalikov_409785/lab6/reports/report.pdf" new file mode 100644 index 0000000..71ec46a Binary files /dev/null and "b/\320\2403213/khalikov_409785/lab6/reports/report.pdf" differ diff --git "a/\320\2403213/khalikov_409785/lab6/src/main.py" "b/\320\2403213/khalikov_409785/lab6/src/main.py" new file mode 100644 index 0000000..c030d10 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab6/src/main.py" @@ -0,0 +1,53 @@ +import sys +from utils import input_float, input_int, select_equation, format_decimal +from methods import euler, improved_euler, milne +import matplotlib.pyplot as plt + +def print_table(xs, ys, method_name): + print(f"\nМетод {method_name}:") + print(f"{'i':>3s} {'x_i':>10s} {'y_i':>15s}") + for i, (x, y) in enumerate(zip(xs, ys)): + print(f"{i:3d} {format_decimal(x):>10s} {format_decimal(y):>15s}") + +if __name__ == '__main__': + print("Выбор ОДУ y' = f(x,y):") + f, y_exact, expr = select_equation() + print(f"Вы выбрали уравнение y' = {expr}\n") + + x0 = input_float("Введите x0: ") + y0 = input_float("Введите y0: ") + xn = input_float("Введите xn: ") + h = input_float("Введите шаг h: ") + eps= input_float("Введите точность eps: ") + + try: + xs_eu, ys_eu, err_eu = euler(f, x0, y0, xn, h, eps) + xs_ie, ys_ie, err_ie = improved_euler(f, x0, y0, xn, h, eps) + xs_ml, ys_ml, errs_ml = milne(f, y_exact, x0, y0, xn, h) + except Exception as e: + print(f"Ошибка при вычислениях: {e}") + sys.exit(1) + + print_table(xs_eu, ys_eu, "Эйлера") + print(f"Оценка погрешности Рунге: {format_decimal(err_eu)}") + + print_table(xs_ie, ys_ie, "Усоверш. Эйлера") + print(f"Оценка погрешности Рунге: {format_decimal(err_ie)}") + + print_table(xs_ml, ys_ml, "Милна") + print(f"Максимальная погрешность: {format_decimal(errs_ml)}") + + num_steps = int((xn - x0) / h) + 1 + xs_exact = [x0 + i*h for i in range(num_steps)] + ys_exact = [y_exact(x) for x in xs_exact] + + plt.plot(xs_exact, ys_exact, label='Точное') + plt.plot(xs_eu, ys_eu, '--', label='Эйлер') + plt.plot(xs_ie, ys_ie, '--', label='Мод. Эейлер') + plt.plot(xs_ml, ys_ml, '--', label='Милн') + plt.legend() + plt.xlabel('x') + plt.ylabel('y') + plt.title("Решение ОДУ") + plt.grid(True) + plt.show() diff --git "a/\320\2403213/khalikov_409785/lab6/src/methods.py" "b/\320\2403213/khalikov_409785/lab6/src/methods.py" new file mode 100644 index 0000000..0466027 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab6/src/methods.py" @@ -0,0 +1,58 @@ +import math + +def euler(f, x0, y0, xn, h, eps): + n = int((xn - x0) / h) + xs = [x0] + ys = [y0] + for _ in range(n): + xi, yi = xs[-1], ys[-1] + yi1 = yi + h * f(xi, yi) + xs.append(xi + h) + ys.append(yi1) + #рунге + y1 = y0 + h * f(x0, y0) + y_half = y0 + (h/2) * f(x0, y0) + y_half = y_half + (h/2) * f(x0 + h/2, y_half) + err = abs(y1 - y_half) + return xs, ys, err + +def improved_euler(f, x0, y0, xn, h, eps): + n = int((xn - x0) / h) + xs = [x0] + ys = [y0] + for _ in range(n): + xi, yi = xs[-1], ys[-1] + k1 = f(xi, yi) + k2 = f(xi + h, yi + h * k1) + yi1 = yi + h * (k1 + k2) / 2 + xs.append(xi + h) + ys.append(yi1) + #рунге + y1 = y0 + h * (f(x0, y0) + f(x0 + h, y0 + h * f(x0, y0))) / 2 + h2 = h / 2 + y_half = y0 + for i in range(2): + xi = x0 + i * h2 + y_half = y_half + h2 * (f(xi, y_half) + f(xi + h2, y_half + h2 * f(xi, y_half))) / 2 + err = abs(y1 - y_half) / (2**2 - 1) + return xs, ys, err + +def milne(f, y_exact, x0, y0, xn, h): + n = int((xn - x0) / h) + xs = [x0 + i * h for i in range(4)] + ys = [y0] + # стартовые 3 шага методом Эйлера + for i in range(3): + ys.append(ys[-1] + h * f(xs[i], ys[-1])) + errors = [] + # предиктор-корректор Милна + for i in range(3, n): + x_im3, x_im2, x_im1, xi = xs[i-3], xs[i-2], xs[i-1], xs[i] + y_im3, y_im2, y_im1 = ys[i-3], ys[i-2], ys[i-1] + y_pred = y_im3 + (4*h/3) * (2*f(x_im2, y_im2) - f(x_im1, y_im1) + 2*f(xi, y_im1)) + y_corr = y_im1 + (h/3) * (f(x_im1, y_im1) + 4*f(xi, y_pred) + f(xi+h, y_pred)) + xs.append(xi + h) + ys.append(y_corr) + errors.append(abs(y_exact(xi + h) - y_corr)) + max_err = max(errors) if errors else 0 + return xs, ys, max_err \ No newline at end of file diff --git "a/\320\2403213/khalikov_409785/lab6/src/utils.py" "b/\320\2403213/khalikov_409785/lab6/src/utils.py" new file mode 100644 index 0000000..6cce884 --- /dev/null +++ "b/\320\2403213/khalikov_409785/lab6/src/utils.py" @@ -0,0 +1,37 @@ +import math + +def input_float(prompt): + while True: + s = input(prompt).strip() + s = s.replace(',', '.') + try: + return float(s) + except ValueError: + print("Неверный формат числа. Попробуйте еще раз.") + +def input_int(prompt): + while True: + s = input(prompt).strip() + try: + return int(s) + except ValueError: + print("Неверный формат целого числа. Попробуйте еще раз.") + +def select_equation(): + eqs = { + 1: (lambda x, y: y, lambda x: math.exp(x), "exp(x)"), + 2: (lambda x, y: 2 + 6*math.exp(2*x), lambda x: 2*x + 3*math.exp(2*x), "2x + 3e^{2x}"), + 3: (lambda x, y: 1 + math.cos(x), lambda x: x + math.cos(x), "x + cos(x)"), + } + print("1: y' = y , точное решение y=exp(x)") + print("2: y' = 2+6e^{2x} , точное решение y=2x+3e^{2x}") + print("3: y' = 1+cos(x) , точное решение y=x+sin(x)") + while True: + try: + c = int(input("Выберите номер уравнения: ")) + return eqs[c] + except (KeyError, ValueError): + print("Неверный выбор. Попробуйте снова.") + +def format_decimal(x, prec=6): + return f"{x:.{prec}f}"