2025-05-06T17:26:22

This commit is contained in:
yuntang 2025-05-06 17:26:23 +08:00
parent de17180ada
commit 225ff71859
7 changed files with 239 additions and 146 deletions

View File

@ -51,7 +51,6 @@ int main(int argc, char *argv[])
// a.setWindowIcon(QIcon(":/images/logo.png"));
#if 1
MainWindow w;
w.setWindowTitle("Analysis Tool");

View File

@ -64,12 +64,20 @@ void CoefficientSelectionForm::on_pushButtonConfirm_clicked()
for (const QJsonValue &value : jsonArray) {
QJsonObject jsonObj = value.toObject();
xVtr<<jsonObj["theory"].toDouble();
xVtr<<jsonObj["temperature"].toDouble();
yVtr<<jsonObj["rate"].toDouble();
}
double coeff[3] = {0};
cubicLeastSquaresFit(xVtr.data(),yVtr.data(),xVtr.size(),coeff);
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
logde<<"y:"<<coeff[0]<<","
<<coeff[1]<<","
@ -100,7 +108,73 @@ void CoefficientSelectionForm::on_pushButtonExit_clicked()
hide();
}
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];
}
// 构建法方程矩阵 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];
}
}
void CoefficientSelectionForm::on_pushButtonSelectFile_clicked()
{
QString filePath = QFileDialog::getOpenFileName(
@ -125,7 +199,6 @@ void CoefficientSelectionForm::on_pushButtonSelectFile_clicked()
//
ui->labelFilePath->setText(filePath);
ui->textEditFileContent->setText(_jsonStr);
}
void CoefficientSelectionForm::on_radioButtonSinglePointCoefficient_toggled(bool checked)
@ -172,79 +245,79 @@ void CoefficientSelectionForm::cubicLeastSquaresFit(
double x[], double y[], int n, double coeff[])
{
int i, j, k;
double atemp[3] = {0}; // 存储x^0, x^1, x^2的和
double b[3] = {0}; // 右侧向量
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
// 计算各次幂的和
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;
// 累加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;
}
// 计算右侧向量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;
// 构建法方程矩阵
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;
}
}
// 高斯列主元消元法
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;
}
// 交换行
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];
}
}
// 消元
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];
}
// 回代求解
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];
}
}

View File

@ -26,7 +26,10 @@ private slots:
void on_pushButtonConfirm_clicked();
void on_pushButtonExit_clicked();
private:
// 立方拟合
void cubicLeastSquaresFit(double x[], double y[], int n, double coeff[4]);
// 平方拟合
void quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[]);
QString _jsonStr;
Ui::CoefficientSelectionForm *ui;

View File

