LTM plot banister with gapped curves

.. we only have banister curves where there is data
   so if there are gaps between seasons we should not
   plot any data.

.. as a result also fixed bug that the qwt gapped
   curve would always plot first zero in a curve.
This commit is contained in:
Mark Liversedge
2019-01-10 18:34:30 +00:00
parent 5cc2e057c8
commit a205e7bb73
4 changed files with 42 additions and 22 deletions

View File

@@ -38,7 +38,11 @@ void QwtPlotGappedCurve::drawSeries(QPainter *painter, const QwtScaleMap &xMap,
// First non-missed point will be the start of curve section.
double x = sample(i).x();
double y = sample(i).y();
if ((y < (naValue_ + -0.001) || y > (naValue_ + 0.001)) && x - last <= gapValue_) {
double yprev = 0;
if (i>0) yprev = sample(i-1).y();
if ((y < (naValue_ + -0.001) || y > (naValue_ + 0.001)) && (x - last <= gapValue_) &&
(yprev < (naValue_ + -0.001) || yprev > (naValue_ + 0.001))) {
int start = i-1;
int end = i;

View File

@@ -444,7 +444,7 @@ LTMPlot::setData(LTMSettings *set)
if (count <= 0) continue;
// Create a curve
QwtPlotCurve *current = metricDetail.type == METRIC_ESTIMATE
QwtPlotCurve *current = (metricDetail.type == METRIC_ESTIMATE || metricDetail.type == METRIC_BANISTER)
? new QwtPlotGappedCurve(metricDetail.uname, 1)
: new QwtPlotCurve(metricDetail.uname);
current->setVisible(!metricDetail.hidden);
@@ -599,7 +599,7 @@ LTMPlot::setData(LTMSettings *set)
//qDebug()<<"Create curve data.."<<timer.elapsed();
// Create a curve
QwtPlotCurve *current = metricDetail.type == METRIC_ESTIMATE
QwtPlotCurve *current = (metricDetail.type == METRIC_ESTIMATE || metricDetail.type == METRIC_BANISTER)
? new QwtPlotGappedCurve(metricDetail.uname, 1)
: new QwtPlotCurve(metricDetail.uname);
current->setVisible(!metricDetail.hidden);

View File

@@ -345,25 +345,7 @@ banisterFit::f(double d, const double *parms)
p0 = parms[4];
//printd("fit iter %s to %s [k1=%g k2=%g t1=%g t2=%g p0=%g]\n", startDate.toString().toStdString().c_str(), stopDate.toString().toStdString().c_str(), k1,k2,t1,t2,p0); // too much info even in debug, unless you want it
// ack, we need to recompute our window using the parameters supplied
bool first = true;
for (int index=startIndex; index < stopIndex; index++) {
// g and h are just accumulated training load with different decay parameters
if (first) {
parent->data[index].g = parent->data[index].h = 0;
first = false;
} else {
parent->data[index].g = (parent->data[index-1].g * exp (-1/t1)) + parent->data[index].score;
parent->data[index].h = (parent->data[index-1].h * exp (-1/t2)) + parent->data[index].score;
}
// apply coefficients
parent->data[index].pte = parent->data[index].g * k1;
parent->data[index].nte = parent->data[index].h * k2;
parent->data[index].perf = p0 + parent->data[index].pte - parent->data[index].nte;
}
compute(startIndex, stopIndex);
}
// return previously computed
@@ -371,6 +353,29 @@ banisterFit::f(double d, const double *parms)
return parent->data[int(d)].perf;
}
void
banisterFit::compute(long start, long stop)
{
// ack, we need to recompute our window using the parameters supplied
bool first = true;
for (int index=start; index < stop; index++) {
// g and h are just accumulated training load with different decay parameters
if (first) {
parent->data[index].g = parent->data[index].h = 0;
first = false;
} else {
parent->data[index].g = (parent->data[index-1].g * exp (-1/t1)) + parent->data[index].score;
parent->data[index].h = (parent->data[index-1].h * exp (-1/t2)) + parent->data[index].score;
}
// apply coefficients
parent->data[index].pte = parent->data[index].g * k1;
parent->data[index].nte = parent->data[index].h * k2;
parent->data[index].perf = p0 + parent->data[index].pte - parent->data[index].nte;
}
}
void
banisterFit::combine(banisterFit other)
{
@@ -421,6 +426,16 @@ void Banister::fit()
printd("window %d %s [k1=%g k2=%g t1=%g t2=%g p0=%g]\n", i, lm_infmsg[status.outcome], prior[0], prior[1], prior[2], prior[3], prior[4]);
}
}
#if 0 // doesn't really make sense for now
// fill curves
for(int i=0; i<windows.length(); i++) {
if (i < (windows.length()-1))
windows[i].compute(windows[i].stopIndex, windows[i+1].startIndex);
else
windows[i].compute(windows[i].stopIndex, data.length());
}
#endif
}
//

View File

@@ -56,6 +56,7 @@ public:
double f(double t, const double *p);
void combine(banisterFit other);
void compute(long startIndex, long stopIndex);
long startIndex, stopIndex;
QDate startDate, stopDate;