206 lines
7.8 KiB
Python
206 lines
7.8 KiB
Python
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())
|