mirror of
https://github.com/shizand/statapp.git
synced 2025-10-01 19:29:08 +03:00
133
statapp/_vendor/multipolyfit.py
Normal file
133
statapp/_vendor/multipolyfit.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# Copyright (c) 2023 Matthew Rocklin
|
||||
# All rights reserved.
|
||||
# This source code is distributed under the terms of the BSD license,
|
||||
# which allows you to use, modify, and distribute it
|
||||
# as long as you comply with the license terms.
|
||||
|
||||
# In addition, this code has been modified by Maxim Slipenko and
|
||||
# is now also licensed under the GPL-3.0.
|
||||
# See the GPL-3.0 license for details.
|
||||
|
||||
import itertools
|
||||
import numpy as np
|
||||
from numpy import linalg, zeros, ones, hstack, asarray, diagonal
|
||||
from sympy import symbols, Mul, Add, S
|
||||
|
||||
|
||||
def basisVector(n, i):
|
||||
""" Return an array like [0, 0, ..., 1, ..., 0, 0]
|
||||
|
||||
>>> from statapp._vendor.multipolyfit import basisVector
|
||||
>>> basis_vector(3, 1)
|
||||
array([0, 1, 0])
|
||||
>>> basisVector(5, 4)
|
||||
array([0, 0, 0, 0, 1])
|
||||
"""
|
||||
x = zeros(n, dtype=int)
|
||||
x[i] = 1
|
||||
return x
|
||||
|
||||
|
||||
def asTall(x):
|
||||
""" Turns a row vector into a column vector """
|
||||
return x.reshape(x.shape + (1,))
|
||||
|
||||
|
||||
def multipolyfit(xs, y, deg, full=False, modelOut=False, powersOut=False):
|
||||
# pylint: disable-msg=too-many-locals
|
||||
"""
|
||||
Least squares multivariate polynomial fit
|
||||
|
||||
Fit a polynomial like ``y = a**2 + 3a - 2ab + 4b**2 - 1``
|
||||
with many covariates a, b, c, ...
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
xs : array_like, shape (M, k)
|
||||
x-coordinates of the k covariates over the M sample points
|
||||
y : array_like, shape(M,)
|
||||
y-coordinates of the sample points.
|
||||
deg : int
|
||||
Degree o fthe fitting polynomial
|
||||
modelOut : bool (defaults to True)
|
||||
If True return a callable function
|
||||
If False return an array of coefficients
|
||||
powersOut : bool (defaults to False)
|
||||
Returns the meaning of each of the coefficients in the form of an
|
||||
iterator that gives the powers over the inputs and 1
|
||||
For example if xs corresponds to the covariates a,b,c then the array
|
||||
[1, 2, 1, 0] corresponds to 1**1 * a**2 * b**1 * c**0
|
||||
|
||||
See Also
|
||||
--------
|
||||
numpy.polyfit
|
||||
|
||||
"""
|
||||
# pylin
|
||||
y = asarray(y).squeeze()
|
||||
# rows = y.shape[0]
|
||||
xs = asarray(xs)
|
||||
numCovariates = xs.shape[1]
|
||||
xs = hstack((ones((xs.shape[0], 1), dtype=xs.dtype) , xs))
|
||||
|
||||
generators = [basisVector(numCovariates + 1, i)
|
||||
for i in range(numCovariates+1)]
|
||||
|
||||
# All combinations of degrees
|
||||
powers = [sum(x) for x in itertools.combinations_with_replacement(generators, deg)]
|
||||
|
||||
# Raise data to specified degree pattern, stack in order
|
||||
a = hstack(asarray([asTall((xs ** p).prod(1)) for p in powers]))
|
||||
|
||||
result = linalg.lstsq(a, y, rcond=None)
|
||||
beta = result[0]
|
||||
|
||||
if modelOut:
|
||||
return mkModel(beta, powers)
|
||||
|
||||
if powersOut:
|
||||
return beta, powers
|
||||
|
||||
if full:
|
||||
residues = result[1]
|
||||
dof = len(a) - len(beta)
|
||||
|
||||
mse = residues / dof
|
||||
cov = mse * diagonal(linalg.inv(a.T @ a))
|
||||
se = np.sqrt(cov)
|
||||
tStatistics = beta / se
|
||||
|
||||
return result, powers, tStatistics, mse
|
||||
|
||||
return beta
|
||||
|
||||
|
||||
def mkModel(beta, powers):
|
||||
""" Create a callable python function out of beta/powers from multipolyfit
|
||||
|
||||
This function is callable from within multipolyfit using the model_out flag
|
||||
"""
|
||||
# Create a function that takes in many x values
|
||||
# and returns an approximate y value
|
||||
def model(*args):
|
||||
numCovariates = len(powers[0]) - 1
|
||||
if len(args) != numCovariates:
|
||||
raise ValueError(f"Expected {numCovariates} inputs")
|
||||
xs = asarray((1,) + args)
|
||||
return sum(coeff * (xs**p).prod()
|
||||
for p, coeff in zip(powers, beta))
|
||||
return model
|
||||
|
||||
|
||||
def mkSympyFunction(beta, powers):
|
||||
terms = getTerms(powers)
|
||||
return Add(*[coeff * term for term, coeff in zip(terms, beta)])
|
||||
|
||||
|
||||
def getTerms(powers):
|
||||
numCovariates = len(powers[0])
|
||||
xs = (S.One,) + symbols(f'x1:{numCovariates}')
|
||||
|
||||
terms = [Mul(*[x ** deg for x, deg in zip(xs, power)]) for power in powers]
|
||||
return terms
|
@@ -21,6 +21,7 @@ from dataclasses import dataclass
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from statapp._vendor.multipolyfit import multipolyfit, getTerms
|
||||
|
||||
DIRECT_LINK = 0
|
||||
INDIRECT_LINK = 1
|
||||
@@ -58,13 +59,21 @@ def varianceAnalysis(data):
|
||||
def correlationAnalysis(data):
|
||||
return pd.DataFrame(data).corr().to_numpy()
|
||||
|
||||
|
||||
@dataclass()
|
||||
class LinearPolynomResult:
|
||||
class RegressionResult:
|
||||
"""
|
||||
Attributes:
|
||||
paramsAndImportance (np.ndarray): Параметры модели. Первая колонка -
|
||||
residualVariance (np.float64): Остаточная дисперсия
|
||||
monomials (list): Список одночленов в строковом виде без коэффициентов. Свободный член - c
|
||||
"""
|
||||
paramsAndImportance: np.ndarray
|
||||
residualVariance: np.float64
|
||||
monomials: list
|
||||
|
||||
|
||||
def linearPolynom(inputData) -> LinearPolynomResult:
|
||||
def linearPolynom(inputData) -> RegressionResult:
|
||||
x = inputData[:, 1:]
|
||||
y = inputData[:, 0]
|
||||
data = pd.DataFrame(x)
|
||||
@@ -75,8 +84,6 @@ def linearPolynom(inputData) -> LinearPolynomResult:
|
||||
params = result[0]
|
||||
# Остатки
|
||||
residues = result[1]
|
||||
|
||||
# Степень свободы
|
||||
dof = len(data) - len(params)
|
||||
mse = residues / dof
|
||||
cov = mse * np.diagonal(np.linalg.inv(data.T @ data))
|
||||
@@ -88,7 +95,25 @@ def linearPolynom(inputData) -> LinearPolynomResult:
|
||||
out[0] = params
|
||||
out[1] = tStatistics
|
||||
|
||||
return LinearPolynomResult(
|
||||
return RegressionResult(
|
||||
out.to_numpy(),
|
||||
np.float64(mse[0])
|
||||
np.float64(mse[0]),
|
||||
['c'] + [f'x{i}' for i in range(1, len(params))]
|
||||
)
|
||||
|
||||
|
||||
def squaredPolynom(inputData):
|
||||
x = inputData[:, 1:]
|
||||
y = inputData[:, 0]
|
||||
result, powers, tStatistics, mse = multipolyfit(x, y, 2, full=True)
|
||||
betas = result[0]
|
||||
|
||||
out = pd.DataFrame()
|
||||
out[0] = betas
|
||||
out[1] = tStatistics
|
||||
|
||||
return RegressionResult(
|
||||
out.to_numpy(),
|
||||
np.float64(mse[0]),
|
||||
['c' if str(x) == '1' else str(x) for x in getTerms(powers)]
|
||||
)
|
||||
|
@@ -17,11 +17,13 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from PySide2 import QtCore
|
||||
from PySide2.QtCore import QSize
|
||||
from PySide2.QtGui import QIcon
|
||||
from PySide2.QtWidgets import QDialog, QHeaderView
|
||||
|
||||
from statapp.calculations import correlationAnalysis
|
||||
from statapp.mathtex_header_view import MathTexHeaderView
|
||||
from statapp.models.correlation_analysis_model import CorrelationAnalysisModel
|
||||
from statapp.ui.ui_correlation_analysis_window import Ui_CorrelationAnalysisWindow
|
||||
from statapp.utils import resourcePath
|
||||
@@ -36,6 +38,12 @@ class CorrelationAnalysisWindow(QDialog):
|
||||
res = correlationAnalysis(data)
|
||||
self.model = CorrelationAnalysisModel(res.round(2))
|
||||
self.ui.tableView.setModel(self.model)
|
||||
self.ui.tableView.setVerticalHeader(
|
||||
MathTexHeaderView(self.ui.tableView)
|
||||
)
|
||||
self.ui.tableView.setHorizontalHeader(
|
||||
MathTexHeaderView(self.ui.tableView,orientation=QtCore.Qt.Horizontal)
|
||||
)
|
||||
header = self.ui.tableView.horizontalHeader()
|
||||
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
||||
|
||||
|
@@ -20,7 +20,8 @@
|
||||
from PySide2.QtWidgets import QDialog, QHeaderView
|
||||
|
||||
from statapp.calculations import linearPolynom
|
||||
from statapp.models.linear_polynom_model import LinearPolynomModel
|
||||
from statapp.mathtex_header_view import MathTexHeaderView
|
||||
from statapp.models.regression_result_model import RegressionResultModel
|
||||
from statapp.ui.ui_linear_polynom_window import Ui_LinearPolynomWindow
|
||||
from statapp.utils import addIcon
|
||||
|
||||
@@ -34,8 +35,9 @@ class LinearPolynomWindow(QDialog):
|
||||
|
||||
result = linearPolynom(data)
|
||||
|
||||
self.model = LinearPolynomModel(result.paramsAndImportance.round(2))
|
||||
self.model = RegressionResultModel(result)
|
||||
self.ui.tableView.setModel(self.model)
|
||||
self.ui.tableView.setVerticalHeader(MathTexHeaderView(self.ui.tableView))
|
||||
header = self.ui.tableView.horizontalHeader()
|
||||
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
||||
|
||||
|
@@ -18,16 +18,19 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import numpy as np
|
||||
from PySide2 import QtCore
|
||||
from PySide2.QtCore import Slot
|
||||
from PySide2.QtWidgets import QMainWindow, QMessageBox
|
||||
|
||||
from statapp.calculations import generateXValues, generateYValues
|
||||
from statapp.generate_factor_window import GenerateFactorWindow
|
||||
from statapp.linear_polynom_window import LinearPolynomWindow
|
||||
from statapp.mathtex_header_view import MathTexHeaderView
|
||||
from statapp.models.input_values_model import InputValuesModel
|
||||
from statapp.generate_window import GenerateWindow
|
||||
from statapp.about_window import AboutWindow
|
||||
from statapp.models.fileslc_model import FileSLCModel
|
||||
from statapp.squared_polynom_window import SquaredPolynomWindow
|
||||
from statapp.ui.ui_main_window import Ui_MainWindow
|
||||
from statapp.utils import buildMessageBox, addIcon
|
||||
from statapp.variance_analysis import VarianceAnalysisWindow
|
||||
@@ -51,6 +54,7 @@ class MainWindow(QMainWindow):
|
||||
self.ui.varianceAnalysisAction,
|
||||
self.ui.correlationAnalisisAction,
|
||||
self.ui.linearPolynomAction,
|
||||
self.ui.squaredPolynomAction,
|
||||
]
|
||||
|
||||
self.aboutWindow = None
|
||||
@@ -59,15 +63,18 @@ class MainWindow(QMainWindow):
|
||||
self.model = InputValuesModel()
|
||||
self.fileModel = FileSLCModel()
|
||||
self.ui.tableView.setModel(self.model)
|
||||
self.ui.tableView.setHorizontalHeader(
|
||||
MathTexHeaderView(self.ui.tableView, orientation=QtCore.Qt.Horizontal)
|
||||
)
|
||||
self.model.layoutChanged.connect(self.updateActionsEnabled)
|
||||
self.updateActionsEnabled()
|
||||
#
|
||||
# Для быстрой отладки
|
||||
# n = 10
|
||||
# y = generateYValues(100, 5, n)
|
||||
# x1 = generateXValues(20, 2, 0, y)
|
||||
# x2 = generateXValues(10, 1, 0, y)
|
||||
# self.model.updateAllData(np.concatenate([y, x1, x2], axis=1))
|
||||
n = 10
|
||||
y = generateYValues(100, 5, n)
|
||||
x1 = generateXValues(20, 2, 0, y)
|
||||
x2 = generateXValues(10, 1, 0, y)
|
||||
self.model.updateAllData(np.concatenate([y, x1, x2], axis=1))
|
||||
|
||||
|
||||
def updateActionsEnabled(self):
|
||||
@@ -178,6 +185,11 @@ class MainWindow(QMainWindow):
|
||||
dw = LinearPolynomWindow(self.model.getData())
|
||||
dw.exec()
|
||||
|
||||
@Slot()
|
||||
def on_squaredPolynomAction_triggered(self):
|
||||
dw = SquaredPolynomWindow(self.model.getData())
|
||||
dw.exec()
|
||||
|
||||
def closeEvent(self, event):
|
||||
if self.isDataChanged:
|
||||
file = ''
|
||||
|
107
statapp/mathtex_header_view.py
Normal file
107
statapp/mathtex_header_view.py
Normal file
@@ -0,0 +1,107 @@
|
||||
#
|
||||
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
|
||||
#
|
||||
# This file is part of Statapp
|
||||
# (see https://github.com/shizand/statapp).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib as mpl
|
||||
import sympy
|
||||
from PySide2 import QtCore, QtGui
|
||||
from PySide2.QtCore import Qt
|
||||
from PySide2.QtWidgets import QHeaderView, QStyleOptionHeader, QStyle
|
||||
from matplotlib.backends.backend_agg import FigureCanvasAgg
|
||||
|
||||
# Основано на https://stackoverflow.com/questions/32035251/
|
||||
|
||||
plt.rc('mathtext', fontset='cm')
|
||||
|
||||
|
||||
def mathTexToQPixMap(mathTex, fs):
|
||||
# ---- set up a mpl figure instance ----
|
||||
fig = mpl.figure.Figure()
|
||||
fig.patch.set_facecolor('none')
|
||||
fig.set_canvas(FigureCanvasAgg(fig))
|
||||
renderer = fig.canvas.get_renderer()
|
||||
# ---- plot the mathTex expression ----
|
||||
ax = fig.add_axes([0, 0, 1, 1])
|
||||
ax.axis('off')
|
||||
ax.patch.set_facecolor('none')
|
||||
t = ax.text(0, 0, f'${mathTex}$', ha='left', va='bottom', fontsize=fs)
|
||||
# ---- fit figure size to text artist ----
|
||||
fWidth, fHeight = fig.get_size_inches()
|
||||
figBBox = fig.get_window_extent(renderer)
|
||||
textBBox = t.get_window_extent(renderer)
|
||||
tightFWidth = textBBox.width * fWidth / figBBox.width
|
||||
tightFHeight = textBBox.height * fHeight / figBBox.height
|
||||
fig.set_size_inches(tightFWidth, tightFHeight)
|
||||
# ---- convert mpl figure to QPixmap ----
|
||||
buf, size = fig.canvas.print_to_buffer()
|
||||
|
||||
return QtGui.QPixmap(
|
||||
QtGui.QImage.rgbSwapped(
|
||||
QtGui.QImage(
|
||||
buf, size[0], size[1], QtGui.QImage.Format_ARGB32
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class CacheQPixMap(dict):
|
||||
def get(self, __key):
|
||||
v = super().get(__key)
|
||||
if v is None:
|
||||
v = mathTexToQPixMap(sympy.latex(sympy.sympify(__key)), 14)
|
||||
super().__setitem__(__key, v)
|
||||
return v
|
||||
|
||||
|
||||
class MathTexHeaderView(QHeaderView):
|
||||
def __init__(self, view, orientation=QtCore.Qt.Vertical):
|
||||
super().__init__(orientation, view)
|
||||
|
||||
if orientation == QtCore.Qt.Vertical:
|
||||
self.setStyleSheet(
|
||||
"QHeaderView::section { padding-left: 15px; padding-right: 15px }"
|
||||
)
|
||||
|
||||
self.converter = CacheQPixMap()
|
||||
|
||||
def paintSection(self, painter, rect, logicalIndex):
|
||||
opt = QStyleOptionHeader()
|
||||
self.initStyleOption(opt)
|
||||
|
||||
opt.rect = rect
|
||||
opt.section = logicalIndex
|
||||
opt.text = ""
|
||||
|
||||
mousePos = self.mapFromGlobal(QtGui.QCursor.pos())
|
||||
if rect.contains(mousePos):
|
||||
opt.state |= QStyle.State_MouseOver
|
||||
|
||||
painter.save()
|
||||
self.style().drawControl(QStyle.CE_Header, opt, painter, self)
|
||||
painter.restore()
|
||||
|
||||
data = self.model().headerData(logicalIndex, self.orientation(), Qt.DisplayRole)
|
||||
|
||||
if data:
|
||||
qPixMap = self.converter.get(data)
|
||||
xPix = (rect.width() - qPixMap.size().width()) / 2. + rect.x()
|
||||
yPix = (rect.height() - qPixMap.size().height()) / 2. + rect.y()
|
||||
rect = QtCore.QRect(xPix, yPix, qPixMap.size().width(),
|
||||
qPixMap.size().height())
|
||||
painter.drawPixmap(rect, qPixMap)
|
@@ -17,15 +17,18 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from PySide2.QtCore import QModelIndex
|
||||
|
||||
from statapp.calculations import RegressionResult
|
||||
from statapp.models.ro_table_model import ROTableModel
|
||||
|
||||
|
||||
class LinearPolynomModel(ROTableModel):
|
||||
class RegressionResultModel(ROTableModel):
|
||||
def __init__(self, result: RegressionResult):
|
||||
data = result.paramsAndImportance
|
||||
super().__init__(data)
|
||||
self._monomials = result.monomials
|
||||
|
||||
def getHorizontalHeader(self):
|
||||
return ['Коэффициент регрессии', 'Коэффициент значимости']
|
||||
|
||||
def getVerticalHeader(self):
|
||||
count = (self.rowCount(QModelIndex()))
|
||||
return ['Свободный член'] + [f'X{i}' for i in range(1, count)]
|
||||
return self._monomials
|
@@ -18,4 +18,4 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
def yxHeader(count):
|
||||
return ['Y'] + [f'X{i}' for i in range(1, count)]
|
||||
return ['y'] + [f'x{i}' for i in range(1, count)]
|
||||
|
44
statapp/squared_polynom_window.py
Normal file
44
statapp/squared_polynom_window.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
|
||||
#
|
||||
# This file is part of Statapp
|
||||
# (see https://github.com/shizand/statapp).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from PySide2.QtWidgets import QDialog, QHeaderView
|
||||
|
||||
from statapp.calculations import squaredPolynom
|
||||
from statapp.mathtex_header_view import MathTexHeaderView
|
||||
from statapp.models.regression_result_model import RegressionResultModel
|
||||
from statapp.ui.ui_squared_polynom_window import Ui_SquaredPolynomWindow
|
||||
from statapp.utils import addIcon
|
||||
|
||||
|
||||
class SquaredPolynomWindow(QDialog):
|
||||
def __init__(self, data):
|
||||
super().__init__()
|
||||
self.ui = Ui_SquaredPolynomWindow()
|
||||
self.ui.setupUi(self)
|
||||
addIcon(self)
|
||||
|
||||
result = squaredPolynom(data)
|
||||
|
||||
self.model = RegressionResultModel(result)
|
||||
self.ui.tableView.setModel(self.model)
|
||||
self.ui.tableView.setVerticalHeader(MathTexHeaderView(self.ui.tableView))
|
||||
header = self.ui.tableView.horizontalHeader()
|
||||
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
||||
|
||||
self.ui.residualVarianceValueLabel.setText(str(result.residualVariance))
|
@@ -17,7 +17,17 @@
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableView" name="tableView"/>
|
||||
<widget class="QTableView" name="tableView">
|
||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||
<number>40</number>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderMinimumSectionSize">
|
||||
<number>40</number>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>40</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
|
@@ -70,6 +70,7 @@
|
||||
<string>Моделирование</string>
|
||||
</property>
|
||||
<addaction name="linearPolynomAction"/>
|
||||
<addaction name="squaredPolynomAction"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="helpmenu">
|
||||
<property name="title">
|
||||
@@ -129,6 +130,11 @@
|
||||
<string>Линейный полином</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="squaredPolynomAction">
|
||||
<property name="text">
|
||||
<string>Квадратичный полином</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
49
statapp/ui/squared_polynom_window.ui
Normal file
49
statapp/ui/squared_polynom_window.ui
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SquaredPolynomWindow</class>
|
||||
<widget class="QDialog" name="SquaredPolynomWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>630</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Квадратичный полином</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableView" name="tableView"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="residualVarianceLabel">
|
||||
<property name="text">
|
||||
<string>Остаточная дисперсия:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="residualVarianceValueLabel">
|
||||
<property name="text">
|
||||
<string>undefined</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
3
statapp/ui/ui_linear_polynom_window.py
generated
3
statapp/ui/ui_linear_polynom_window.py
generated
@@ -44,6 +44,9 @@ class Ui_LinearPolynomWindow(object):
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.tableView = QTableView(LinearPolynomWindow)
|
||||
self.tableView.setObjectName(u"tableView")
|
||||
self.tableView.horizontalHeader().setMinimumSectionSize(40)
|
||||
self.tableView.verticalHeader().setMinimumSectionSize(40)
|
||||
self.tableView.verticalHeader().setDefaultSectionSize(40)
|
||||
|
||||
self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
|
||||
|
||||
|
4
statapp/ui/ui_main_window.py
generated
4
statapp/ui/ui_main_window.py
generated
@@ -56,6 +56,8 @@ class Ui_MainWindow(object):
|
||||
self.correlationAnalisisAction.setObjectName(u"correlationAnalisisAction")
|
||||
self.linearPolynomAction = QAction(MainWindow)
|
||||
self.linearPolynomAction.setObjectName(u"linearPolynomAction")
|
||||
self.squaredPolynomAction = QAction(MainWindow)
|
||||
self.squaredPolynomAction.setObjectName(u"squaredPolynomAction")
|
||||
self.centralwidget = QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
@@ -104,6 +106,7 @@ class Ui_MainWindow(object):
|
||||
self.analyzemenu.addAction(self.varianceAnalysisAction)
|
||||
self.analyzemenu.addAction(self.correlationAnalisisAction)
|
||||
self.modelmenu.addAction(self.linearPolynomAction)
|
||||
self.modelmenu.addAction(self.squaredPolynomAction)
|
||||
self.helpmenu.addAction(self.aboutmenuaction)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
@@ -122,6 +125,7 @@ class Ui_MainWindow(object):
|
||||
self.varianceAnalysisAction.setText(QCoreApplication.translate("MainWindow", u"\u0414\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437", None))
|
||||
self.correlationAnalisisAction.setText(QCoreApplication.translate("MainWindow", u"\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437", None))
|
||||
self.linearPolynomAction.setText(QCoreApplication.translate("MainWindow", u"\u041b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u043d\u043e\u043c", None))
|
||||
self.squaredPolynomAction.setText(QCoreApplication.translate("MainWindow", u"\u041a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u043d\u043e\u043c", None))
|
||||
self.label.setText(QCoreApplication.translate("MainWindow", u"\u0421\u0422\u0410\u0422\u0418\u0421\u0422\u0418\u0427\u0415\u0421\u041a\u0418\u0415 \u0414\u0410\u041d\u041d\u042b\u0415", None))
|
||||
self.filemenu.setTitle(QCoreApplication.translate("MainWindow", u"\u0424\u0430\u0439\u043b", None))
|
||||
self.generatemenu.setTitle(QCoreApplication.translate("MainWindow", u"\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439", None))
|
||||
|
79
statapp/ui/ui_squared_polynom_window.py
generated
Normal file
79
statapp/ui/ui_squared_polynom_window.py
generated
Normal file
@@ -0,0 +1,79 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2023 Maxim Slipenko, Eugene Lazurenko.
|
||||
#
|
||||
# This file is part of Statapp
|
||||
# (see https://github.com/shizand/statapp).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'squared_polynom_window.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 5.15.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide2.QtCore import *
|
||||
from PySide2.QtGui import *
|
||||
from PySide2.QtWidgets import *
|
||||
|
||||
|
||||
class Ui_SquaredPolynomWindow(object):
|
||||
def setupUi(self, SquaredPolynomWindow):
|
||||
if not SquaredPolynomWindow.objectName():
|
||||
SquaredPolynomWindow.setObjectName(u"SquaredPolynomWindow")
|
||||
SquaredPolynomWindow.resize(630, 400)
|
||||
self.gridLayout_2 = QGridLayout(SquaredPolynomWindow)
|
||||
self.gridLayout_2.setObjectName(u"gridLayout_2")
|
||||
self.gridLayout = QGridLayout()
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.tableView = QTableView(SquaredPolynomWindow)
|
||||
self.tableView.setObjectName(u"tableView")
|
||||
|
||||
self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
|
||||
|
||||
self.gridLayout_3 = QGridLayout()
|
||||
self.gridLayout_3.setObjectName(u"gridLayout_3")
|
||||
self.gridLayout_3.setContentsMargins(-1, 10, -1, -1)
|
||||
self.residualVarianceLabel = QLabel(SquaredPolynomWindow)
|
||||
self.residualVarianceLabel.setObjectName(u"residualVarianceLabel")
|
||||
|
||||
self.gridLayout_3.addWidget(self.residualVarianceLabel, 0, 0, 1, 1)
|
||||
|
||||
self.residualVarianceValueLabel = QLabel(SquaredPolynomWindow)
|
||||
self.residualVarianceValueLabel.setObjectName(u"residualVarianceValueLabel")
|
||||
|
||||
self.gridLayout_3.addWidget(self.residualVarianceValueLabel, 0, 1, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addLayout(self.gridLayout_3, 1, 0, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
|
||||
|
||||
|
||||
self.retranslateUi(SquaredPolynomWindow)
|
||||
|
||||
QMetaObject.connectSlotsByName(SquaredPolynomWindow)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, SquaredPolynomWindow):
|
||||
SquaredPolynomWindow.setWindowTitle(QCoreApplication.translate("SquaredPolynomWindow", u"\u041a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u043d\u043e\u043c", None))
|
||||
self.residualVarianceLabel.setText(QCoreApplication.translate("SquaredPolynomWindow", u"\u041e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0430\u044f \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044f:", None))
|
||||
self.residualVarianceValueLabel.setText(QCoreApplication.translate("SquaredPolynomWindow", u"undefined", None))
|
||||
# retranslateUi
|
@@ -20,6 +20,7 @@
|
||||
from PySide2.QtWidgets import QDialog, QHeaderView
|
||||
|
||||
from statapp.calculations import varianceAnalysis
|
||||
from statapp.mathtex_header_view import MathTexHeaderView
|
||||
from statapp.models.variance_analysis_model import VarianceAnalysisModel
|
||||
from statapp.ui.ui_variance_analysis_window import Ui_VarianceAnalysisWindow
|
||||
from statapp.utils import addIcon
|
||||
@@ -34,6 +35,9 @@ class VarianceAnalysisWindow(QDialog):
|
||||
res = varianceAnalysis(data)
|
||||
self.model = VarianceAnalysisModel(res.round(2))
|
||||
self.ui.tableView.setModel(self.model)
|
||||
self.ui.tableView.setVerticalHeader(
|
||||
MathTexHeaderView(self.ui.tableView)
|
||||
)
|
||||
header = self.ui.tableView.horizontalHeader()
|
||||
header.setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
|
||||
|
||||
|
Reference in New Issue
Block a user