Skip to content
Open

Lab2 #12

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
Binary file added Р3208/kaparulin_408737/lab1/Comp_math_1.pdf
Binary file not shown.
157 changes: 157 additions & 0 deletions Р3208/kaparulin_408737/lab1/SysOfLinEq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
from itertools import permutations

import numpy as np

class SysOfLinEq:
def __init__(self, file_name=''):
self.answ = []
self.variance = float('inf')
self.iter_cnt = 0

if not file_name:
self.__input_params()
else:
self.__read_params(file_name)

self.__is_epsilon_correct()

assert self.__is_solvable(), "The condition of predominance of diagonal elements is not fulfilled"

self.__create_coeff_matrix()
self.__solution()

def get_variance(self):
return self.variance

def get_iteration_count(self):
return self.iter_cnt

def get_matrix_norm(self):
return np.max(np.sum(np.abs(self.KMatrix[:, :-1]), axis=1))

def get_solution(self):
return self.solution

# решение СЛАУ
def __solution(self):
"""
У нас есть расширенная матрица со свободными коэфицентами
тогда чтобы они имели вес ровно 1, добавляем единичный столбец
"""
self.solution = np.concat(( self.KMatrix[:, self.dims], [1] ))

while np.max(self.variance) >= self.epsilon:
self.iter_cnt+=1
old_solution = np.copy(self.solution)

for line in range(self.dims):
self.solution[line] = np.sum(self.KMatrix[line] * self.solution)

self.variance = np.abs(self.solution - old_solution)

self.solution = self.solution[:-1]
self.variance = self.variance[:-1]

# создание матрицы коэфициентов
def __create_coeff_matrix(self):
self.KMatrix = np.empty((self.dims, self.dims+1))

for line in range(self.dims):
self.KMatrix[line] = np.concat(( -self.matrix[line], [self.answ[line]]))
self.KMatrix[line] /= self.matrix[line][line]
self.KMatrix[line, line] = 0


# выполняется ли условие сходимости
def __is_solvable(self):
# проверка, что вообще есть число большее суммы остальных в строке
if self.__is_not_diagonally_dominant(np.abs(self.matrix)):
return False

# попытка поставить на диагональ максимальные числа
for line in range(self.dims):
sorted_indices = np.argsort(self.matrix[line:][:, line])[::-1]
self.matrix[line:] = self.matrix[line:][sorted_indices]

if self.__is_diagonally_dominant(np.abs(self.matrix)):
return True

# можно переставновками проверить, но это дольше
# чем две верхних проверки
for perm in permutations(range(self.dims)):
permuted_matrix = self.matrix[list(perm), :]

if self.__is_diagonally_dominant(np.abs(permuted_matrix)):
self.matrix = permuted_matrix
return True

return False

# проверка условия преобладания диагональных элементов
def __is_not_diagonally_dominant(self, matrix):
return np.any( (np.sum(matrix, axis=1) - 2*np.max(matrix, axis=1)) > 0 )

# проверка условия преобладания диагональных элементов
def __is_diagonally_dominant(self, matrix):
one_strict = False
diagonally_dominant = np.sum(matrix, axis=1) - 2*np.diag(matrix)

if np.any(diagonally_dominant > 0):
return False

if np.any(diagonally_dominant < 0):
one_strict = True

return True & one_strict


def __is_epsilon_correct(self):
if self.epsilon < 0:
raise ValueError("e must be positive")

# ввод всех параметров
def __input_params(self):

print("Input n: ", end="")
self.dims = self.__get_param("n", int, input)
print("Input e: ", end="")
self.epsilon = self.__get_param("e", float, input)

self.matrix = np.empty((self.dims, self.dims))

print("\nInput matrix:")

for line_cnt in range(self.dims):
line_input = input().split()
self.answ.append(line_input[-1])
line = np.array(list(map(float, line_input[:-1])), dtype=np.float64)
assert line.shape == (self.dims,), "Incorrect line shape"
self.matrix[line_cnt] = line

print()

# чтение всех параметов из файла
def __read_params(self, file_name):
with open(file_name) as f:

self.dims = self.__get_param("n", int, f.readline)
self.epsilon = self.__get_param("e", float, f.readline)


self.matrix = np.empty((self.dims, self.dims))

for line_cnt in range(self.dims):
line_file = f.readline().split()
self.answ.append(line_file[-1])
line = np.array(list(map(float, line_file[:-1])), dtype=np.float64)
assert line.shape == (self.dims,), "Incorrect line shape"
self.matrix[line_cnt] = line

