Code

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 5000d7a1738915277d065318971440624dc65d4d..6e31ea6d09916eda496096b02f23acb5ad7d6002 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 104ea8f2c593a88247a47cdbd0d047b9a399fb32..3753c0f57ee3b2205803c9647f38ab9b6ae87a93 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 94fa31e7c2156da001d9ebc708b72c35c4dba376..38ba9f817e28997348a796428da115851e0706af 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;