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.
 
 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.
 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_TREND,TREND)
          add_op(OP_RAD2DEG,RAD2DEG)
          add_op(OP_DEG2RAD,DEG2RAD)
+         add_op(OP_AVG,AVG)
 #undef add_op
               }
     (*str)[offset] = '\0';
 #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_TREND,TREND)
        match_op(OP_RAD2DEG,RAD2DEG)
        match_op(OP_DEG2RAD,DEG2RAD)
+       match_op(OP_AVG,AVG)
 #undef match_op
 
 
 #undef match_op
 
 
@@ -755,6 +757,28 @@ rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx,
                        rpnstack -> s[--stptr] = DNAN;
                }
                break;
                        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;
        }
            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_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;
 
 typedef struct rpnp_t {
     enum op_en   op;