@ -31,112 +31,130 @@ EnthalpyDataCorrectionForm::~EnthalpyDataCorrectionForm()
void EnthalpyDataCorrectionForm::on_pushButtonSave_clicked()
{
if(ui->checkBoxC6H12->isChecked()){
float theory = ui->lineEditTheoryC6H12->text().toFloat();
float measure = ui->lineEditMeasC6H12->text().toFloat();
double temperature = ui->labelTempC6H12->text().toDouble();
double theory = ui->lineEditTheoryC6H12->text().toDouble();
double measure = ui->lineEditMeasC6H12->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxHg->isChecked()){
float theory = ui->lineEditTheoryHg->text().toFloat();
float measure = ui->lineEditMeasHg->text().toFloat();
double temperature = ui->labelTempHg->text().toDouble();
double theory = ui->lineEditTheoryHg->text().toDouble();
double measure = ui->lineEditMeasHg->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxC6H5COOH->isChecked()){
float theory = ui->lineEditTheoryC6H5COOH->text().toFloat();
float measure = ui->lineEditMeasC6H5COOH->text().toFloat();
double temperature = ui->labelTempC6H5COOH->text().toDouble();
double theory = ui->lineEditTheoryC6H5COOH->text().toDouble();
double measure = ui->lineEditMeasC6H5COOH->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxIn->isChecked()){
float theory = ui->lineEditTheoryIn->text().toFloat();
float measure = ui->lineEditMeasIn->text().toFloat();
double temperature = ui->labelTempIn->text().toDouble();
double theory = ui->lineEditTheoryIn->text().toDouble();
double measure = ui->lineEditMeasIn->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxSn->isChecked()){
float theory = ui->lineEditTheorySn->text().toFloat();
float measure = ui->lineEditMeasSn->text().toFloat();
double temperature = ui->labelTempSn->text().toDouble();
double theory = ui->lineEditTheorySn->text().toDouble();
double measure = ui->lineEditMeasSn->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxBi->isChecked()){
float theory = ui->lineEditTheoryBi->text().toFloat();
float measure = ui->lineEditMeasBi->text().toFloat();
double temperature = ui->labelTempBi->text().toDouble();
double theory = ui->lineEditTheoryBi->text().toDouble();
double measure = ui->lineEditMeasBi->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxKC1O3->isChecked()){
float theory = ui->lineEditTheoryKC1O3->text().toFloat();
float measure = ui->lineEditMeasKC103->text().toFloat();
double temperature = ui->labelTempKC1O3->text().toDouble();
double theory = ui->lineEditTheoryKC1O3->text().toDouble();
double measure = ui->lineEditMeasKC103->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxPb->isChecked()){
float theory = ui->lineEditTheoryPb->text().toFloat();
float measure = ui->lineEditMeasPb->text().toFloat();
double temperature = ui->labelTempPb->text().toDouble();
double theory = ui->lineEditTheoryPb->text().toDouble();
double measure = ui->lineEditMeasPb->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxKNO3->isChecked()){
float theory = ui->lineEditTheoryKNO3->text().toFloat();
float measure = ui->lineEditMeasKNO3->text().toFloat();
double temperature = ui->labelTempKNO3->text().toDouble();
double theory = ui->lineEditTheoryKNO3->text().toDouble();
double measure = ui->lineEditMeasKNO3->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxZn->isChecked()){
float theory = ui->lineEditTheoryZn->text().toFloat();
float measure = ui->lineEditMeasZn->text().toFloat();
double temperature = ui->labelTempZn->text().toDouble();
double theory = ui->lineEditTheoryZn->text().toDouble();
double measure = ui->lineEditMeasZn->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxAg2SO4->isChecked()){
float theory = ui->lineEditTheoryAg2SO4->text().toFloat();
float measure = ui->lineEditMeasAg2SO4->text().toFloat();
double temperature = ui->labelTempAg2SO4->text().toDouble();
double theory = ui->lineEditTheoryAg2SO4->text().toDouble();
double measure = ui->lineEditMeasAg2SO4->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxCsCl->isChecked()){
float theory = ui->lineEditTheoryCsC1->text().toFloat();
float measure = ui->lineEditMeasCsCl->text().toFloat();
double temperature = ui->labelTempCsC1->text().toDouble();
double theory = ui->lineEditTheoryCsC1->text().toDouble();
double measure = ui->lineEditMeasCsCl->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxSiO2->isChecked()){
float theory = ui->lineEditTheorySiO2->text().toFloat();
float measure = ui->lineEditMeasSiO2->text().toFloat();
double temperature = ui->labelTempSiO2->text().toDouble();
double theory = ui->lineEditTheorySiO2->text().toDouble();
double measure = ui->lineEditMeasSiO2->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxK2SO4->isChecked()){
float theory = ui->lineEditTheoryK2SO4->text().toFloat();
float measure = ui->lineEditMeasK2SO4->text().toFloat();
double temperature = ui->labelTempK2SO4->text().toDouble();
double theory = ui->lineEditTheoryK2SO4->text().toDouble();
double measure = ui->lineEditMeasK2SO4->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxK2CrO4->isChecked()){
float theory = ui->lineEditTheoryK2CrO4->text().toFloat();
float measure = ui->lineEditMeasK2CrO4->text().toFloat();
double temperature = ui->labelTempK2CrO4->text().toDouble();
double theory = ui->lineEditTheoryK2CrO4->text().toDouble();
double measure = ui->lineEditMeasK2CrO4->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxBaCO3->isChecked()){
float theory = ui->lineEditTheoryBaCO3->text().toFloat();
float measure = ui->lineEditMeasBaCO3->text().toFloat();
double temperature = ui->labelTempBaCO3->text().toDouble();
double theory = ui->lineEditTheoryBaCO3->text().toDouble();
double measure = ui->lineEditMeasBaCO3->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxAg->isChecked()){
float theory = ui->lineEditTheoryAg->text().toFloat();
float measure = ui->lineEditMeasAg->text().toFloat();
double temperature = ui->labelTempAg->text().toDouble();
double theory = ui->lineEditTheoryAg->text().toDouble();
double measure = ui->lineEditMeasAg->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
if(ui->checkBoxCu->isChecked()){
float theory = ui->lineEditTheoryCu->text().toFloat();
float measure = ui->lineEditMeasCu->text().toFloat();
double temperature = ui->labelTempCu->text().toDouble();
double theory = ui->lineEditTheoryCu->text().toDouble();
double measure = ui->lineEditMeasCu->text().toDouble();
_theoryDataVtr.push_back({theory,theory/measure});
_theoryDataVtr.push_back({temperature,theory/measure});
}
//
saveJson();
@ -153,7 +171,7 @@ void EnthalpyDataCorrectionForm::saveJson()
QJsonArray jsonArray;
for (const TheoryData &data : _theoryDataVtr) {
QJsonObject jsonObj;
jsonObj["theory"] = data.theory;
jsonObj["temperature"] = data.temperature;
jsonObj["rate"] = data.rate;
jsonArray.append(jsonObj);
}

View File

@ -23,8 +23,8 @@ private:
void saveJson();
private:
struct TheoryData{
float theory;
float rate;
double temperature;
double rate;
};
QVector<TheoryData> _theoryDataVtr;

View File

@ -59,7 +59,7 @@
</widget>
</item>
<item row="13" column="3">
<widget class="QLabel" name="label_36">
<widget class="QLabel" name="labelTempSiO2">
<property name="text">
<string>573.0</string>
</property>
@ -69,7 +69,7 @@
<widget class="QLineEdit" name="lineEditTheoryKC1O3"/>
</item>
<item row="7" column="3">
<widget class="QLabel" name="label_30">
<widget class="QLabel" name="labelTempKC1O3">
<property name="text">
<string>299.5</string>
</property>
@ -93,7 +93,7 @@
</widget>
</item>
<item row="12" column="3">
<widget class="QLabel" name="label_35">
<widget class="QLabel" name="labelTempCsC1">
<property name="text">
<string>476.0</string>
</property>
@ -114,7 +114,7 @@
</widget>
</item>
<item row="8" column="3">
<widget class="QLabel" name="label_31">
<widget class="QLabel" name="labelTempPb">
<property name="text">
<string>327.4</string>
</property>
@ -127,7 +127,7 @@
<widget class="QLineEdit" name="lineEditMeasC6H12"/>
</item>
<item row="11" column="3">
<widget class="QLabel" name="label_34">
<widget class="QLabel" name="labelTempAg2SO4">
<property name="text">
<string>430.0</string>
</property>
@ -157,7 +157,7 @@
</widget>
</item>
<item row="15" column="3">
<widget class="QLabel" name="label_38">
<widget class="QLabel" name="labelTempK2CrO4">
<property name="text">
<string>665.0</string>
</property>
@ -205,7 +205,7 @@
</widget>
</item>
<item row="5" column="3">
<widget class="QLabel" name="label_29">
<widget class="QLabel" name="labelTempSn">
<property name="text">
<string>231.9</string>
</property>
@ -219,7 +219,7 @@
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="label_9">
<widget class="QLabel" name="labelTempC6H5COOH">
<property name="text">
<string>122.1</string>
</property>
@ -246,7 +246,7 @@
<widget class="QLineEdit" name="lineEditMeasSiO2"/>
</item>
<item row="16" column="3">
<widget class="QLabel" name="label_39">
<widget class="QLabel" name="labelTempBaCO3">
<property name="text">
<string>810.0</string>
</property>
@ -292,7 +292,7 @@
</widget>
</item>
<item row="14" column="3">
<widget class="QLabel" name="label_37">
<widget class="QLabel" name="labelTempK2SO4">
<property name="text">
<string>583.0</string>
</property>
@ -306,7 +306,7 @@
</widget>
</item>
<item row="9" column="3">
<widget class="QLabel" name="label_32">
<widget class="QLabel" name="labelTempKNO3">
<property name="text">
<string>334.0</string>
</property>
@ -323,7 +323,7 @@
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_7">
<widget class="QLabel" name="labelTempC6H12">
<property name="text">
<string>-86.0</string>
</property>
@ -377,7 +377,7 @@
</widget>
</item>
<item row="17" column="3">
<widget class="QLabel" name="label_40">
<widget class="QLabel" name="labelTempAg">
<property name="text">
<string>961.8</string>
</property>
@ -407,7 +407,7 @@
<widget class="QLineEdit" name="lineEditMeasKC103"/>
</item>
<item row="6" column="3">
<widget class="QLabel" name="label_28">
<widget class="QLabel" name="labelTempBi">
<property name="text">
<string>271.4</string>
</property>
@ -421,7 +421,7 @@
</widget>
</item>
<item row="18" column="3">
<widget class="QLabel" name="label_41">
<widget class="QLabel" name="labelTempCu">
<property name="text">
<string>1083.0</string>
</property>
@ -452,7 +452,7 @@
<widget class="QLineEdit" name="lineEditMeasHg"/>
</item>
<item row="10" column="3">
<widget class="QLabel" name="label_33">
<widget class="QLabel" name="labelTempZn">
<property name="text">
<string>419.5</string>
</property>
@ -506,7 +506,7 @@
<widget class="QLineEdit" name="lineEditMeasCsCl"/>
</item>
<item row="2" column="3">
<widget class="QLabel" name="label_26">
<widget class="QLabel" name="labelTempHg">
<property name="text">
<string>-38.8</string>
</property>
@ -553,7 +553,7 @@
</widget>
</item>
<item row="4" column="3">
<widget class="QLabel" name="label_27">
<widget class="QLabel" name="labelTempIn">
<property name="text">
<string>156.6</string>
</property>