2025-04-18 09:30:35 +00:00
|
|
|
#include <QFileDialog>
|
|
|
|
|
|
|
|
|
|
#include "coefficientselectionform.h"
|
|
|
|
|
#include "ui_coefficientselectionform.h"
|
|
|
|
|
#include "confighandler.h"
|
|
|
|
|
#include "logger.h"
|
|
|
|
|
#include "global.h"
|
|
|
|
|
|
|
|
|
|
CoefficientSelectionForm::CoefficientSelectionForm(QWidget *parent) :
|
|
|
|
|
QWidget(parent),
|
|
|
|
|
ui(new Ui::CoefficientSelectionForm)
|
|
|
|
|
{
|
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
|
|
|
|
|
setWindowTitle("热焓校正系数选择");
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
ui->LineEditCoefficient->setText(
|
|
|
|
|
QString::number(
|
|
|
|
|
ConfigHandler::_configMap[ConInstrumentCoefficientStr].toFloat(),
|
|
|
|
|
'f',3));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ui->radioButtonSinglePointCoefficient->setChecked(true);
|
|
|
|
|
ui->radioButtonSinglePointCoefficient->setChecked(false);
|
|
|
|
|
|
|
|
|
|
on_radioButtonSinglePointCoefficient_toggled(true);
|
|
|
|
|
on_radioButtonMultiPointCoefficient_toggled(false);
|
|
|
|
|
|
|
|
|
|
ui->textEditFileContent->setReadOnly(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CoefficientSelectionForm::~CoefficientSelectionForm()
|
|
|
|
|
{
|
|
|
|
|
delete ui;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-21 01:32:54 +00:00
|
|
|
void CoefficientSelectionForm::showEvent(QShowEvent *event)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 09:30:35 +00:00
|
|
|
void CoefficientSelectionForm::on_pushButtonCalculate_clicked()
|
|
|
|
|
{
|
|
|
|
|
float theory = ui->LineEditTheory->text().toFloat();
|
|
|
|
|
float measure = ui->LineEditActualMeasurement->text().toFloat();
|
|
|
|
|
|
|
|
|
|
_instrumentCoefficient = theory/measure;
|
|
|
|
|
ui->LineEditCoefficient->setText(QString::number(_instrumentCoefficient,'f',3));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CoefficientSelectionForm::on_pushButtonConfirm_clicked()
|
|
|
|
|
{
|
|
|
|
|
if(ui->radioButtonSinglePointCoefficient->isChecked()){
|
|
|
|
|
ConfigHandler::_configMap[ConInstrumentCoefficientStr] = _instrumentCoefficient;
|
|
|
|
|
ConfigHandler::writer();
|
|
|
|
|
|
|
|
|
|
Global::_enthalpyCoefficientEnableFlag = false;
|
|
|
|
|
}else{
|
|
|
|
|
QVector<double> xVtr,yVtr;
|
|
|
|
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(_jsonStr.toUtf8());
|
|
|
|
|
QJsonArray jsonArray = jsonDoc.array();
|
|
|
|
|
|
|
|
|
|
for (const QJsonValue &value : jsonArray) {
|
|
|
|
|
QJsonObject jsonObj = value.toObject();
|
2025-05-06 09:26:23 +00:00
|
|
|
xVtr<<jsonObj["temperature"].toDouble();
|
2025-04-18 09:30:35 +00:00
|
|
|
yVtr<<jsonObj["rate"].toDouble();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double coeff[3] = {0};
|
2025-05-06 09:26:23 +00:00
|
|
|
quadraticLeastSquaresFit(xVtr.data(),yVtr.data(),xVtr.size(),coeff);
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
std::cout << "Fitted quadratic polynomial: y = "
|
|
|
|
|
<< coeff[0] << "x^2 + "
|
|
|
|
|
<< coeff[1] << "x + "
|
|
|
|
|
<< coeff[2] << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
|
2025-04-18 09:30:35 +00:00
|
|
|
|
|
|
|
|
logde<<"y:"<<coeff[0]<<","
|
|
|
|
|
<<coeff[1]<<","
|
|
|
|
|
<<coeff[2];
|
|
|
|
|
|
2025-04-21 01:32:54 +00:00
|
|
|
Global::_enthalpyCoefficientEnableFlag = true;
|
2025-04-18 09:30:35 +00:00
|
|
|
|
|
|
|
|
Global::_enthalpyCoefficientVtr.clear();
|
|
|
|
|
Global::_enthalpyCoefficientVtr.push_back(coeff[2]);
|
|
|
|
|
Global::_enthalpyCoefficientVtr.push_back(coeff[1]);
|
|
|
|
|
Global::_enthalpyCoefficientVtr.push_back(coeff[0]);
|
|
|
|
|
}
|
2025-04-21 01:32:54 +00:00
|
|
|
|
|
|
|
|
hide();
|
2025-04-18 09:30:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CoefficientSelectionForm::on_pushButtonExit_clicked()
|
|
|
|
|
{
|
2025-04-21 01:32:54 +00:00
|
|
|
#if 0
|
2025-04-18 09:30:35 +00:00
|
|
|
ui->LineEditTheory->clear();
|
|
|
|
|
ui->LineEditCoefficient->clear();
|
|
|
|
|
|
|
|
|
|
ui->labelFilePath->clear();
|
|
|
|
|
ui->textEditFileContent->clear();
|
|
|
|
|
|
|
|
|
|
_jsonStr.clear();
|
2025-04-21 01:32:54 +00:00
|
|
|
#endif
|
2025-04-18 09:30:35 +00:00
|
|
|
|
|
|
|
|
hide();
|
|
|
|
|
}
|
2025-05-06 09:26:23 +00:00
|
|
|
void CoefficientSelectionForm::quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[]) {
|
|
|
|
|
if (n < 3) {
|
|
|
|
|
throw std::runtime_error("At least 3 data points are required for quadratic fit.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算各次幂的和
|
|
|
|
|
double sum_x = 0.0, sum_x2 = 0.0, sum_x3 = 0.0, sum_x4 = 0.0;
|
|
|
|
|
double sum_y = 0.0, sum_xy = 0.0, sum_x2y = 0.0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < n; ++i) {
|
|
|
|
|
sum_x += x[i];
|
|
|
|
|
sum_x2 += x[i] * x[i];
|
|
|
|
|
sum_x3 += x[i] * x[i] * x[i];
|
|
|
|
|
sum_x4 += x[i] * x[i] * x[i] * x[i];
|
|
|
|
|
sum_y += y[i];
|
|
|
|
|
sum_xy += x[i] * y[i];
|
|
|
|
|
sum_x2y += x[i] * x[i] * y[i];
|
|
|
|
|
}
|
2025-04-18 09:30:35 +00:00
|
|
|
|
2025-05-06 09:26:23 +00:00
|
|
|
// 构建法方程矩阵 A 和向量 b
|
|
|
|
|
double A[3][3] = {
|
|
|
|
|
{sum_x2, sum_x, n},
|
|
|
|
|
{sum_x3, sum_x2, sum_x},
|
|
|
|
|
{sum_x4, sum_x3, sum_x2}
|
|
|
|
|
};
|
|
|
|
|
double b[3] = {sum_x2y, sum_xy, sum_y};
|
|
|
|
|
|
|
|
|
|
// 使用高斯消元法求解线性方程组
|
|
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
|
|
|
// 寻找主元行
|
|
|
|
|
int max_row = i;
|
|
|
|
|
double max_val = std::fabs(A[i][i]);
|
|
|
|
|
for (int j = i + 1; j < 3; ++j) {
|
|
|
|
|
if (std::fabs(A[j][i]) > max_val) {
|
|
|
|
|
max_val = std::fabs(A[j][i]);
|
|
|
|
|
max_row = j;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 交换行
|
|
|
|
|
if (max_row != i) {
|
|
|
|
|
for (int k = 0; k < 3; ++k) {
|
|
|
|
|
std::swap(A[i][k], A[max_row][k]);
|
|
|
|
|
}
|
|
|
|
|
std::swap(b[i], b[max_row]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 消元
|
|
|
|
|
for (int j = i + 1; j < 3; ++j) {
|
|
|
|
|
double factor = A[j][i] / A[i][i];
|
|
|
|
|
for (int k = i; k < 3; ++k) {
|
|
|
|
|
A[j][k] -= factor * A[i][k];
|
|
|
|
|
}
|
|
|
|
|
b[j] -= factor * b[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 回代求解
|
|
|
|
|
coeff[2] = b[2] / A[2][2];
|
|
|
|
|
for (int i = 1; i >= 0; --i) {
|
|
|
|
|
double sum = 0.0;
|
|
|
|
|
for (int j = i + 1; j < 3; ++j) {
|
|
|
|
|
sum += A[i][j] * coeff[j];
|
|
|
|
|
}
|
|
|
|
|
coeff[i] = (b[i] - sum) / A[i][i];
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-04-18 09:30:35 +00:00
|
|
|
void CoefficientSelectionForm::on_pushButtonSelectFile_clicked()
|
|
|
|
|
{
|
|
|
|
|
QString filePath = QFileDialog::getOpenFileName(
|
|
|
|
|
nullptr, "选择 JSON 文件", "", "JSON 文件 (*.json);;所有文件 (*.*)");
|
|
|
|
|
|
|
|
|
|
if (!filePath.isEmpty()) {
|
|
|
|
|
QFile file(filePath);
|
|
|
|
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
|
|
|
QTextStream in(&file);
|
|
|
|
|
_jsonStr = in.readAll();
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "无法打开文件:" << filePath;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "未选择文件";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
ui->labelFilePath->setText(filePath);
|
|
|
|
|
ui->textEditFileContent->setText(_jsonStr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CoefficientSelectionForm::on_radioButtonSinglePointCoefficient_toggled(bool checked)
|
|
|
|
|
{
|
|
|
|
|
ui->LineEditTheory->setEnabled(checked);
|
|
|
|
|
ui->LineEditCoefficient->setEnabled(checked);
|
|
|
|
|
ui->LineEditActualMeasurement->setEnabled(checked);
|
|
|
|
|
|
|
|
|
|
ui->pushButtonCalculate->setEnabled(checked);
|
|
|
|
|
#if 0
|
|
|
|
|
if(checked){
|
|
|
|
|
ui->LineEditTheory->setEnabled(true);
|
|
|
|
|
ui->LineEditCoefficient->setEnabled(true);
|
|
|
|
|
ui->LineEditActualMeasurement->setEnabled(true);
|
|
|
|
|
|
|
|
|
|
ui->pushButtonCalculate->setEnabled(true);
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
|
|
ui->LineEditTheory->setEnabled(false);
|
|
|
|
|
ui->LineEditCoefficient->setEnabled(false);
|
|
|
|
|
ui->LineEditActualMeasurement->setEnabled(false);
|
|
|
|
|
|
|
|
|
|
ui->pushButtonCalculate->setEnabled(false);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CoefficientSelectionForm::on_radioButtonMultiPointCoefficient_toggled(bool checked)
|
|
|
|
|
{
|
|
|
|
|
ui->pushButtonSelectFile->setEnabled(checked);
|
|
|
|
|
ui->textEditFileContent->setEnabled(checked);
|
|
|
|
|
#if 0
|
|
|
|
|
if(checked){
|
|
|
|
|
ui->pushButtonSelectFile->setEnabled(true);
|
|
|
|
|
ui->textEditFileContent->setEnabled(true);
|
|
|
|
|
}else{
|
|
|
|
|
ui->pushButtonSelectFile->setEnabled(false);
|
|
|
|
|
ui->textEditFileContent->setEnabled(false);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CoefficientSelectionForm::cubicLeastSquaresFit(
|
|
|
|
|
double x[], double y[], int n, double coeff[])
|
|
|
|
|
{
|
|
|
|
|
int i, j, k;
|
2025-05-06 09:26:23 +00:00
|
|
|
double atemp[3] = {0}; // 存储x^0, x^1, x^2的和
|
|
|
|
|
double b[3] = {0}; // 右侧向量
|
|
|
|
|
|
|
|
|
|
// 计算各次幂的和
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
double xi = x[i];
|
|
|
|
|
double xi_pow2 = xi * xi; // x^2
|
|
|
|
|
|
|
|
|
|
// 累加atemp[0]到atemp[2]
|
|
|
|
|
atemp[0] += 1; // x^0的和等于数据点个数
|
|
|
|
|
atemp[1] += xi;
|
|
|
|
|
atemp[2] += xi_pow2;
|
|
|
|
|
|
|
|
|
|
// 计算右侧向量b
|
|
|
|
|
double yi = y[i];
|
|
|
|
|
b[0] += yi;
|
|
|
|
|
b[1] += yi * xi;
|
|
|
|
|
b[2] += yi * xi_pow2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建法方程矩阵
|
|
|
|
|
double a[3][3];
|
|
|
|
|
a[0][0] = atemp[0];
|
|
|
|
|
a[0][1] = atemp[1];
|
|
|
|
|
a[0][2] = atemp[2];
|
|
|
|
|
a[1][0] = atemp[1];
|
|
|
|
|
a[1][1] = atemp[2];
|
|
|
|
|
a[1][2] = 0;
|
|
|
|
|
a[2][0] = atemp[2];
|
|
|
|
|
a[2][1] = 0;
|
|
|
|
|
a[2][2] = 0;
|
|
|
|
|
|
|
|
|
|
// 高斯列主元消元法
|
|
|
|
|
for (k = 0; k < 2; k++) { // 消去第k列
|
|
|
|
|
// 寻找主元行
|
|
|
|
|
int max_row = k;
|
|
|
|
|
double max_val = fabs(a[k][k]);
|
|
|
|
|
for (i = k + 1; i < 3; i++) {
|
|
|
|
|
if (fabs(a[i][k]) > max_val) {
|
|
|
|
|
max_val = fabs(a[i][k]);
|
|
|
|
|
max_row = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 交换行
|
|
|
|
|
if (max_row != k) {
|
|
|
|
|
for (j = k; j < 3; j++) {
|
|
|
|
|
double temp = a[k][j];
|
|
|
|
|
a[k][j] = a[max_row][j];
|
|
|
|
|
a[max_row][j] = temp;
|
|
|
|
|
}
|
|
|
|
|
double temp_b = b[k];
|
|
|
|
|
b[k] = b[max_row];
|
|
|
|
|
b[max_row] = temp_b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 消元
|
|
|
|
|
for (i = k + 1; i < 3; i++) {
|
|
|
|
|
double factor = a[i][k] / a[k][k];
|
|
|
|
|
for (j = k; j < 3; j++) {
|
|
|
|
|
a[i][j] -= factor * a[k][j];
|
|
|
|
|
}
|
|
|
|
|
b[i] -= factor * b[k];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 回代求解
|
|
|
|
|
coeff[2] = b[2] / a[2][2];
|
|
|
|
|
for (i = 1; i >= 0; i--) {
|
|
|
|
|
double sum = 0.0;
|
|
|
|
|
for (j = i + 1; j < 3; j++) {
|
|
|
|
|
sum += a[i][j] * coeff[j];
|
|
|
|
|
}
|
|
|
|
|
coeff[i] = (b[i] - sum) / a[i][i];
|
|
|
|
|
}
|
2025-04-18 09:30:35 +00:00
|
|
|
}
|