my final form!!!
This commit is contained in:
10
Л3-В6/Программа/example.txt
Normal file
10
Л3-В6/Программа/example.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# example 1
|
||||||
|
-1 11 -1 3 25
|
||||||
|
10 -1 2 0 6
|
||||||
|
2 -1 10 -1 -11
|
||||||
|
0 3 -1 8 15
|
||||||
|
|
||||||
|
# example 2
|
||||||
|
-1 11 -1 25
|
||||||
|
10 -1 2 6
|
||||||
|
2 -1 10 -11
|
||||||
@@ -1,63 +1,14 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
import sys
|
||||||
|
from PyQt6.QtWidgets import QApplication
|
||||||
|
from PyQt6.QtGui import QFont
|
||||||
|
|
||||||
import solution
|
import window
|
||||||
|
|
||||||
A = np.matrix(
|
if __name__ == "__main__":
|
||||||
[
|
app = QApplication(sys.argv)
|
||||||
[4.3, -12.1, 23.2, -14.1],
|
font = QFont("Cascadia Code", 14)
|
||||||
[2.4, -4.4, 3.5, 5.5],
|
app.setFont(font)
|
||||||
[5.4, 8.3, -7.4, -12.7],
|
window = window.MainWindow()
|
||||||
[6.3, -7.6, 1.34, 3.7],
|
window.show()
|
||||||
],
|
sys.exit(app.exec())
|
||||||
dtype=np.float64,
|
|
||||||
)
|
|
||||||
|
|
||||||
B = np.matrix([[15.5, 2.5, 8.6, 12.1]], dtype=np.float64).T
|
|
||||||
|
|
||||||
A = np.matrix(
|
|
||||||
[
|
|
||||||
[14.4, -5.3, 14.3, -12.7],
|
|
||||||
[23.4, -14.2, -5.4, 2.1],
|
|
||||||
[6.3, -13.2, -6.5, 14.3],
|
|
||||||
[5.6, 8.8, -6.7, -23.8],
|
|
||||||
],
|
|
||||||
dtype=np.float64,
|
|
||||||
)
|
|
||||||
|
|
||||||
B = np.matrix([[-14.4, 6.6, 9.4, 7.3]], dtype=np.float64).T
|
|
||||||
|
|
||||||
|
|
||||||
# A = np.matrix(
|
|
||||||
# [
|
|
||||||
# [-1, 11, -1, 3],
|
|
||||||
# [10, -1, 2, 0],
|
|
||||||
# [2, -1, 10, -1],
|
|
||||||
# [0, 3, -1, 8],
|
|
||||||
# ],
|
|
||||||
# dtype=np.float64,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# B = np.matrix([[25, 6, -11, 15]], dtype=np.float64).T
|
|
||||||
|
|
||||||
# print(algorithm.det(A))
|
|
||||||
# print(np.linalg.det(A))
|
|
||||||
|
|
||||||
# print(algorithm.norm(A))
|
|
||||||
# print(np.linalg.norm(A, ord=float("inf")))
|
|
||||||
|
|
||||||
# print(algorithm.cond(A))
|
|
||||||
# print(np.linalg.cond(A, p=float("inf")))
|
|
||||||
|
|
||||||
# koef = np.matrix([[1, 1, 1, 1]], dtype=np.float64)
|
|
||||||
# for i in range(A.shape[0]):
|
|
||||||
# A[i, :] *= koef[0, i]
|
|
||||||
# B[i, :] *= koef[0, i]
|
|
||||||
|
|
||||||
# print(A)
|
|
||||||
# print(algorithm.cond(A))
|
|
||||||
# print(B)
|
|
||||||
|
|
||||||
X = np.linalg.inv(A) * B
|
|
||||||
|
|
||||||
print(solution.iterative_method(A, B))
|
|
||||||
print(X)
|
|
||||||
|
|||||||
33
Л3-В6/Программа/src/task.py
Normal file
33
Л3-В6/Программа/src/task.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import numpy as np
|
||||||
|
|
||||||
|
_A = np.matrix(
|
||||||
|
[
|
||||||
|
[4.3, -12.1, 23.2, -14.1],
|
||||||
|
[2.4, -4.4, 3.5, 5.5],
|
||||||
|
[5.4, 8.3, -7.4, -12.7],
|
||||||
|
[6.3, -7.6, 1.34, 3.7],
|
||||||
|
],
|
||||||
|
dtype=np.float64,
|
||||||
|
)
|
||||||
|
|
||||||
|
_B = np.matrix([[15.5, 2.5, 8.6, 12.1]], dtype=np.float64).T
|
||||||
|
|
||||||
|
# _A = np.matrix(
|
||||||
|
# [
|
||||||
|
# [-1, 11, -1, 3],
|
||||||
|
# [10, -1, 2, 0],
|
||||||
|
# [2, -1, 10, -1],
|
||||||
|
# [0, 3, -1, 8],
|
||||||
|
# ],
|
||||||
|
# dtype=np.float64,
|
||||||
|
# )
|
||||||
|
|
||||||
|
# _B = np.matrix([[25, 6, -11, 15]], dtype=np.float64).T
|
||||||
|
|
||||||
|
|
||||||
|
def A() -> np.matrix:
|
||||||
|
return _A
|
||||||
|
|
||||||
|
|
||||||
|
def B() -> np.matrix:
|
||||||
|
return _B
|
||||||
384
Л3-В6/Программа/src/window.py
Normal file
384
Л3-В6/Программа/src/window.py
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
import sys
|
||||||
|
from PyQt6.QtWidgets import (
|
||||||
|
QMessageBox,
|
||||||
|
QMainWindow,
|
||||||
|
QLabel,
|
||||||
|
QComboBox,
|
||||||
|
QPushButton,
|
||||||
|
QFormLayout,
|
||||||
|
QWidget,
|
||||||
|
QLineEdit,
|
||||||
|
QHBoxLayout,
|
||||||
|
QLayout,
|
||||||
|
QApplication,
|
||||||
|
)
|
||||||
|
from PyQt6.QtCore import Qt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import task
|
||||||
|
import algorithm
|
||||||
|
import solution
|
||||||
|
|
||||||
|
|
||||||
|
class DisplayField(QWidget):
|
||||||
|
label_text: str
|
||||||
|
|
||||||
|
def __init__(self, parent, label_text="", text=""):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self._layout = QHBoxLayout(self)
|
||||||
|
self._layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
self.label_text = label_text
|
||||||
|
self.text = QLabel(f"{self.label_text}{text}")
|
||||||
|
self.text.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||||
|
|
||||||
|
self._layout.addWidget(self.text)
|
||||||
|
|
||||||
|
def set_visible(self, visible):
|
||||||
|
self.text.setVisible(visible)
|
||||||
|
|
||||||
|
def set_text(self, text):
|
||||||
|
self.text.setText(f"{self.label_text}{text}")
|
||||||
|
|
||||||
|
|
||||||
|
class InputField(QWidget):
|
||||||
|
value: str
|
||||||
|
change_func: callable = None
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent,
|
||||||
|
label_text="",
|
||||||
|
placeholder_text="",
|
||||||
|
lineedit_text="",
|
||||||
|
label_position="left",
|
||||||
|
):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self._layout = QHBoxLayout(self)
|
||||||
|
self._layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.label = QLabel(label_text)
|
||||||
|
self.lineedit = QLineEdit(lineedit_text)
|
||||||
|
self.lineedit.setPlaceholderText(placeholder_text)
|
||||||
|
self.lineedit.setMinimumWidth(50)
|
||||||
|
|
||||||
|
if label_position == "left":
|
||||||
|
self._layout.addWidget(self.label)
|
||||||
|
self._layout.addWidget(self.lineedit)
|
||||||
|
elif label_position == "right":
|
||||||
|
self._layout.addWidget(self.lineedit)
|
||||||
|
self._layout.addWidget(self.label)
|
||||||
|
elif label_position == "none":
|
||||||
|
self._layout.addWidget(self.lineedit)
|
||||||
|
|
||||||
|
self.value = self.get_value()
|
||||||
|
self.lineedit.textChanged.connect(self._on_change)
|
||||||
|
|
||||||
|
def get_value(self):
|
||||||
|
return self.lineedit.text()
|
||||||
|
|
||||||
|
def set_value(self, value):
|
||||||
|
self.lineedit.setText(value)
|
||||||
|
|
||||||
|
def on_change(self, func):
|
||||||
|
self.change_func = func
|
||||||
|
|
||||||
|
def _on_change(self):
|
||||||
|
if self.change_func:
|
||||||
|
self.change_func(self)
|
||||||
|
|
||||||
|
self.value = self.get_value()
|
||||||
|
|
||||||
|
|
||||||
|
def on_input_float_number(widget: InputField):
|
||||||
|
try:
|
||||||
|
str_value = widget.get_value()
|
||||||
|
if not (str_value == "" or str_value == "-"):
|
||||||
|
widget.value = str(float(str_value))
|
||||||
|
except:
|
||||||
|
widget.set_value(str(widget.value))
|
||||||
|
|
||||||
|
|
||||||
|
def on_input_int_number(widget: InputField):
|
||||||
|
try:
|
||||||
|
str_value = widget.get_value()
|
||||||
|
if not (str_value == "" or str_value == "-"):
|
||||||
|
widget.value = str(int(str_value))
|
||||||
|
except:
|
||||||
|
widget.set_value(str(widget.value))
|
||||||
|
|
||||||
|
|
||||||
|
class MatrixRowWidget(QWidget):
|
||||||
|
x_inputs: list[InputField]
|
||||||
|
b_input: InputField
|
||||||
|
|
||||||
|
def __init__(self, parent, i: int, n: int):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self._layout = QHBoxLayout()
|
||||||
|
self._layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.x_inputs = []
|
||||||
|
for j in range(n):
|
||||||
|
inp = InputField(self, f"x{j + 1}", "", "0.0", "right")
|
||||||
|
inp.lineedit.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||||
|
self.x_inputs.append(inp)
|
||||||
|
self._layout.addWidget(inp)
|
||||||
|
if j != n - 1:
|
||||||
|
self._layout.addWidget(QLabel(" + "))
|
||||||
|
|
||||||
|
self._layout.addWidget(QLabel(" = "))
|
||||||
|
self.b_input = InputField(self, "", "", "0.0", "none")
|
||||||
|
self.b_input.lineedit.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
self._layout.addWidget(self.b_input)
|
||||||
|
|
||||||
|
self.setLayout(self._layout)
|
||||||
|
|
||||||
|
def get_value_x(self, i: int):
|
||||||
|
return self.x_inputs[i].get_value()
|
||||||
|
|
||||||
|
def get_value_b(self):
|
||||||
|
return self.b_input.get_value()
|
||||||
|
|
||||||
|
def on_change(self, func):
|
||||||
|
for inp in self.x_inputs:
|
||||||
|
inp.on_change(func)
|
||||||
|
|
||||||
|
self.b_input.on_change(func)
|
||||||
|
|
||||||
|
|
||||||
|
class MatrixWidget(QWidget):
|
||||||
|
rows: list[MatrixRowWidget]
|
||||||
|
_layout: QFormLayout
|
||||||
|
on_change_func = None
|
||||||
|
|
||||||
|
def __init__(self, parent, n: int):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self._initialize()
|
||||||
|
self._create(n)
|
||||||
|
|
||||||
|
def _initialize(self):
|
||||||
|
self.rows = []
|
||||||
|
self._layout = QFormLayout()
|
||||||
|
self._layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
def _create(self, n: int):
|
||||||
|
for i in range(n):
|
||||||
|
self.rows.append(MatrixRowWidget(self, i, n))
|
||||||
|
|
||||||
|
for row in self.rows:
|
||||||
|
self._layout.addRow(row)
|
||||||
|
if self.on_change_func:
|
||||||
|
row.on_change(self.on_change_func)
|
||||||
|
|
||||||
|
self.setLayout(self._layout)
|
||||||
|
|
||||||
|
def recreate(self, n: int):
|
||||||
|
for row in self.rows:
|
||||||
|
row.deleteLater()
|
||||||
|
|
||||||
|
self.rows = []
|
||||||
|
self._create(n)
|
||||||
|
|
||||||
|
def set_value_x(self, i: int, j: int, value: float):
|
||||||
|
self.rows[i].x_inputs[j].set_value(value)
|
||||||
|
|
||||||
|
def set_value_b(self, i: int, value: float):
|
||||||
|
self.rows[i].b_input.set_value(value)
|
||||||
|
|
||||||
|
def get_value_x(self, i: int, j: int):
|
||||||
|
return self.rows[i].get_value_x(j)
|
||||||
|
|
||||||
|
def get_value_b(self, i: int):
|
||||||
|
return self.rows[i].get_value_b()
|
||||||
|
|
||||||
|
def on_change(self, func):
|
||||||
|
self.on_change_func = func
|
||||||
|
|
||||||
|
for row in self.rows:
|
||||||
|
if self.on_change_func:
|
||||||
|
row.on_change(self.on_change_func)
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow(QMainWindow):
|
||||||
|
initialized = False
|
||||||
|
|
||||||
|
matrix_a: np.matrix
|
||||||
|
matrix_b: np.matrix
|
||||||
|
|
||||||
|
det_display: DisplayField
|
||||||
|
cond_display: DisplayField
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.setupUI()
|
||||||
|
|
||||||
|
self.initialized = True
|
||||||
|
self.update_stats()
|
||||||
|
|
||||||
|
def setupUI(self):
|
||||||
|
self.setWindowTitle("Лабораторная работа №3")
|
||||||
|
self.central_widget = QWidget()
|
||||||
|
self.setCentralWidget(self.central_widget)
|
||||||
|
|
||||||
|
layout = QFormLayout()
|
||||||
|
|
||||||
|
label1 = QLabel("Вариант 6", self)
|
||||||
|
layout.addWidget(label1)
|
||||||
|
|
||||||
|
self.n_input = InputField(self, " n: ", "число строк", str(4), "left")
|
||||||
|
self.n_input.on_change(lambda w: self.on_n_input_changed(w))
|
||||||
|
layout.addWidget(self.n_input)
|
||||||
|
|
||||||
|
buttons_row = QWidget()
|
||||||
|
buttons_row_layout = QHBoxLayout()
|
||||||
|
buttons_row_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
self.reset_button = QPushButton("Сбросить", self)
|
||||||
|
self.reset_button.clicked.connect(self.on_reset_button_clicked)
|
||||||
|
buttons_row_layout.addWidget(self.reset_button)
|
||||||
|
|
||||||
|
self.paste_button = QPushButton("Вставить", self)
|
||||||
|
self.paste_button.clicked.connect(self.on_paste_button_clicked)
|
||||||
|
buttons_row_layout.addWidget(self.paste_button)
|
||||||
|
|
||||||
|
buttons_row.setLayout(buttons_row_layout)
|
||||||
|
layout.addWidget(buttons_row)
|
||||||
|
|
||||||
|
self.matrix = MatrixWidget(self, 4)
|
||||||
|
self.matrix.on_change(lambda w: self.on_matrix_changed(w))
|
||||||
|
self.set_matrix(task.A(), task.B())
|
||||||
|
layout.addWidget(self.matrix)
|
||||||
|
|
||||||
|
self.det_display = DisplayField(self, "Определитель: ", "")
|
||||||
|
layout.addWidget(self.det_display)
|
||||||
|
|
||||||
|
self.cond_display = DisplayField(self, "Число обусловленности: ", "")
|
||||||
|
layout.addWidget(self.cond_display)
|
||||||
|
|
||||||
|
find_solution_button = QPushButton("Решить", self)
|
||||||
|
find_solution_button.clicked.connect(self.on_find_solution_clicked)
|
||||||
|
layout.addWidget(find_solution_button)
|
||||||
|
|
||||||
|
self.solution_display = DisplayField(self, "Решение: ", "")
|
||||||
|
layout.addWidget(self.solution_display)
|
||||||
|
self.solution_display.set_visible(False)
|
||||||
|
|
||||||
|
self.central_widget.setLayout(layout)
|
||||||
|
|
||||||
|
def on_find_solution_clicked(self):
|
||||||
|
x = solution.iterative_method(self.matrix_a, self.matrix_b)
|
||||||
|
|
||||||
|
if x is None:
|
||||||
|
self.solution_display.set_visible(True)
|
||||||
|
self.solution_display.set_text("Нет решения")
|
||||||
|
else:
|
||||||
|
self.solution_display.set_visible(True)
|
||||||
|
solution_text = "\n"
|
||||||
|
for i in range(x.shape[0]):
|
||||||
|
solution_text += f"x{i} = {x[i, 0]:.5f}"
|
||||||
|
if i < x.shape[0] - 1:
|
||||||
|
solution_text += "\n"
|
||||||
|
self.solution_display.set_text(solution_text)
|
||||||
|
|
||||||
|
def on_paste_button_clicked(self):
|
||||||
|
text = QApplication.clipboard().text()
|
||||||
|
try:
|
||||||
|
input_np = np.fromstring(text, dtype=np.float64, sep=" ")
|
||||||
|
|
||||||
|
n = 0.5 * (np.sqrt(4.0 * input_np.shape[0] + 1.0) - 1.0)
|
||||||
|
if n % 1.0 != 0.0:
|
||||||
|
return
|
||||||
|
n = int(n)
|
||||||
|
|
||||||
|
input_np = np.reshape(input_np, (n, n + 1))
|
||||||
|
|
||||||
|
self.n_input.set_value(str(n))
|
||||||
|
|
||||||
|
self.matrix_a = np.copy(input_np[:n, :n])
|
||||||
|
self.matrix_b = np.copy(input_np[:n, n:])
|
||||||
|
|
||||||
|
self.set_matrix(self.matrix_a, self.matrix_b)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_n_input_changed(self, widget: InputField):
|
||||||
|
MAX_N = 8
|
||||||
|
|
||||||
|
on_input_int_number(widget)
|
||||||
|
try:
|
||||||
|
n = int(widget.get_value())
|
||||||
|
if n < 1:
|
||||||
|
widget.set_value(str(1))
|
||||||
|
return
|
||||||
|
if n > MAX_N:
|
||||||
|
widget.set_value(str(MAX_N))
|
||||||
|
return
|
||||||
|
|
||||||
|
self.matrix.recreate(int(self.n_input.get_value()))
|
||||||
|
self.input_matrix_from_widget()
|
||||||
|
self.update_stats()
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_reset_button_clicked(self):
|
||||||
|
self.n_input.set_value(str(4))
|
||||||
|
self.set_matrix(task.A(), task.B())
|
||||||
|
|
||||||
|
def on_matrix_changed(self, widget: InputField):
|
||||||
|
on_input_float_number(widget)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.input_matrix_from_widget()
|
||||||
|
self.update_stats()
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
def input_matrix_from_widget(self):
|
||||||
|
try:
|
||||||
|
self.matrix_a = np.matrix(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
self.matrix.get_value_x(i, j)
|
||||||
|
for j in range(self.matrix.rows[0].x_inputs.__len__())
|
||||||
|
]
|
||||||
|
for i in range(self.matrix.rows.__len__())
|
||||||
|
],
|
||||||
|
dtype=np.float64,
|
||||||
|
)
|
||||||
|
self.matrix_b = np.matrix(
|
||||||
|
[
|
||||||
|
[self.matrix.get_value_b(i)]
|
||||||
|
for i in range(self.matrix.rows.__len__())
|
||||||
|
],
|
||||||
|
dtype=np.float64,
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
def update_stats(self):
|
||||||
|
if not self.initialized:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.solution_display.set_visible(False)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.det_display.set_text(f"{algorithm.det(self.matrix_a):.5f}")
|
||||||
|
self.cond_display.set_text(f"{algorithm.cond(self.matrix_a):.5f}")
|
||||||
|
except:
|
||||||
|
self.det_display.set_text("Невозможно вычислить")
|
||||||
|
self.cond_display.set_text("Невозможно вычислить")
|
||||||
|
|
||||||
|
def set_matrix(self, A: np.matrix, B: np.matrix):
|
||||||
|
for i in range(A.shape[0]):
|
||||||
|
for j in range(A.shape[1]):
|
||||||
|
self.matrix.set_value_x(i, j, str(A[i, j]))
|
||||||
|
|
||||||
|
for i in range(B.shape[0]):
|
||||||
|
self.matrix.set_value_b(i, str(B[i, 0]))
|
||||||
|
|
||||||
|
self.update_stats()
|
||||||
Reference in New Issue
Block a user