- you may need to define the data series whit the optional start= parameter, so that
the source data series has enough data to provide prediction also at the beginning of a graph...
+The percentile can be between [-100:+100].
+The positive percentiles interpolates between values while the negative will take the closest.
+
+Example: you run 7 shifts with a window of 1800seconds. Assuming that the rrd-file
+has a step size of 300 seconds this means we have to do the percentile calculation
+based on a max of 42 distinct values (less if you got NAN). that means that in the
+best case you get a step rate between values of 2.4 percent.
+so if you ask for the 99th percentile, then you would need to look at the 41.59th
+value. As we only have integers, either the 41st or the 42nd value.
+
+With the positive percentile a linear interpolation between the 2 values is done
+to get the effective value.
+
+The negative returns the closest value distance wise - so in the above case 42nd value,
+which is effectively returning the Percentile100 or the max of the previous 7 days in the window.
+
Here an example, that will create a 10 day graph that also shows the
prediction 3 days into the future with its uncertainty value (as defined by avg+-4*sigma)
This also shows if the prediction is exceeded at a certain point.
if (rpnp[rpi].op == OP_PREDICTPERC) {
stackunderflow(1);
percentile = rpnstack->s[--stptr];
- if ((percentile<0) || (percentile > 100)) {
+ if (abs(percentile) > 100) {
rrd_set_error("unsupported percentile: %f",percentile);
return -1;
}
/* sort the numbers */
qsort(extra,count,sizeof(double),rpn_compare_double);
/* get the percentile selected */
- int idx=(int)round(percentile * ((float)count-1.0));
- /* maybe we should also do an interpolation between the 2
- * neighboring fields, similar to what we do with MEDIAN
- */
- val = extra[idx];
+ double idxf = percentile * ((float)count-1.0);
+ if (percentile < 0) { /* take the next best */
+ int idx = round(abs(idxf));
+ val = extra[idx];
+ } else { /* interpolate */
+ int idx = floor(idxf);
+ double deltax = idxf - idx;
+ val = extra[idx];
+ if (deltax) { /* this check also handles the percentile=100 case */
+ double deltay = extra[idx + 1] - extra[idx];
+ val += deltay * deltax;
+ }
+ }
}
break;
default: /* should not get here ... */