191 lines
5.0 KiB
C++
191 lines
5.0 KiB
C++
#include <iostream>
|
||
#include <limits>
|
||
|
||
#include "global.h"
|
||
|
||
namespace Global {
|
||
Mode _mode = Mode::Analysis;
|
||
|
||
AxisMode _axisMode = AxisMode::SingleY;
|
||
|
||
QVector<CurveFileData> _curveFileDataVtr;
|
||
|
||
int _currentPhase = 0;
|
||
ExperimentInfo _experimentInfo;
|
||
QVector<CurveExperimentData> _curveExperimentDataVtr;
|
||
CurveExperimentData* _currentCurveExperimentDataPtr = nullptr;
|
||
|
||
bool _smoothnessFlag = false;
|
||
QVector<CurveExperimentData> _curveSmoothnessDataVtr;
|
||
QString _smoothnessFileName;
|
||
|
||
bool _enthalpyCoefficientEnableFlag = false;
|
||
QVector<double> _enthalpyCoefficientVtr;
|
||
|
||
bool _displayTimeValue = false;
|
||
|
||
LanguageType _languageType = LanguageType::Chinese;
|
||
|
||
bool _experimentOITFlag = false;
|
||
|
||
QString converDoubleToStr(const double num)
|
||
{
|
||
return QString::number(num,'f',3);
|
||
}
|
||
|
||
void quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[])
|
||
{
|
||
if (n < 3) {
|
||
throw std::invalid_argument("At least 3 data points are required for quadratic fitting");
|
||
}
|
||
|
||
double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0;
|
||
double sum_y = 0, sum_xy = 0, sum_x2y = 0;
|
||
|
||
// 计算各项累加和
|
||
for (int i = 0; i < n; ++i) {
|
||
double xi = x[i];
|
||
double xi2 = xi * xi;
|
||
double xi3 = xi2 * xi;
|
||
double xi4 = xi3 * xi;
|
||
double yi = y[i];
|
||
|
||
sum_x += xi;
|
||
sum_x2 += xi2;
|
||
sum_x3 += xi3;
|
||
sum_x4 += xi4;
|
||
sum_y += yi;
|
||
sum_xy += xi * yi;
|
||
sum_x2y += xi2 * yi;
|
||
}
|
||
|
||
// 构建正规方程组的增广矩阵
|
||
double matrix[3][4] = {
|
||
{sum_x4, sum_x3, sum_x2, sum_x2y}, // 对应方程: a*Σx⁴ + b*Σx³ + c*Σx² = Σx²y
|
||
{sum_x3, sum_x2, sum_x, sum_xy}, // 对应方程: a*Σx³ + b*Σx² + c*Σx = Σxy
|
||
{sum_x2, sum_x, static_cast<double>(n), sum_y} // 对应方程: a*Σx² + b*Σx + c*n = Σy
|
||
};
|
||
|
||
// 高斯消元法解方程组
|
||
for (int i = 0; i < 3; ++i) {
|
||
// 部分主元选择
|
||
int maxRow = i;
|
||
for (int k = i + 1; k < 3; ++k) {
|
||
if (std::abs(matrix[k][i]) > std::abs(matrix[maxRow][i])) {
|
||
maxRow = k;
|
||
}
|
||
}
|
||
|
||
// 交换行
|
||
for (int k = i; k < 4; ++k) {
|
||
std::swap(matrix[i][k], matrix[maxRow][k]);
|
||
}
|
||
|
||
// 消元
|
||
for (int k = i + 1; k < 3; ++k) {
|
||
double factor = matrix[k][i] / matrix[i][i];
|
||
for (int j = i; j < 4; ++j) {
|
||
matrix[k][j] -= factor * matrix[i][j];
|
||
}
|
||
}
|
||
}
|
||
|
||
// 回代求解
|
||
coeff[2] = matrix[2][3] / matrix[2][2]; // c
|
||
coeff[1] = (matrix[1][3] - matrix[1][2] * coeff[2]) / matrix[1][1]; // b
|
||
coeff[0] = (matrix[0][3] - matrix[0][2] * coeff[2] - matrix[0][1] * coeff[1]) / matrix[0][0]; // a
|
||
}
|
||
|
||
// 计算一元一次函数在给定区间内开始变成负值的点
|
||
double findNegativeStartPoint(double m, double b, double start, double end) {
|
||
// 处理斜率为零的情况
|
||
if (m == 0) {
|
||
// 当斜率为 0 时,函数值为常数 b
|
||
if (b < 0) {
|
||
return start; // 若 b 为负,函数在区间起始点就为负
|
||
} else {
|
||
return std::numeric_limits<double>::infinity(); // 若 b 非负,函数在区间内不会变负
|
||
}
|
||
}
|
||
|
||
// 计算零点
|
||
double zeroPoint = -b / m;
|
||
|
||
// 检查零点是否在给定区间内
|
||
if (zeroPoint >= start && zeroPoint <= end) {
|
||
return zeroPoint; // 零点在区间内,函数在此点开始变负
|
||
}
|
||
|
||
// 根据斜率正负判断函数单调性,进而判断函数在区间内是否会变负
|
||
if (m > 0) {
|
||
// 斜率大于 0,函数单调递增
|
||
if (m * start + b < 0) {
|
||
return start; // 起始点函数值为负,函数在起始点就为负
|
||
}
|
||
} else {
|
||
// 斜率小于 0,函数单调递减
|
||
if (m * end + b < 0) {
|
||
return end; // 结束点函数值为负,函数在结束点开始为负
|
||
}
|
||
}
|
||
|
||
// 函数在区间内不会变负
|
||
return std::numeric_limits<double>::infinity();
|
||
}
|
||
|
||
void clearExperimentData()
|
||
{
|
||
_curveExperimentDataVtr.clear();
|
||
_currentCurveExperimentDataPtr = nullptr;
|
||
_currentPhase = -1;
|
||
}
|
||
|
||
bool isZero(double value, double epsilon) {
|
||
return std::abs(value) < epsilon;
|
||
}
|
||
|
||
QString getFileName(const QString filePath)
|
||
{
|
||
QFileInfo fileInfo(filePath);
|
||
|
||
// 获取文件的后缀名并转换为小写,方便比较
|
||
QString fileSuffix = fileInfo.suffix().toLower();
|
||
|
||
return fileInfo.fileName();
|
||
}
|
||
|
||
}
|
||
|
||
#if 0
|
||
Global::Global()
|
||
{
|
||
_mode = Global::Mode::Analysis;
|
||
_deviceConnectStatus = Global::DeviceConnectionStatus::Disconnected;
|
||
}
|
||
|
||
Global *Global::instance()
|
||
{
|
||
static Global ins;
|
||
return &ins;
|
||
}
|
||
|
||
void Global::setMode(const Global::Mode mode)
|
||
{
|
||
if(mode != _mode){
|
||
_mode = mode;
|
||
emit sigModeModify(mode);
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
void Global::setDeviceConnectionStatus(const Global::DeviceConnectionStatus status)
|
||
{
|
||
if(status != _deviceConnectStatus){
|
||
_deviceConnectStatus = status;
|
||
emit sigDeviceConnnectionStatusModify(status);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#endif
|