Skip to content
Permalink
Browse files

Add CV alongside RMSE on CP Chart

.. seems silly to not do it, and its relatively useful when comparing
   the different model fits.
  • Loading branch information...
liversedge committed Jul 6, 2019
1 parent 236f782 commit 7b659e69d8df1a3a61fffc5e7ac5b76faf435b00
Showing with 40 additions and 15 deletions.
  1. +10 −0 src/Charts/AllPlot.cpp
  2. +30 −15 src/Metrics/PDModel.cpp
@@ -497,6 +497,13 @@ AllPlotObject::parseZoneString(QString zstring)
{
QVector<QwtZone> returning;

// we don't worry none about the metric
if (zstring.contains(":")) {
// split out the metric piece
QStringList toks=zstring.split(":");
if (toks.count()>=2) zstring=toks[1];
}

// split zstring into ; delimetered tokens
foreach(QString entry, zstring.split(";")) {

@@ -2396,6 +2403,7 @@ AllPlot::recalc(AllPlotObject *objects)
for(int k=0; k<objects->U.count(); k++) {
if (!objects->U[k].array.empty()) {
objects->U[k].curve->setSamples(xaxis.data() + startingIndex, objects->U[k].smooth.data() + startingIndex, totalPoints);
//XXXXHEREXXX
}
}

@@ -3387,6 +3395,7 @@ AllPlot::setDataFromPlot(AllPlot *plot, int startidx, int stopidx)
}
int points = stopidx - startidx + 1; // e.g. 10 to 12 is 3 points 10,11,12, so not 12-10 !
for(int k=0; k<standard->U.count(); k++) standard->U[k].curve->setSamples(xaxis,smoothU[k], points);
//XXXXHEREXXX
standard->hrvCurve->setSamples(plot->standard->smoothHrv_time.data(),
plot->standard->smoothHrv.data(),
plot->standard->smoothHrv.count());
@@ -5179,6 +5188,7 @@ AllPlot::setDataFromObject(AllPlotObject *object, AllPlot *reference)
if (!object->U[k].smooth.empty()) {

standard->U[k].curve->setSamples(xaxis.data(), object->U[k].smooth.data(), totalPoints);
//XXXXHEREXXX
standard->U[k].curve->attach(this);
standard->U[k].curve->setVisible(true);
}
@@ -179,8 +179,10 @@ PDModel::deriveCPParameters(int model)
double errtot=0;
double sse=0;
double meany=0;
double MEAN=0;
for(int i=0; i<t.size(); i++){
double py = y(t[i]/60.0f); // predicted y
MEAN += py;
meany += p[i]; // calculatng mean divided at end
double err = p[i] - py; // error for this point
errtot += err; // for mean errors divided at end
@@ -190,14 +192,15 @@ PDModel::deriveCPParameters(int model)

// lets use to calc R2
meany /= double(t.size());
MEAN /= double(t.size());
double sv=0;
for(int i=0; i<t.size(); i++) {
sv += (p[i]-meany) * (p[i]-meany);
}
double R2=1-(sse/sv);

// carry on with RMSE
double mean = errtot/double(t.size());
double mean = errtot/double(t.size()); // mean of residuals MEAN is mean of variable
errtot = 0;

// mean of residuals^2
@@ -206,7 +209,11 @@ PDModel::deriveCPParameters(int model)

// RMSE
double RMSE=sqrt(mean);
fitsummary = QString("RMSE %1 watts R<sup>2</sup>=%3 [LR] %2 points").arg(RMSE, 0, 'f', 2).arg(t.size()).arg(R2, 0, 'f', 3);
double CV=(RMSE/MEAN) * 100;
fitsummary = QString("RMSE %1w CV %4% R<sup>2</sup>=%3 [LR] %2 points").arg(RMSE, 0, 'f', 0)
.arg(t.size())
.arg(R2, 0, 'f', 3)
.arg(CV, 0, 'f', 1);

} else if (fit == LeastSquares && this->nparms() > 0) {
// only try lmfit if the model supports that
@@ -309,22 +316,22 @@ PDModel::deriveCPParameters(int model)

// get vector of residuals
QVector<double> residuals(p.size());
double MEAN=0;
double errtot=0;
for(int i=0; i<p.size(); i++){
double err = p[i] - y(t[i]/60.0f);
errtot += err; // for mean
residuals[i]=err;
double err = y(t[i]/60.0f) - p[i]; // error
errtot += err * err; // accumulate squar of errors
MEAN += y(t[i]/60.0f); // for average error divided at end
}
double mean = errtot/double(p.size());
errtot = 0;
MEAN /= double(p.size()); // average error
double mean = errtot/double(p.size()); // average square of error

// mean of residuals^2
for(int i=0; i<p.size(); i++) errtot += pow(residuals[i]-mean, 2);
mean = errtot / double(p.size());

// RMSE
// RMSE and CV
double RMSE=sqrt(mean);
fitsummary = QString("RMSE %1 watts [LM] %2 points").arg(RMSE, 0, 'f', 2).arg(p.size());
double CV=(RMSE/MEAN) * 100;
fitsummary = QString("RMSE %1w CV %3% [LM] %2 points").arg(RMSE, 0, 'f', 0)
.arg(p.size())
.arg(CV, 0, 'f', 1);

} else {

@@ -451,12 +458,15 @@ PDModel::calcSummary()
// get vector of residuals
QVector<double> residuals(data.size());
double errtot=0;
double MEAN=0;
for(int i=0; i<data.size(); i++){
double err = data[i] - y((i+1)/60.0f);
MEAN += y((i+1)/60.0f);
errtot += err; // for mean
residuals[i]=err;
}
double mean = errtot/double(data.size());
MEAN/=double(data.size());
errtot = 0;

// mean of residuals^2
@@ -465,7 +475,8 @@ PDModel::calcSummary()

// RMSE
double RMSE=sqrt(mean);
fitsummary = QString("RMSE %1 watts [envelope] %2 points").arg(RMSE, 0, 'f', 2).arg(data.size());
double CV=(RMSE/MEAN) *100;
fitsummary = QString("RMSE %1w CV %3% [envelope] %2 points").arg(RMSE, 0, 'f', 0).arg(data.size()).arg(CV,0,'f',1);
}

//
@@ -1289,12 +1300,15 @@ ExtendedModel::deriveExtCPParameters()
// get vector of residuals
QVector<double> residuals(data.size());
double errtot=0;
double MEAN=0;
for(int i=0; i<data.size(); i++){
double err = data[i] - y((i+1)/60.0f);
MEAN += y((i+1)/60.0f);
errtot += err; // for mean
residuals[i]=err;
}
double mean = errtot/double(data.size());
MEAN/=double(data.size());
errtot = 0;

// mean of residuals^2
@@ -1303,7 +1317,8 @@ ExtendedModel::deriveExtCPParameters()

// RMSE
double RMSE=sqrt(mean);
fitsummary = QString("RMSE %1 watts [envelope] %2 points").arg(RMSE, 0, 'f', 2).arg(data.size());
double CV=(RMSE/MEAN)*100;
fitsummary = QString("RMSE %1w CV %3% [envelope] %2 points").arg(RMSE, 0, 'f', 0).arg(data.size()).arg(CV,0,'f',1);
}

QList<QPointF>

0 comments on commit 7b659e6

Please sign in to comment.
You can’t perform that action at this time.