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
182 changes: 182 additions & 0 deletions Р3208/vasilev_366389/lab1/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import csv
import numpy as np
import random


def generate_random_matrix(min_val=-25, max_val=25):
size = random.randint(2, 20)
matrix = [[random.uniform(min_val, max_val) for _ in range(size)] for _ in range(size)]
vector = [random.uniform(min_val, max_val) for _ in range(size)]

for i in range(size):
matrix[i].append(vector[i])

return matrix


def read_matrix_from_file(filename):
matrix = []
try:
with open(filename, newline='') as file:
if filename.endswith('.csv'):
reader = csv.reader(file)
rows = [row for row in reader]
else:
rows = [line.split() for line in file]

for row in rows:
if not all(num.replace('.', '', 1).replace('-', '', 1).isdigit() for num in row):
raise ValueError("Ошибка: все элементы должны быть вещественными числами")
matrix.append([float(num) for num in row])
return matrix
except FileNotFoundError:
print("Такой файл не найден. Попробуйте снова.")
return read_matrix_from_file(input())


def validate_matrix(matrix):
n = len(matrix)
for row in matrix:
if len(row) != n + 1:
raise ValueError("Ошибка: каждая строка должна содержать n элементов матрицы и один элемент вектора")


def diagonal_dominance(matrix):
matrix = np.array(matrix)
n = len(matrix)
for i in range(n):
row_sum = sum(abs(matrix[i, j]) for j in range(n) if j != i)
if abs(matrix[i, i]) <= row_sum:
return False
return True


def rearrange_matrix(matrix, vector):
n = len(matrix)
matrix = np.array(matrix, dtype=float)
vector = np.array(vector, dtype=float)
for i in range(n):
max_index = max(range(i, n),
key=lambda k: abs(matrix[k, i]) - sum(abs(matrix[k, j]) for j in range(n) if j != i))
if max_index != i:
matrix[[i, max_index]] = matrix[[max_index, i]]
vector[i], vector[max_index] = vector[max_index], vector[i]
return matrix, vector


def norm_matrix(matrix):
return max(sum(abs(element) for element in row) for row in matrix)


def iteration(matrix, x, vector):
n = len(matrix)
x_new = np.zeros(n)
for i in range(n):
sum_ax = sum(matrix[i][j] * x[j] for j in range(n) if j != i)
x_new[i] = (vector[i] - sum_ax) / matrix[i][i]
return x_new


def iterative_method(matrix, vector, precision, max_iterations=1000):
n = len(matrix)
x = np.zeros(n)
iterations = 0
errors = []

while iterations <= max_iterations:
x_new = iteration(matrix, x, vector)
errors.append(np.abs(x_new - x))

iterations += 1

if np.max(np.abs(x_new - x)) < precision:
return x_new, iterations, errors

x = x_new

print("Метод не сошёлся за", max_iterations, "итераций")
return x, max_iterations, errors


def calculate_matrix(matrix, precision):
validate_matrix(matrix)
matrix = np.array(matrix, dtype=float)
vector = matrix[:, -1]
matrix = matrix[:, :-1]

if not diagonal_dominance(matrix):
matrix, vector = rearrange_matrix(matrix, vector)
if not diagonal_dominance(matrix):
print("Ошибка: матрица не является диагонально доминирующей и не может быть преобразована")
return

norm = norm_matrix(matrix)
x, iterations, errors = iterative_method(matrix, vector, precision)

print("Матрица после преобразований: ")
for i in range(len(matrix)):
print([float('%.2f' % elem) for elem in matrix[i]])
print("Вектор свободных членов после преобразований: ", vector)
print("Норма матрицы: ", norm)
print("Вектор неизвестных: ", x)
print("Количество итераций: ", iterations)
print("Погрешность: ", errors[-1] if errors else None)


def is_valid_number(value):
try:
float(value)
return True
except ValueError:
return False


