1
0

first commit

This commit is contained in:
Suiranoil
2024-03-19 14:03:49 +03:00
commit 00024e4ed1
17 changed files with 1191 additions and 0 deletions

View File

@@ -0,0 +1,205 @@
import aim
import сomputational_mathematics as cm
from PyQt6.QtWidgets import QComboBox, QPushButton, QLineEdit, QFormLayout
import sys
import numpy as np
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel
from PyQt6.QtGui import QIcon
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class Form(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("Lab2")
self.setWindowIcon(QIcon("icon.png"))
self.setGeometry(100, 100, 800, 940)
main_layout = QVBoxLayout()
# Группа "Уравнение"
equation_html = (
'<span style="color:rgb(87, 46, 120); font-size:28px;">Уравнение:</span>'
)
equation_html += "<br>"
equation_html += (
'<span style="font-size:28px;">y = x<sup>3</sup> - 10 * x + 2</span>'
)
# Создаем QLabel с использованием HTML разметки
label_equation = QLabel(self)
label_equation.setText(equation_html)
label_equation.setWordWrap(True) # Переносим текст если он не помещается в окне
# Добавляем QLabel в вашу группу и на главный слой
group_equation = QVBoxLayout()
group_equation.addWidget(label_equation)
main_layout.addLayout(group_equation)
# Группа "Параметры"
self.group_parameters = QFormLayout()
label_name = QLabel("Параметры:", self)
label_name.setStyleSheet("color: rgb(87, 46, 120); font-size: 28px")
self.group_parameters.addWidget(label_name)
self.label_a = QLabel("a:", self)
self.label_a.setStyleSheet("color: rgb(87, 46, 120); font-size: 20px")
self.line_edit_a = QLineEdit(self)
self.line_edit_a.setText("-10000.0")
self.label_b = QLabel("b:", self)
self.label_b.setStyleSheet("color: rgb(87, 46, 120); font-size: 20px")
self.line_edit_b = QLineEdit(self)
self.line_edit_b.setText("10000.0")
self.group_parameters.addRow(label_name)
self.group_parameters.addRow(self.label_a, self.line_edit_a)
self.group_parameters.addRow(self.label_b, self.line_edit_b)
main_layout.addLayout(self.group_parameters)
# Группа "Действия"
self.group_actions = QVBoxLayout()
label_actions = QLabel("Действия:", self)
label_actions.setStyleSheet("color: rgb(87, 46, 120); font-size: 28px")
self.button_find_solution = QPushButton("Решить", self)
self.button_find_solution.clicked.connect(self.findSolution)
self.combo_box_solutions = QComboBox(self)
self.combo_box_solutions.addItems(
[
"Метод половинного деления",
"Метод хорд",
"Метод Ньютона",
"Модифицированный метод",
"Комбинированный метод",
"Итерационный метод",
]
)
group_parameters = QFormLayout()
group_parameters.addRow(label_actions)
group_parameters.addRow(self.button_find_solution, self.combo_box_solutions)
self.group_actions.addLayout(group_parameters)
self.label_result = QLabel("Результат:", self)
self.label_result.setStyleSheet("color: rgb(87, 46, 120); font-size: 20px")
self.group_actions.addWidget(self.label_result)
self.line_edit_result = QLineEdit(self)
self.group_actions.addWidget(self.line_edit_result)
self.line_edit_roots = QLineEdit(self)
self.group_actions.addWidget(self.line_edit_roots)
self.line_edit_section = QLineEdit(self)
self.group_actions.addWidget(self.line_edit_section)
self.line_edit_result.setText(f"Решения: ")
self.line_edit_roots.setText(f"Найдено: z интервалов")
self.line_edit_section.setText(f"Отрезок (a, b)")
main_layout.addLayout(self.group_actions)
self.setLayout(main_layout)
# Добавление виджета для графика
self.canvas = FigureCanvas(Figure())
main_layout.addWidget(self.canvas)
self.setLayout(main_layout)
self.plotGraph()
def findSolution(self):
method = self.combo_box_solutions.currentText()
a = float(self.line_edit_a.text())
b = float(self.line_edit_b.text())
x_range = np.array(np.arange(a, b, step=0.1), dtype=np.float64)
y_range = aim.f(x_range)
solution_range = []
for i in range(len(x_range) - 1):
if y_range[i] * y_range[i + 1] < 0:
solution_range.append((x_range[i], x_range[i + 1]))
strResult = "Решения: "
strSection = "Отрезки: "
self.line_edit_roots.setText(f"Найдено: {len(solution_range)} интервала")
for a, b in solution_range:
if method == "Метод половинного деления":
strResult += "[" + str(cm.half_div_method(aim.f, aim.f_d, a, b)) + "] "
strSection += f" ({a}, {b}) "
elif method == "Метод хорд":
strResult += (
"[" + str(cm.chord_method(aim.f, aim.f_d, aim.f_dd, a, b)) + "] "
)
strSection += f" ({a}, {b}) "
elif method == "Метод Ньютона":
strResult += "[" + str(cm.newtons_method(aim.f, aim.f_d, a, b)) + "] "
strSection += f" ({a}, {b}) "
elif method == "Модифицированный метод":
strResult += (
"[" + str(cm.modified_newtons_method(aim.f, aim.f_d, a, b)) + "] "
)
strSection += f" ({a}, {b}) "
elif method == "Комбинированный метод":
strResult += "[" + str(cm.combined_method(aim.f, aim.f_d, a, b)) + "] "
strSection += f" ({a}, {b}) "
elif method == "Итерационный метод":
strResult += "[" + str(cm.iterative_method(aim.f, aim.f_d, a, b)) + "] "
strSection += f" ({a}, {b}) "
self.line_edit_section.setText(strSection)
self.line_edit_result.setText(strResult)
solution_range.clear()
def plotGraph(self):
x = np.linspace(-10, 10, 400)
y = x**3 - 10 * x + 2
ax = self.canvas.figure.subplots()
ax.plot(x, y, label="$x^3 - 10x + 2$", color="b")
# Добавляем оси axis
ax.spines["left"].set_position(("data", 0))
ax.spines["bottom"].set_position(("data", 0))
ax.spines["right"].set_color("none")
ax.spines["top"].set_color("none")
ax.yaxis.set_ticks_position("left")
ax.xaxis.set_ticks_position("bottom")
# Добавляем точки на оси x и их значения
x_intercepts = x[np.where(np.diff(np.signbit(y)))[0]]
for x_intercept in x_intercepts:
ax.plot(x_intercept, 0, "ro") # добавляем красную точку
ax.annotate(
f"x={x_intercept:.2f}", (x_intercept, 0.5), color="r"
) # добавляем значение x
# Ограничиваем график по оси y до 15
ax.set_ylim(-15, 15)
ax.set_title("График уравнения")
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.grid(True)
ax.legend()
self.canvas.draw()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Form()
form.show()
sys.exit(app.exec())

View File

@@ -0,0 +1,26 @@
import sympy
func_str = "x ** 3 - 10 * x + 2"
func = sympy.sympify(func_str)
func_d = sympy.diff(func)
func_dd = sympy.diff(func_d)
func_l = sympy.lambdify("x", func, "numpy")
func_d_l = sympy.lambdify("x", func_d, "numpy")
func_dd_l = sympy.lambdify("x", func_dd, "numpy")
def f_str():
return func_str
def f(x):
return func_l(x)
def f_d(x):
return func_d_l(x)
def f_dd(x):
return func_dd_l(x)

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -0,0 +1,77 @@
def half_div_method(f, f_d, a, b, max_iter=10_000, eps=0.00001):
x_n = (a + b) / 2
i = 0
while abs(f(x_n)) >= eps and i < max_iter:
x_n = (a + b) / 2
f_ = f(x_n)
if f_ == 0:
break
if f(a) * f_ < 0:
b = x_n
else:
a = x_n
i += 1
return x_n
def chord_method(f, f_d, f_dd, a, b, max_iter=1_000_000, eps=0.01):
x_n = (a + b) / 2
i = 0
while abs(f(x_n)) >= eps and i < max_iter:
X = a
if f(X) * f_dd(X) <= 0:
X = b
if f(X) * f_dd(X) <= 0:
return None
x_n = x_n - f(x_n) * (X - x_n) / (f(X) - f(x_n))
i += 1
return x_n
def newtons_method(f, f_d, a, b, max_iter=10_000, eps=0.00001):
x_n = a
i = 0
while abs(f(x_n)) >= eps and i < max_iter:
x_n = x_n - f(x_n) / f_d(x_n)
i += 1
return x_n
def modified_newtons_method(f, f_d, a, b, max_iter=1_000_000, eps=0.01):
x_n = a
f_d_0 = f_d(x_n)
i = 0
while abs(f(x_n)) >= eps and i < max_iter:
x_n = x_n - f(x_n) / f_d_0
i += 1
return x_n
def combined_method(f, f_d, a, b, max_iter=10_000, eps=0.00001):
x_n = a
y_n = b
i = 0
while abs(x_n - y_n) >= eps and i < max_iter:
x_n = x_n - f(x_n) / f_d(x_n)
y_n = y_n - f(y_n) * (x_n - y_n) / (f(x_n) - f(y_n))
i += 1
return (x_n + y_n) / 2
def iterative_method(f, f_d, a, b, max_iter=10_000, eps=0.0001):
def phi(x):
return x - f(x) / f_d(x)
i = 0
x = phi(a)
while abs(f(x)) >= eps and i < max_iter:
x = phi(x)
i += 1
return x