X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_rpncalc.c;h=d83c0f4a7d920aabd62f6daacff1d910c7b8061b;hb=a9c2a94950e57c9d8847073c579a24455e749a66;hp=11924830c4715f8fdee1938564c4f89ebe76683b;hpb=35354e059a77479a7a135c1e4fc71c76523fd7c4;p=rrdtool.git diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index 1192483..d83c0f4 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008 + * RRDtool 1.3.2 Copyright by Tobi Oetiker, 1997-2008 **************************************************************************** * rrd_rpncalc.c RPN calculator functions ****************************************************************************/ @@ -174,6 +174,8 @@ void rpn_compact2str( add_op(OP_REV, REV) add_op(OP_TREND, TREND) add_op(OP_TRENDNAN, TRENDNAN) + add_op(OP_PREDICT, PREDICT) + add_op(OP_PREDICTSIGMA, PREDICTSIGMA) add_op(OP_RAD2DEG, RAD2DEG) add_op(OP_DEG2RAD, DEG2RAD) add_op(OP_AVG, AVG) @@ -371,6 +373,8 @@ rpnp_t *rpn_parse( match_op(OP_REV, REV) match_op(OP_TREND, TREND) match_op(OP_TRENDNAN, TRENDNAN) + match_op(OP_PREDICT, PREDICT) + match_op(OP_PREDICTSIGMA, PREDICTSIGMA) match_op(OP_RAD2DEG, RAD2DEG) match_op(OP_DEG2RAD, DEG2RAD) match_op(OP_AVG, AVG) @@ -784,6 +788,84 @@ short rpn_calc( } } break; + case OP_PREDICT: + case OP_PREDICTSIGMA: + stackunderflow(2); + { + /* the local averaging window (similar to trend, but better here, as we get better statistics thru numbers)*/ + int locstepsize = rpnstack->s[--stptr]; + /* the number of shifts and range-checking*/ + int shifts = rpnstack->s[--stptr]; + stackunderflow(shifts); + // handle negative shifts special + if (shifts<0) { + stptr--; + } else { + stptr-=shifts; + } + /* the real calculation */ + double val=DNAN; + /* the info on the datasource */ + time_t dsstep = (time_t) rpnp[rpi - 1].step; + int dscount = rpnp[rpi - 1].ds_cnt; + int locstep = (int)ceil((float)locstepsize/(float)dsstep); + + /* the sums */ + double sum = 0; + double sum2 = 0; + int count = 0; + /* now loop for each position */ + int doshifts=shifts; + if (shifts<0) { doshifts=-shifts; } + for(int loop=0;loops[stptr]; + } else { + shiftstep = rpnstack->s[stptr+loop]; + } + if(shiftstep <0) { + rrd_set_error("negative shift step not allowed: %i",shiftstep); + return -1; + } + shiftstep=(int)ceil((float)shiftstep/(float)dsstep); + /* loop all local shifts */ + for(int i=0;i<=locstep;i++) { + /* now calculate offset into data-array - relative to output_idx*/ + int offset=shiftstep+i; + /* and process if we have index 0 of above */ + if ((offset>=0)&&(offset0) { + val = sum/(double)count; + } + } else { + if (count>1) { /* the sigma case */ + val=count*sum2-sum*sum; + if (val<0) { + val=DNAN; + } else { + val=sqrt(val/((float)count*((float)count-1.0))); + } + } + } + rpnstack->s[stptr] = val; + } + break; case OP_TREND: case OP_TRENDNAN: stackunderflow(1);