self.answ = np.array(self.answ, dtype=np.float64)

# получение 1 параметра
def __get_param(self, name, type, func):
try:
return type(func())
except:
raise ValueError(f"Incorrect {name}")
13 changes: 13 additions & 0 deletions Р3208/kaparulin_408737/lab1/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from SysOfLinEq import SysOfLinEq





if __name__ == "__main__":
sle = SysOfLinEq("pars.txt") # pars.txt

print("Решение: ", sle.get_solution())
print("Норма матрицы: ", sle.get_matrix_norm())
print("Кол-во итераций: ", sle.get_iteration_count())
print("Вектор погрешностей: ", sle.get_variance())
26 changes: 26 additions & 0 deletions Р3208/kaparulin_408737/lab1/rand_gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import random

import numpy as np

n = int(input("Input n: "))
e = float(input("Input e: "))

with open("pars.txt", "w") as f:
f.write(str(n) + "\n")
f.write(str(e) + "\n")

lines = []
diag = list(range(n))

for _ in range(n):
random_number = random.choice(diag)

diag.remove(random_number)

line = np.random.randint(0, 10, n+1)

lines.append(" ".join(map(str, line)) + "\n")


f.writelines(lines)

Binary file added Р3208/kaparulin_408737/lab2/Non_lin_equ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions Р3208/kaparulin_408737/lab2/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Лабораторная работа 2

6 вариант
Binary file added Р3208/kaparulin_408737/lab2/System_graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Р3208/kaparulin_408737/lab2/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from non_lin_eq import Lin_Eq

Lin_Eq()
109 changes: 109 additions & 0 deletions Р3208/kaparulin_408737/lab2/non_lin_eq/Main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from .PolDel import PolDel
from .Secant import Secant
from .SimpleIter import SimpleIter

from numpy import sin, cos
import numpy as np
import matplotlib.pyplot as plt

f = [
[
lambda x: 2*x**3 + 3.41*x**2 - 23.74*x + 2.95,
lambda x: 6*x**2 + 6.82*x - 23.74,
lambda x: 12*x + 6.82
],

[
lambda x: sin(x) + cos(x),
lambda x: cos(x) - sin(x),
lambda x: -sin(x) - cos(x)
],

[
lambda x: x**2 + 1,
lambda x: 2*x,
lambda x: 2
],

[
lambda x: x + cos(x-1) - 0.7,
lambda x: 1 - sin(x-1),
lambda x: - cos(x-1)
],
]

method = [
PolDel,
Secant,
SimpleIter
]

class Main:
def __init__(self):
eq_nmb = 0

while(eq_nmb not in [1, 2, 3, 4]):
print("[1] f(x) = 2*x**3 + 3.41*x**2 - 23.74*x + 2.95")
print("[2] f(x) = sin(x) + cos(x)")
print("[3] f(x) = x**2 + 1")
print("[4] f(x) = x + cos(x-1) - 0.7")
print("Введите номер уравнения: ", end="")
eq_nmb = self.__get_param("equation number", int, input)
print()

print("Введите путь до данных(\"\" - ввод в терминале): ", end="")
file = self.__get_param("file name", str, input)


method_nmb = 0

while(method_nmb not in [1, 2, 3]):
print()
print("[1] Метод половинного деления")
print("[2] Метод секущих")
print("[3] Метод простой итерации")
print("Введите номер метода решения уравнения: ", end="")
method_nmb = self.__get_param("method name", int, input)

print()
print("Результаты в файл?(\"\" - нет, file_path - да): ", end="")
res_file = self.__get_param("result file name", str, input)
print()

x, f_x, iter_cnt, interval = method[method_nmb-1](f[eq_nmb-1], file).get_answer()

if res_file == "":
print("x: ", x)
print("f(x): ", f_x)
print("Number of iteration: ", iter_cnt)
else:
resf = open(res_file, 'w')

print("x: ", x, file=resf)
print("f(x): ", f_x, file=resf)
print("Number of iteration: ", iter_cnt, file=resf)

resf.close()

x_plot = np.linspace(interval[0], interval[1], 500)
y_plot = f[eq_nmb-1][0](x_plot)

plt.title('График нелинейной функции')
plt.plot(x_plot, y_plot)
plt.xlabel('x')
plt.ylabel('y')
plt.grid(1)
plt.savefig("Non_lin_equ.png")


# получение 1 параметра
def __get_param(self, name, type, func):
try:
return type(func())
except:
print(f"Incorrect {name}")
exit()


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