def main():
print("Решение системы линейных алгебраических уравнений СЛАУ")
while True:
try:
print("Введите точность:")
precision = float(input())
if precision <= 0:
raise ValueError("Ошибка: точность должна быть положительным числом.")
break
except ValueError:
print("Ошибка: введите корректное положительное число для точности.")
print(
"Введите матрицу в формате 'a11 a12 a13 ... a1n b1; a21 a22 a23 ... a2n b2; ... a3n1 an2 an3 ... ann bn' или введите имя файла с матрицей (.txt или .csv)")
print("Матрица должна быть квадратной. n <= 20")
print("Введите имя файла или первую строку матрицы: (Для генерации случайной матрицы введите RANDOM)")
while True:
try:
input_data = input().strip()
if input_data.endswith('.csv') or input_data.endswith('.txt'):
matrix = read_matrix_from_file(input_data)
elif input_data == 'RANDOM':
matrix = generate_random_matrix()
print("Сгенерированная матрица:")
for i in range(len(matrix)):
print([float('%.2f' % elem) for elem in matrix[i]])
else:
matrix = [[float(num) for num in input_data.split()]]
if len(matrix[0]) > 21:
raise ValueError("Ошибка: размерность матрицы должна быть не больше 20.")
current_row = 1
while current_row < len(matrix[0]) - 1:
input_data = input().strip()
row = input_data.split()
if len(row) != len(matrix[0]) or not all(is_valid_number(num) for num in row):
print(f"Ошибка: строка должна содержать {len(matrix[0])} вещественных чисел.")
continue
matrix.append([float(num) for num in row])
current_row += 1
break
except ValueError as e:
print(f"Ошибка: {e}. Попробуйте снова.")
try:
calculate_matrix(matrix, precision)
except ValueError as e:
print(e)


if __name__ == '__main__':
main()
69 changes: 69 additions & 0 deletions Р3208/vasilev_366389/lab2/calculation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import numpy as np
import verificator
import plots


def method_of_chords(f, a, b, epsilon, max_iter=1000):
if not verificator.check_root(f, a, b):
return None

x0, x1 = a, b
for _ in range(max_iter):
f0, f1 = f(x0), f(x1)
if abs(f1 - f0) < 1e-12:
break
x2 = x1 - f1 * (x1 - x0) / (f1 - f0)
if abs(x2 - x1) < epsilon:
plots.plot_function(f, a, b, x2)
return x2, f(x2), _ + 1
x0, x1 = x1, x2
plots.plot_function(f, a, b, x2)
return max_iter


def newtons_method(f, df, x0, epsilon, max_iter=1000):
for _ in range(max_iter):
f0, df0 = f(x0), df(f, x0)
if abs(df0) < 1e-12:
break
x1 = x0 - f0 / df0
if abs(x1 - x0) < epsilon:
plots.plot_function_without_points(f, x0, x1)
return x1, f(x1), _ + 1
x0 = x1
plots.plot_function_without_points(f, x0, x1)
return max_iter


def simple_iterations(f, phi, x0, epsilon, max_iter=1000):
x = x0
for _ in range(max_iter):
x_next = phi(f, x)
if abs(x_next - x) < epsilon:
plots.plot_function_without_points(f, x0, x_next)
return x_next, f(x_next), _ + 1
x = x_next
plots.plot_function_without_points(f, x0, x_next)
return max_iter


def newton_system_method(f, J, x0, epsilon, max_iter=1000):
x = np.array(x0)
errors = []
for _ in range(max_iter):
F = np.array([fi(x) for fi in f])
J_matrix = J(f, x)
try:
J_inv = np.linalg.inv(J_matrix)
except np.linalg.LinAlgError:
return None
delta = np.dot(J_inv, F)
x_next = x - delta
error = np.linalg.norm(x_next - x)
errors.append(float(error))
if error < epsilon:
plots.plot_functions_system(f[0], f[1], x_next, x0)
return x_next, _, errors
x = x_next
return max_iter

44 changes: 44 additions & 0 deletions Р3208/vasilev_366389/lab2/examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import numpy as np

functions = [
lambda x: 2.74 * x**3 - 1.93 * x**2 - 15.28 * x - 3.72,
lambda x: np.sin(x) - 0.5 * x**2 + 3,
lambda x: np.cos(x) + 3 * x**4 - 2,
lambda x: x**5 - 10 * x**3 + 4 * x**2 - 7,
lambda x: np.exp(x) - x**10 + 1
]

function_strings = [
"2.74 * x**3 - 1.93 * x**2 - 15.28 * x - 3.72",
"sin(x) - 0.5 * x^2 + 3",
"cos(x) + 3 * x^4 - 2",
"x^5 - 10 * x^3 + 4 * x^2 - 7",
"exp(x) - x^10 + 1"
]

methods_strings = [
"Метод хорд",
"Метод Ньютона",
"Метод простой итерации"
]

system_strings = [
"f1(x, y) = tan(xy + 0.3) - x^2, f2(x, y) = 0.9x^2 + 2y^2 - 1",
"f1(x, y) = sin(x + y) - 1.4x, f2(x, y) = x^2 + y ^2 - 1"
]

system_variables = [
['x', 'y'],
['x', 'y']
]

systems = [
[
lambda x: np.tan(x[0] * x[1] + 0.3) - x[0]**2,
lambda x: 0.9 * x[0]**2 + 2 * x[1]**2 - 1
],
[
lambda x: np.sin(x[0] + x[1]) - x[0]*1.4,
lambda x: x[0]**2 + x[1]**2 - 1
]
]
Loading