From 965e593962bdaa26af1e0f508055a7a4fd20109a Mon Sep 17 00:00:00 2001 From: Dmitry Zhurov Date: Mon, 8 Aug 2022 00:56:40 +0800 Subject: [PATCH 1/4] regression slope and intersept calculation --- .../widgets/QECorrelation/QECorrelation.cpp | 30 ++++-- .../widgets/QECorrelation/QECorrelation.h | 2 +- .../widgets/QECorrelation/QECorrelation.ui | 102 +++++++++++++++++- 3 files changed, 121 insertions(+), 13 deletions(-) diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp index c1d8984a..36e329e3 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp @@ -688,10 +688,10 @@ void QECorrelation::setReadOut (const QString status) //------------------------------------------------------------------------------ // Refer to http://en.wikipedia.org/wiki/Correlation_and_dependence +// and to https://en.wikipedia.org/wiki/Simple_linear_regression // -double QECorrelation::calculateCorrelationCoefficient () +void QECorrelation::calculateCorrelationAndRegression (double &correlation_coef, double ®ression_slope, double ®ression_intersept) { - double result; int number; double sumX; double sumY ; @@ -709,7 +709,12 @@ double QECorrelation::calculateCorrelationCoefficient () double sdY; number = this->xData.count (); - if (number <= 0) return 0.0; + if (number <= 0){ + correlation_coef = 0.0; + regression_slope = 0.0; + regression_intersept = 0.0; + return ; + } // Sum x, x^2, y, y^2 and xy. // @@ -753,12 +758,19 @@ double QECorrelation::calculateCorrelationCoefficient () sdX = sqrt (varX); sdY = sqrt (varY); - result = (meanXY - meanX * meanY) / (sdX * sdY); + correlation_coef = (meanXY - meanX * meanY) / (sdX * sdY); } else { - result = 0.0; + correlation_coef = 0.0; } - return result; + if (varX != 0.0){ + regression_slope = (meanXY - meanX * meanY) / varX; + regression_intersept = meanY - regression_slope*meanX; + }else{ + regression_slope=std::nan("0"); + regression_intersept=std::nan("0"); + } + return; } //------------------------------------------------------------------------------ @@ -861,6 +873,8 @@ void QECorrelation::updateDataArrays () int extra; int number; double correlation; + double slope; + double intersept; samplePeriod = this->uiForm->Sample_Interval_Edit->getValue (); maximumPoints = (int) this->uiForm->Number_Samples_Edit->getValue (); @@ -882,12 +896,14 @@ void QECorrelation::updateDataArrays () maximumPeriod = samplePeriod * maximumPoints; currentPeriod = samplePeriod * number; - correlation = this->calculateCorrelationCoefficient (); + this->calculateCorrelationAndRegression (correlation, slope, intersept); this->uiForm->Number_Points_Label->setText (QString ("%1").arg (number)); this->uiForm->Maximum_Sample_Label->setText (QEUtilities::intervalToString (maximumPeriod, 0, false)); this->uiForm->Ongoing_Sample_Label->setText (QEUtilities::intervalToString (currentPeriod, 0, false)); this->uiForm->Correlation_Value_Label->setText (QString ("%1").arg (correlation, 0, 'f', 4)); + this->uiForm->Regression_Slope_Value_Label->setText (QString ("%1").arg (slope, 0, 'f', 4)); + this->uiForm->Regression_Intercept_Value_Label->setText (QString ("%1").arg (intersept, 0, 'f', 4)); this->replotIsRequired = true; } diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h index 58d3c231..a9bb5574 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h @@ -194,7 +194,7 @@ class QE_FRAMEWORK_LIBRARY_SHARED_EXPORT QECorrelation : public QEAbstractDynami void setup (); void setReadOut (const QString status); - double calculateCorrelationCoefficient (); + void calculateCorrelationAndRegression (double &correlation_coef, double ®ression_slope, double ®ression_intersept); void updateDataArrays (); void reDrawPlane (); void runSelectNameDialog (const int instance); diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui index ac02df25..7b36008f 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui @@ -7,7 +7,7 @@ 0 0 672 - 536 + 562 @@ -65,13 +65,13 @@ 0 - 136 + 162 16777215 - 136 + 162 @@ -563,7 +563,7 @@ 0 - 92 + 118 660 20 @@ -659,7 +659,7 @@ 0 - 112 + 138 660 20 @@ -815,6 +815,98 @@ :/qe/stripchart/save_file.png:/qe/stripchart/save_file.png + + + + 120 + 95 + 84 + 16 + + + + QLabel { background-color: rgb(224,224,224); } QLabel { color: rgb(0,0,0); } + + + +99.7852 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 6 + + + + + + 4 + 95 + 108 + 16 + + + + + 8 + + + + QLabel { color: rgb(0,0,0); } + + + Regression slope: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 216 + 95 + 108 + 16 + + + + + 8 + + + + QLabel { color: rgb(0,0,0); } + + + Intercept: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 292 + 95 + 84 + 16 + + + + QLabel { background-color: rgb(224,224,224); } QLabel { color: rgb(0,0,0); } + + + -1.2345 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 6 + + From 1847188174e1e2f79691440fda4227dac4a39a8d Mon Sep 17 00:00:00 2001 From: Dmitry Zhurov Date: Mon, 8 Aug 2022 03:14:36 +0800 Subject: [PATCH 2/4] plot regression --- .../widgets/QECorrelation/QECorrelation.cpp | 57 +++++++++++++------ .../widgets/QECorrelation/QECorrelation.h | 7 ++- .../widgets/QECorrelation/QECorrelation.ui | 13 +++++ 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp index 36e329e3..7d276472 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp @@ -322,6 +322,9 @@ void QECorrelation::setup () QObject::connect (this->uiForm->Time_Select_Button, SIGNAL (clicked (bool)), this, SLOT (timeSelectButtonClick (bool))); + QObject::connect (this->uiForm->Sow_Regression_CheckBox, SIGNAL (stateChanged (int)), + this, SLOT (plotRegressionStateChanged (int))); + QObject::connect (this->uiForm->Number_Samples_Edit, SIGNAL (valueChanged (const double)), this, SLOT (numberSamplesEditChange (const double))); @@ -690,7 +693,7 @@ void QECorrelation::setReadOut (const QString status) // Refer to http://en.wikipedia.org/wiki/Correlation_and_dependence // and to https://en.wikipedia.org/wiki/Simple_linear_regression // -void QECorrelation::calculateCorrelationAndRegression (double &correlation_coef, double ®ression_slope, double ®ression_intersept) +void QECorrelation::calculateCorrelationAndRegression () { int number; double sumX; @@ -710,10 +713,10 @@ void QECorrelation::calculateCorrelationAndRegression (double &correlation_coef, number = this->xData.count (); if (number <= 0){ - correlation_coef = 0.0; - regression_slope = 0.0; - regression_intersept = 0.0; - return ; + this->correlation_coef = 0.0; + this->regression_slope = std::nan("0"); + this->regression_intersept = std::nan("0"); + return ; } // Sum x, x^2, y, y^2 and xy. @@ -758,17 +761,17 @@ void QECorrelation::calculateCorrelationAndRegression (double &correlation_coef, sdX = sqrt (varX); sdY = sqrt (varY); - correlation_coef = (meanXY - meanX * meanY) / (sdX * sdY); + this->correlation_coef = (meanXY - meanX * meanY) / (sdX * sdY); } else { - correlation_coef = 0.0; + this->correlation_coef = 0.0; } if (varX != 0.0){ - regression_slope = (meanXY - meanX * meanY) / varX; - regression_intersept = meanY - regression_slope*meanX; + this->regression_slope = (meanXY - meanX * meanY) / varX; + this->regression_intersept = meanY - regression_slope*meanX; }else{ - regression_slope=std::nan("0"); - regression_intersept=std::nan("0"); + this->regression_slope = std::nan("0"); + this->regression_intersept = std::nan("0"); } return; } @@ -837,6 +840,16 @@ void QECorrelation::reDrawPlane () pen.setStyle (Qt::DashLine); this->plotArea->setGridPen (pen); + if (this->uiForm->Sow_Regression_CheckBox->checkState() == Qt::Checked){ + if (this->regression_slope!=this->regression_slope){ // is nan + }else{ + pen.setColor (QColor ("red")); + this->plotArea->setCurveStyle (QwtPlotCurve::Lines); + this->plotArea->setCurvePen (pen); + this->plotArea->plotCurveData ({TX_Min, TX_Max}, {this->regression_slope*TX_Min+this->regression_intersept, this->regression_slope*TX_Max+this->regression_intersept}); + } + } + pen.setColor (QColor ("blue")); pen.setStyle (Qt::SolidLine); @@ -873,8 +886,6 @@ void QECorrelation::updateDataArrays () int extra; int number; double correlation; - double slope; - double intersept; samplePeriod = this->uiForm->Sample_Interval_Edit->getValue (); maximumPoints = (int) this->uiForm->Number_Samples_Edit->getValue (); @@ -896,15 +907,19 @@ void QECorrelation::updateDataArrays () maximumPeriod = samplePeriod * maximumPoints; currentPeriod = samplePeriod * number; - this->calculateCorrelationAndRegression (correlation, slope, intersept); + this->calculateCorrelationAndRegression (); this->uiForm->Number_Points_Label->setText (QString ("%1").arg (number)); this->uiForm->Maximum_Sample_Label->setText (QEUtilities::intervalToString (maximumPeriod, 0, false)); this->uiForm->Ongoing_Sample_Label->setText (QEUtilities::intervalToString (currentPeriod, 0, false)); - this->uiForm->Correlation_Value_Label->setText (QString ("%1").arg (correlation, 0, 'f', 4)); - this->uiForm->Regression_Slope_Value_Label->setText (QString ("%1").arg (slope, 0, 'f', 4)); - this->uiForm->Regression_Intercept_Value_Label->setText (QString ("%1").arg (intersept, 0, 'f', 4)); - + this->uiForm->Correlation_Value_Label->setText (QString ("%1").arg (this->correlation_coef, 0, 'f', 4)); + if (this->regression_slope!=this->regression_slope){ // is nan + this->uiForm->Regression_Slope_Value_Label->setText (QString ("---")); + this->uiForm->Regression_Intercept_Value_Label->setText (QString ("---")); + }else{ + this->uiForm->Regression_Slope_Value_Label->setText (QString ("%1").arg (this->regression_slope, 0, 'f', 4)); + this->uiForm->Regression_Intercept_Value_Label->setText (QString ("%1").arg (this->regression_intersept, 0, 'f', 4)); + } this->replotIsRequired = true; } @@ -1376,6 +1391,12 @@ void QECorrelation::timeSelectButtonClick (bool) } } +//------------------------------------------------------------------------------ +// +void QECorrelation::plotRegressionStateChanged (bool){ + this->replotIsRequired = true; +} + //------------------------------------------------------------------------------ // void QECorrelation::setArchiveData (const QObject* userData, const bool isOkay, diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h index a9bb5574..a2a28534 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h @@ -180,6 +180,10 @@ class QE_FRAMEWORK_LIBRARY_SHARED_EXPORT QECorrelation : public QEAbstractDynami double yMin; double yMax; + double regression_slope; + double regression_intersept; + double correlation_coef; + enum PlotModes { pmDots = 1, pmLines }; enum ScaleModes { smDynamic, smManual, smData }; @@ -194,7 +198,7 @@ class QE_FRAMEWORK_LIBRARY_SHARED_EXPORT QECorrelation : public QEAbstractDynami void setup (); void setReadOut (const QString status); - void calculateCorrelationAndRegression (double &correlation_coef, double ®ression_slope, double ®ression_intersept); + void calculateCorrelationAndRegression (); void updateDataArrays (); void reDrawPlane (); void runSelectNameDialog (const int instance); @@ -234,6 +238,7 @@ private slots: void manualScaleClick (bool); void plotModeSelect (bool); void timeSelectButtonClick (bool); + void plotRegressionStateChanged (bool); void numberSamplesEditChange (const double); void sampleIntervalEditChange (const double); }; diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui index 7b36008f..17d9c62a 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui @@ -907,6 +907,19 @@ 6 + + + + 480 + 7 + 100 + 24 + + + + Plot regression + + From ceacffe252dc8c90217407f09fc4a98b4cc70548 Mon Sep 17 00:00:00 2001 From: Dmitry Zhurov Date: Mon, 8 Aug 2022 03:27:03 +0800 Subject: [PATCH 3/4] label is renamed --- .../project/widgets/QECorrelation/QECorrelation.cpp | 4 ++-- qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp index 7d276472..40a5e091 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp @@ -322,7 +322,7 @@ void QECorrelation::setup () QObject::connect (this->uiForm->Time_Select_Button, SIGNAL (clicked (bool)), this, SLOT (timeSelectButtonClick (bool))); - QObject::connect (this->uiForm->Sow_Regression_CheckBox, SIGNAL (stateChanged (int)), + QObject::connect (this->uiForm->Show_Regression_CheckBox, SIGNAL (stateChanged (int)), this, SLOT (plotRegressionStateChanged (int))); @@ -840,7 +840,7 @@ void QECorrelation::reDrawPlane () pen.setStyle (Qt::DashLine); this->plotArea->setGridPen (pen); - if (this->uiForm->Sow_Regression_CheckBox->checkState() == Qt::Checked){ + if (this->uiForm->Show_Regression_CheckBox->checkState() == Qt::Checked){ if (this->regression_slope!=this->regression_slope){ // is nan }else{ pen.setColor (QColor ("red")); diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui index 17d9c62a..365293f8 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.ui @@ -907,7 +907,7 @@ 6 - + 480 From 5abadd7256577c6a649363b3f39cd1b3d01847af Mon Sep 17 00:00:00 2001 From: Dmitry Zhurov Date: Mon, 8 Aug 2022 03:33:09 +0800 Subject: [PATCH 4/4] regression variables were renamed --- .../widgets/QECorrelation/QECorrelation.cpp | 30 +++++++++---------- .../widgets/QECorrelation/QECorrelation.h | 6 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp index 40a5e091..e4d005cc 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.cpp @@ -713,9 +713,9 @@ void QECorrelation::calculateCorrelationAndRegression () number = this->xData.count (); if (number <= 0){ - this->correlation_coef = 0.0; - this->regression_slope = std::nan("0"); - this->regression_intersept = std::nan("0"); + this->correlationCoef = 0.0; + this->regressionSlope = std::nan("0"); + this->regressionIntersept = std::nan("0"); return ; } @@ -761,17 +761,17 @@ void QECorrelation::calculateCorrelationAndRegression () sdX = sqrt (varX); sdY = sqrt (varY); - this->correlation_coef = (meanXY - meanX * meanY) / (sdX * sdY); + this->correlationCoef = (meanXY - meanX * meanY) / (sdX * sdY); } else { - this->correlation_coef = 0.0; + this->correlationCoef = 0.0; } if (varX != 0.0){ - this->regression_slope = (meanXY - meanX * meanY) / varX; - this->regression_intersept = meanY - regression_slope*meanX; + this->regressionSlope = (meanXY - meanX * meanY) / varX; + this->regressionIntersept = meanY - regressionSlope*meanX; }else{ - this->regression_slope = std::nan("0"); - this->regression_intersept = std::nan("0"); + this->regressionSlope = std::nan("0"); + this->regressionIntersept = std::nan("0"); } return; } @@ -841,12 +841,12 @@ void QECorrelation::reDrawPlane () this->plotArea->setGridPen (pen); if (this->uiForm->Show_Regression_CheckBox->checkState() == Qt::Checked){ - if (this->regression_slope!=this->regression_slope){ // is nan + if (this->regressionSlope!=this->regressionSlope){ // is nan }else{ pen.setColor (QColor ("red")); this->plotArea->setCurveStyle (QwtPlotCurve::Lines); this->plotArea->setCurvePen (pen); - this->plotArea->plotCurveData ({TX_Min, TX_Max}, {this->regression_slope*TX_Min+this->regression_intersept, this->regression_slope*TX_Max+this->regression_intersept}); + this->plotArea->plotCurveData ({TX_Min, TX_Max}, {this->regressionSlope*TX_Min+this->regressionIntersept, this->regressionSlope*TX_Max+this->regressionIntersept}); } } @@ -912,13 +912,13 @@ void QECorrelation::updateDataArrays () this->uiForm->Number_Points_Label->setText (QString ("%1").arg (number)); this->uiForm->Maximum_Sample_Label->setText (QEUtilities::intervalToString (maximumPeriod, 0, false)); this->uiForm->Ongoing_Sample_Label->setText (QEUtilities::intervalToString (currentPeriod, 0, false)); - this->uiForm->Correlation_Value_Label->setText (QString ("%1").arg (this->correlation_coef, 0, 'f', 4)); - if (this->regression_slope!=this->regression_slope){ // is nan + this->uiForm->Correlation_Value_Label->setText (QString ("%1").arg (this->correlationCoef, 0, 'f', 4)); + if (this->regressionSlope!=this->regressionSlope){ // is nan this->uiForm->Regression_Slope_Value_Label->setText (QString ("---")); this->uiForm->Regression_Intercept_Value_Label->setText (QString ("---")); }else{ - this->uiForm->Regression_Slope_Value_Label->setText (QString ("%1").arg (this->regression_slope, 0, 'f', 4)); - this->uiForm->Regression_Intercept_Value_Label->setText (QString ("%1").arg (this->regression_intersept, 0, 'f', 4)); + this->uiForm->Regression_Slope_Value_Label->setText (QString ("%1").arg (this->regressionSlope, 0, 'f', 4)); + this->uiForm->Regression_Intercept_Value_Label->setText (QString ("%1").arg (this->regressionIntersept, 0, 'f', 4)); } this->replotIsRequired = true; } diff --git a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h index a2a28534..5b0a3332 100644 --- a/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h +++ b/qeframeworkSup/project/widgets/QECorrelation/QECorrelation.h @@ -180,9 +180,9 @@ class QE_FRAMEWORK_LIBRARY_SHARED_EXPORT QECorrelation : public QEAbstractDynami double yMin; double yMax; - double regression_slope; - double regression_intersept; - double correlation_coef; + double regressionSlope; + double regressionIntersept; + double correlationCoef; enum PlotModes { pmDots = 1, pmLines }; enum ScaleModes { smDynamic, smManual, smData };