Added AVG function to CDEF language. Martin Sperl martin sperl.org
authoroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Sun, 18 Jun 2006 21:21:56 +0000 (21:21 +0000)
committeroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Sun, 18 Jun 2006 21:21:56 +0000 (21:21 +0000)
git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.2/program@847 a5681a0c-68f1-0310-ab6d-d61299d08faa

doc/rrdgraph_rpn.pod
src/rrd_rpncalc.c
src/rrd_rpncalc.h

index 5000d7a..6e31ea6 100644 (file)
@@ -139,6 +139,13 @@ Example: C<CDEF:x=v1,v2,v3,v4,v5,v6,6,SORT,POP,5,REV,POP,+,+,+,4,/> will
 compute the average of the values v1 to v6 after removing the smallest and
 largest.
 
+B<AVG>
+
+Pop one element (I<count>) from the stack. Now pop I<count> elements and build the
+average, ignoring all UNKNOWN values in the process.
+
+Example: C<CDEF:x=a,b,c,d,4,AVG>
+
 B<TREND>
 
 Create a "sliding window" average of another data series.
index 104ea8f..3753c0f 100644 (file)
@@ -161,6 +161,7 @@ void rpn_compact2str(rpn_cdefds_t *rpnc,ds_def_t *ds_def,char **str)
          add_op(OP_TREND,TREND)
          add_op(OP_RAD2DEG,RAD2DEG)
          add_op(OP_DEG2RAD,DEG2RAD)
+         add_op(OP_AVG,AVG)
 #undef add_op
               }
     (*str)[offset] = '\0';
@@ -338,6 +339,7 @@ rpn_parse(void *key_hash,const char *const expr_const,long (*lookup)(void *,char
        match_op(OP_TREND,TREND)
        match_op(OP_RAD2DEG,RAD2DEG)
        match_op(OP_DEG2RAD,DEG2RAD)
+       match_op(OP_AVG,AVG)
 #undef match_op
 
 
@@ -755,6 +757,28 @@ rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx,
                        rpnstack -> s[--stptr] = DNAN;
                }
                break;
+           case OP_AVG:
+               stackunderflow(0);
+                {
+                   int i=rpnstack -> s[stptr--];
+                   double sum=0;
+                   int count=0;
+                   stackunderflow(i-1);
+                   while(i>0) {
+                     double val=rpnstack -> s[stptr--];
+                     i--;
+                    if (isnan(val)) { continue; }
+                     count++;
+                     sum+=val;
+                   }
+                   // now push the result bavk on stack
+                   if (count>0) {
+                     rpnstack -> s[++stptr]=sum/count;
+                   } else {
+                     rpnstack -> s[++stptr]=DNAN;
+                   }
+                }
+                break;
            case OP_END:
                break;
        }
index 94fa31e..38ba9f8 100644 (file)
@@ -17,7 +17,8 @@ enum op_en {OP_NUMBER=0,OP_VARIABLE,OP_INF,OP_PREV,OP_NEGINF,
            OP_MIN,OP_MAX,OP_LIMIT, OP_FLOOR, OP_CEIL,
            OP_UN,OP_END,OP_LTIME,OP_NE,OP_ISINF,OP_PREV_OTHER,OP_COUNT,
            OP_ATAN,OP_SQRT,OP_SORT,OP_REV,OP_TREND,
-           OP_ATAN2,OP_RAD2DEG,OP_DEG2RAD};
+           OP_ATAN2,OP_RAD2DEG,OP_DEG2RAD,
+           OP_AVG};
 
 typedef struct rpnp_t {
     enum op_en   op;